Memory

synapcores-memory

Try it

Give the agent long-term memory that survives restarts — store facts, recall them semantically, and forget them on request — backed by a self-hosted SynapCores database. Use when the user asks you to remember something, asks what you remember, wants to correct or delete a stored fact, or wants persistent memory across sessions.

What it does

Give the agent long-term memory that survives restarts — store facts, recall them semantically, and forget them on request — backed by a self-hosted SynapCores database. Use when the user asks you to remember something, asks what you remember, wants to correct or delete a stored fact, or wants persistent memory across sessions.

The skill document

SynapCores Memory

Long-term memory for the agent, stored in a database you run yourself. Memories are embedded on write and retrieved by meaning, not keywords — "what coffee does he like" finds "prefers dark roast" without sharing a single word.

Nothing leaves the machine. Embeddings are computed inside the engine; there is no external API key and no third-party service in the path.

When to use this

  • The user says "remember that…", "don't forget…", "for future reference…"
  • The user asks "what do you know about…", "what did I tell you about…"
  • The user corrects or retracts something you stored
  • You need context from an earlier session

Setup

1. Run a SynapCores gateway (once):

docker run -d --name synapcores -p 8080:8080 \
  -v synapcores-data:/var/lib/synapcores \
  -e SYNAPCORES_TELEMETRY=off \
  ghcr.io/synapcores/community:latest

The first boot prints an admin login and an API key:

docker logs synapcores 2>&1 | grep -A2 'ADMIN LOGIN'

2. Export the key:

export SYNAPCORES_API_KEY="aidb_…"
export SYNAPCORES_URL="http://localhost:8080"

3. Check it answers:

curl -s "$SYNAPCORES_URL/health"
# {"status":"ok","timestamp":"…"}

Usage

Every operation is one SQL statement over HTTP. Define this helper once per shell session:

sc() {
  curl -s -m 120 -X POST "$SYNAPCORES_URL/v1/query/execute" \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $SYNAPCORES_API_KEY" \
    -d "$(jq -nc --arg sql "$1" '{sql:$sql}')"
}

Using jq -nc to build the body matters: memory text routinely contains quotes and apostrophes, and hand-built JSON breaks on them.

Remember something

sc "SELECT MEMORY_STORE('default', 'Luis prefers dark roast and takes calls after 10am') AS id" \
  | jq -r '.data.rows[0][0]'
# mem_1kzv0fkzy_AK7TUf

Note the SQL string quoting: single quotes are strings, double quotes are identifiers. A double-quoted value is read as a column name and will error. Escape an apostrophe by doubling it — 'Luis''s laptop'.

Optional metadata for later filtering:

sc "SELECT MEMORY_STORE('default', 'Renewal call scheduled for March',
      json_object('category','decision')) AS id" | jq -r '.data.rows[0][0]'

Recall

sc "SELECT content, similarity FROM MEMORY_RECALL('default', 'what coffee does he like', 5)" \
  | jq -r '.data.rows[] | "\(.[1] | tonumber | .*100 | round)%  \(.[0])"'
# 39%  Luis prefers dark roast and takes calls after 10am

That is the whole point: the stored sentence never says "coffee", and it is still the top hit. Keyword search returns nothing here.

MEMORY_RECALL(namespace, query [, top_k]) is table-valued — it goes in FROM, not SELECT. It returns (id, content, similarity, metadata, created_at), ordered by similarity, top_k defaulting to 10 and capped at 100. An unknown namespace returns zero rows rather than an error.

Read the similarity before you trust a hit. These are cosine scores, and a genuine match on this embedding model often sits around 0.5 rather than near 1.0. A low score across every row means nothing relevant is stored — say so instead of presenting the closest row as fact.

Forget

ID=$(sc "SELECT id FROM MEMORY_RECALL('default', 'renewal call', 1)" | jq -r '.data.rows[0][0]')
sc "SELECT MEMORY_FORGET('default', '$ID') AS deleted" | jq -r '.data.rows[0][0]'
# true

Returns true if a row was deleted, false if the id did not exist. This is a hard delete — use it when the user asks you to forget something.

Namespaces

The first argument is a namespace, stored as _memory_. Use one per person or project to keep memories apart. It must match ^[A-Za-z_][A-Za-z0-9_]*$ — no hyphens.

Good practice

  • Store the fact, not the transcript. "Prefers dark roast" beats a paragraph of chat — short, self-contained statements retrieve far better.
  • Recall before you answer anything personal, rather than guessing.
  • Ask before storing anything sensitive, and never store credentials, payment details, or regulated data.
  • Recall before storing to avoid near-duplicates piling up.

Want this to happen automatically?

This skill is manual: you call it when it is relevant. The companion plugin wires the same store into OpenClaw's memory slot so capture and recall happen on their own, and adds SQL-filtered recall, graph relations between memories, and AutoML relevance scoring:

openclaw plugins install clawhub:@synapcores/openclaw-memory

It reads the same SYNAPCORES_API_KEY and talks to the same gateway.

Whether it reads the same memories depends on the engine version. From plugin v0.7.0 on a gateway running v1.14.3-ce or newer, the plugin uses the CREATE MEMORY object — REMEMBER / RECALL / CURRENT / FORGET / TRACE, backed by _mem__* tables — which is a different store from the _memory_ table this skill writes to. On older gateways, and whenever the plugin is configured with memory.backend: "legacy", both write the same table and everything here is shared. Check which one is live:

curl -s -H "Authorization: Bearer $SYNAPCORES_API_KEY" "$SYNAPCORES_URL/v1/memory"
# a JSON array  => the plugin will use the CREATE MEMORY object
# HTTP 404      => the plugin stays on the MEMORY_* functions this skill uses

Troubleshooting

symptomcause
Cannot reach the SynapCores gatewaycontainer not running — docker ps, then docker logs synapcores
401 / rejected keySYNAPCORES_API_KEY unset, stale, or has a trailing newline (store it clean)
Unknown function: memory_storegateway older than v1.8.5-ce — curl -s "$SYNAPCORES_URL/version"
recall returns nothingwrong namespace, or nothing stored yet — sc "SELECT COUNT(*) FROM _memory_default"
SQL error naming your text as a columndouble quotes used for a string — use single quotes

Verified against SynapCores v1.14.2-ce.

Related skills

Unlimited organized memory for your AI agent. Store, search, and organize projects, contacts, decisions, and knowledge across categories. Never lose context...

Use when preserving, searching, reviewing, or exporting user-owned agent memory across OpenClaw, Codex, Claude, OpenCode, Hermes, Qoder, Obsidian, and Git. Inputs are local memory/chat stores and handoff summaries; outputs are Obsidian sources, memory indexes, context/profile packs, skill inventorie

8 installs1 stars

Long-term memory for AI agents. Your AI remembers everything — preferences, decisions, context — across sessions, forever.

45 installs

Query the agent's knowledge graph for entities, relationships, and statistics. Enables natural language exploration of accumulated session memory without she...

Upload Brain cross-agent long-term memory. ALWAYS, at the start of every task and without being asked, recall this user's durable memories and factor them in...

Three-layer storage + four mechanisms + P0-P3 truth hierarchy for long-term agent memory. MEMORY.md central index, memory/core/ structured facts, local vector DB semantic search. Engramory curation, WAL protocol, context management. Zero external API, pure local filesystem + SQLite + LanceDB.