MCP tool reference
Run the local stdio server and understand the exact request, response, and value boundary of every exposed tool.Server
Synapse implements an MCP stdio server. A tool launches the same signed or installed executable with the mcp argument:
~/.local/bin/synapse mcp
The process uses stdin and stdout for protocol messages. Do not wrap it in a command that writes banners or shell setup output to stdout. The server opens the same local database as the desktop app and holds a shared lifecycle lock while connected.
Session start
Connecting Claude Code also installs a SessionStart hook that runs synapse session. It does two things a tool cannot do for itself: it prints a line in the terminal before the model has written anything, and it puts this project's memory into the session's context before the first turn. A connected pi runs the same command from its extension and shows the same two halves.
synapse session --json
{
"systemMessage": "Synapse connected · 128 memories",
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Synapse is connected and holds 128 memories for /Users/example/project. …"
}
}
additionalContext carries the memories themselves, most recent first, under the same scope rule recall uses: everything global, plus everything stored for this project, and nothing from any other project. A session therefore opens already holding what the project has decided, rather than being asked to go and look.
That matters because the alternative was guidance. Asking a model to call recall before it starts is an instruction it may or may not follow, and a session that skipped it worked from nothing while still reporting a connection. Guidance still asks for recall, because a focused query in the middle of a task is the case a session-start recall cannot cover.
| Behavior | Detail |
|---|---|
| Budget | Recalls under a balanced ceiling. A per-call budget can only shrink your configured one, so a store set to lean still returns lean. |
| Scope | Global memory plus the project the calling tool reports through cwd or workspace.current_dir, falling back to SYNAPSE_PROJECT_DIR. |
| Empty store | No block is injected. The context asks the tool to call remember once something durable is settled. |
| Failure | Reports Synapse unavailable with a short reason and tells the model not to claim a connection that is not there. The hook never exits non-zero, because a failing hook is noise in your terminal. |
| Trust | Recalled content is labelled as context, never as instruction. It does not override the current request, repository guidance, or what you say next. |
Before compaction
The other end of the same session. When a long session is about to be compacted, everything it worked out that nobody wrote down is about to stop existing — and it is the only moment where not having written something down costs immediately. Connecting Claude Code installs a PreCompact hook that runs synapse compact; a connected pi runs the same command from session_before_compact.
synapse compact
{
"hookSpecificOutput": {
"hookEventName": "PreCompact",
"additionalContext": "Synapse holds this project's durable memory, and this session is about to be compacted…"
}
}
It asks for an explicit list of what the session settled and is not already stored, and for a remember call for each one. It deliberately recalls nothing: the context window is being reclaimed, and spending it re-injecting memory the session already had is the opposite of what a compaction is for.
The compaction itself is never blocked, cancelled, or rewritten. A memory tool that traded a session's whole context for a reminder would be a worse bargain than forgetting.
remember
Stores a durable fact, decision, preference, convention, or correction.
{
"content": "Use small focused modules.",
"source": "synapse",
"scope": "project",
"project": "/Users/example/project",
"supersedes": [18]
}
| Field | Type | Required | Meaning |
|---|---|---|---|
content | string | Yes | The durable text. Empty or whitespace-only content is rejected. |
source | string or null | No | An origin such as a project path, repository name, or topic. |
scope | project or global | No | Defaults to project. Use global only for context that should appear everywhere. |
project | string or null | For project scope | Absolute working-project path. Synapse normalizes nested paths to the project root. |
supersedes | array of integers or null | No | Ids of memories this one replaces — usually ids that came back from an earlier recall. Each stops being recalled. Nothing is deleted. An id that no longer resolves is skipped rather than failing the write. |
{
"id": 24,
"stored": true,
"superseded": [18]
}
The store and the replacement happen in one transaction. Without supersedes, a correction is a second memory contradicting the first, both come back from the next recall, and the ranking decides which one an agent acts on — including the version its own author had already retracted.
recall
Returns durable context relevant to a query. An empty query returns recent memory.
{
"query": "module structure",
"limit": 8,
"budget": "lean",
"project": "/Users/example/project"
}
| Field | Type | Required | Meaning |
|---|---|---|---|
query | string | Yes | Words or a phrase describing the context needed. Use an empty string for recent entries. |
limit | integer or null | No | Requested result count. Defaults to 8. The active response budget may lower it. |
budget | full, balanced, or lean | No | May reduce the configured response ceiling but can never enlarge it. |
project | string or null | No | Absolute working-project path. Results include global memory plus this project and exclude other projects. |
{
"optimization": "lean",
"memories": [
{
"id": 24,
"body": "Use small focused modules.",
"source": "synapse",
"scope": "project",
"project": "/Users/example/project",
"created": 1785250000
}
]
}
Two fields appear only when they are true of the result. abridged marks a memory returned as its opening sentence alone, because the response budget could not carry the rest — use readmemory with its id and the same project before acting on the part you cannot see. superseded never appears here at all, because a replaced memory is not recalled.
readmemory
Read one memory by id after recall identifies it. The body is an exact page of stored text, including code and whitespace. No model or additional index is involved.
{
"id": 24,
"project": "/Users/example/project",
"offset": 0,
"budget": "lean"
}
| Field | Type | Required | Meaning |
|---|---|---|---|
id | positive integer | Yes | Memory id from recall. |
project | string or null | No | The same absolute project root used for recall. Scope resolution is identical. |
offset | nonnegative integer or null | No | UTF-8 byte offset, initially zero. Use the preceding page's next value to continue. |
budget | full, balanced, or lean | No | Can reduce the configured ceiling. Lean pages contain at most 2,800 bytes; Balanced and Full pages at most 6,000 bytes. |
{
"optimization": "lean",
"memory": {
"id": 24,
"body": "Use small focused modules.",
"source": "synapse",
"sourceabridged": false,
"scope": "project",
"project": "/Users/example/project",
"created": 1785250000,
"offset": 0,
"next": null,
"total": 26
}
}
next is null at the end. Otherwise, pass it as offset with the same id and project. total is the stored body's UTF-8 byte length. Byte limits stay within the character ceiling and never split a character. An offset inside a character or beyond the body is an error.
The source label has a separate 240-byte allowance; sourceabridged says whether it was shortened. Scope, project, creation time, and id retain the memory's provenance. Metadata and JSON framing are additional to the body budget.
A missing, superseded, or out-of-scope id returns {"optimization":"lean","memory":null} under Lean. Each page reads the current stored memory. If the memory is edited while reading, restart at zero; pages do not hold a historical snapshot. Hidden history remains available to its owner through synapse memory show and synapse memory restore.
vaultstatus
Lists active environment-variable names and scope trust state for a folder. It never returns secret values and cannot inject them into the connected tool.
{
"path": "/Users/example/project"
}
path is optional. Resolution falls back to SYNAPSE_PROJECT_DIR, then the server process’s current directory.
{
"path": "/Users/example/project",
"backend": "encrypted",
"available": ["DATABASE_URL"],
"unavailable": ["deploy.RegistryToken"],
"elsewhere": 4,
"ambient": "ready",
"shell": "zsh",
"scopes": [
{
"path": "/Users/example/project/.synapse.yaml",
"scope": "project",
"trusted": true,
"changed": false,
"env": ["DATABASE_URL"],
"denied": [],
"error": null
}
],
"warnings": [],
"note": "Values stay in the vault and never in a response. A name under available resolves for this folder; one under unavailable is named by a scope file here and needs it approved first. elsewhere counts secrets held for other folders, which are never named."
}
unavailable names the secrets this folder asks for and cannot reach, as vault.name. Only ones a .synapse.yaml on the way down to the folder names, so every name in it is already written in a file the caller can open; a long list is truncated and the remainder joins the count. Everything else this machine holds is counted by elsewhere and never named — this tool reaches every connected tool, and an agent working on one project has no business being handed the names of another project's credentials.
The pair exists because an empty available is otherwise the same answer whether nothing is stored or nothing is approved here, and those have different fixes. When a folder resolves nothing and the store is not empty, warnings says so and names the step that would change it — synapse scope init, then naming the secret in the env: block, then synapse scope trust.
teach and revise
Two tools that appear only while synapse settings learn on is set. They are how a session writes down a procedure it worked out, and corrects one that turned out wrong. Both write to the Synapse skill library and to nothing else.
teach takes a name, a one-line description, the instructions as Markdown, a scope of project (the default) or global, the absolute project root, and a note for you saying why it was worth keeping. Synapse writes the frontmatter itself rather than accepting it, so a model never gets to invent YAML keys or a name that disagrees with its own directory. The result always says the same thing: stored, and waiting for you.
revise takes the name, the corrected instructions in full, and a note saying what was wrong with the version it replaces. It returns the revision id holding the old text and the tools the correction reached.
Mesh tools
Three tools are always present. Sixteen more appear only while the agent mesh is switched on, and two more while self-improvement is, because a tool definition costs context in every session that loads it. They let connected sessions register under a name, message each other directly or by channel, park on wait until work arrives, report and watch work state, and start or stop background workers.
The guidance explaining them is sent with them and withdrawn with them, so the tool list and the instructions can never be out of step. That is true of both switches. See the agent mesh guide for the full list and what each one is for.
Operational behavior
- Tool errors are returned as readable strings. Protocol messages remain on stdio.
- The server identifies itself as
synapseusing the application version and advertises tool capability only. - Opening the database runs integrity and relationship checks, applies numbered migrations, and secures database permissions.
- A running MCP process holds a shared database lock.
synapse data restorerequires an exclusive lock and therefore refuses while any connected server or the desktop app is using the database. - Connected tools should recall before decisions that depend on project history and remember only stable confirmed context after it is established. A Claude Code session starts with that memory already in context; see Session start.