Turnbook
Turnbook is an MCP memory server that gives AI agents shared, local, verbatim long-term memory across apps and models.
Save facts, preferences, plans, decisions, and conversation details proactively in the user’s own words, with entities, attributes, timestamps, and supersession.
Recall structured memories and conversation turns, including full source context, entity history, recent/since/as-of filters, and scope filtering.
Build bounded context packets for answering questions that depend on past conversations.
Manage personal memory storage: choose/sync folders, share memory across the user’s own PCs, reindex, and export/import whole or project-specific memory.
Create and manage team project brains: publish decisions/progress/blockers, attach links and commits, view timelines, invite/manage members, audit, and join/leave teams.
Delete selected memories or secrets safely after showing masked previews and getting confirmation.
Inspect recorded code changes by project, time range, file, symbol, or change kind.
Team memory sharing for a project: teammates' AIs can share a project's decisions and progress through Graph-MIND while the underlying files stay in GitHub, without exposing personal memory.
Team memory sharing for a project: teammates' AIs can share a project's decisions and progress through Graph-MIND while the underlying files stay in Slack, without exposing personal memory.
Turnbook
Your AI forgets everything when the session ends. This one remembers, and it never calls an LLM to do it.
88.8% on LongMemEval. Zero model tokens spent saving memory. Runs on your own PC.
Decide something with one agent on Monday. Ask another on Wednesday. It knows.
English · 한국어
Recorded live on one PC: Claude Code (Opus 5.5, effort high) and Codex (GPT-6.1-Sol, effort high) sharing one Turnbook memory. Model thinking time is fast-forwarded.
Install
Windows: download Turnbook-Setup.cmd and double-click it, or in PowerShell:
irm https://raw.githubusercontent.com/goyohan0611-png/turnbook/main/scripts/install.ps1 | iexmacOS / Linux:
curl -LsSf https://raw.githubusercontent.com/goyohan0611-png/turnbook/main/scripts/install.sh | shNo Python needed; nothing else to set up. Restart your AI apps afterwards. Already have Python?
pip install turnbook && turnbook-install. More: docs/install.md.
After pip install turnbook:
{
"mcpServers": {
"turnbook": {
"command": "python",
"args": ["-m", "graph_mind.mcp_server"]
}
}
}Claude Code: claude mcp add turnbook -- python -m graph_mind.mcp_server. This gives the
tools only; turnbook-install also saves every conversation automatically.
Related MCP server: claude-memory
Try it
Work as usual for a while, then open a new session, another app, or another model and ask:
"Where did we leave off yesterday?"
"Which database did we pick for the billing service, and why?"
"What did you change in the auth middleware last week?"
"What's my dog's name?" (any fact you mentioned once, in passing)
Nothing to tag or save by hand: every turn is already stored, and the agent pulls back the few that answer the question.
What it does
One shared brain for every agent in your terminal. Whichever coding agent or model you run, they all read and write the same memory. Switch agents or models; the memory stays.
Made for orchestration. When an orchestrator runs several agents at once, they all write to the same memory as they work, so what one agent decided is there for the next. Every memory keeps which app and session it came from.
Remembers conversations word for word, on your own PC. Saving is a database write: no model call, no tokens. When a question depends on the past, the agent gets back the few thousand tokens that answer it. Korean and English.
One memory across your PCs. Run
turnbook folder share, thenturnbook folder <code>on the other PC (the AI tells you the command; it never moves your memory by itself, so a web page cannot either). Office network or Tailscale, over TLS, every line encrypted before it leaves a PC.Hand a memory to someone else as a file.
turnbook export FILEwrites all of it;--project FOLDERwrites only the conversations held in that folder. They runturnbook import FILE.Yours. No account, no cloud of its own, no telemetry. Secrets are masked before anything is stored, and "delete the password I typed earlier" deletes it everywhere. docs/privacy.md
Teams, if you want them. Share a project's decisions and progress with teammates' AIs, never your personal memory; files stay in Slack and GitHub. docs/teams.md
Works with
The installer finds these and connects them; run it again after installing a new one.
app | conversations saved | how |
Claude Code | every turn | reads its transcripts |
Codex CLI | every turn | reads its transcripts |
Cursor | every turn | reads its transcripts |
Copilot CLI | every turn | reads its transcripts |
Claude Desktop (Cowork) | every turn | reads its session files |
Gemini CLI | every turn | hooks; also adds relevant memory before each answer |
OpenCode | every turn | plugin; also adds relevant memory before each answer, for any model |
Claude Desktop chat, Windsurf, VS Code Copilot, Cline, LM Studio | what the model saves | MCP tools |
Any other MCP client works through the tools: see the hand-written config above.
How it works
flowchart LR
A["Claude Code · Codex · Cursor<br/>Gemini CLI · OpenCode · ..."] -- "transcripts, hooks, plugin" --> C["capture service<br/>(runs in the background)"]
C -- "verbatim turns,<br/>secrets masked" --> S[("your memory<br/>on this PC")]
S --> I["local search<br/>words + meaning + time"]
A -- "a question that needs the past" --> I
I -- "the few turns that answer it<br/>(~3k tokens)" --> ASaving costs nothing. Turns are stored as they were said. No model summarises or extracts anything at write time, so nothing is lost or invented on the way in, and no tokens are spent.
Search runs on your PC. Word search, a multilingual embedding model (mpnet, int8; ONNX, no GPU) and when things were said are combined; the agent gets a short packet with the source turns, not a dump of history.
The model you already use does the thinking. Turnbook hands it evidence; it answers. When models get better, the answers get better without changing the memory.
Does it work?
LongMemEval is the public benchmark for long-term chat memory: 500 questions over about 50 past sessions each. Every system below got the same answer model (gpt-5-mini), the same prompt and the official gpt-4o judge; only the memory differs.
accuracy | model tokens spent saving memory | text the answer model reads | |
Turnbook | 88.8% (all 500) | 0 | 3.4k tokens |
agentmemory | 80.4% (same 499) | — | ~16.5k tokens |
MemPalace 3.10.0 | 57.5% (40 questions) | 0 | — |
Mem0 2.2.1 (open source) | 52.5% (40 questions) | ~640,000 per question | — |
On agentmemory's 499 Turnbook scored 89.0%; on the 40, 85.0%. Retrieval alone, on agentmemory's own measure (an answer session among the first 5 retrieved): Turnbook 98.5%, agentmemory 95.2%. These runs used the embedding model of 0.9.9 and before; on a 100-question sample the current one finds the answer session as often or more (among the first 5: 99.0% against 97.9%).
Every question, answer and verdict is in research/runs/; method, failures and
how to rerun it: docs/benchmarks.md.
FAQ
Will it slow my PC down? The background service uses about 2% of one CPU core when nothing new is coming in and about 650 MB of memory, most of it the search model. A memory search takes about 20 ms (41 ms at the 95th percentile on a GitHub runner); the first one after an app starts, about 1.3 s. After an update that changes the search model, it reads the memory again once, at half pace (about an hour for 11,000 pieces).
What does it cost? Nothing. No API key and no model calls of its own; your AI app reads a packet of about 3k tokens when a question needs the past.
Does anything leave my PC? No, unless you share the memory with your own other PCs or a team. No telemetry. Secrets (API keys, passwords, card numbers...) are masked before storing.
How is this different from CLAUDE.md or an app's built-in memory? Those keep notes a model wrote, one app at a time. Turnbook keeps every turn as it was said and shares it across every app and model on the PC.
Korean? Yes: Korean and English conversations, and questions in either language. A Korean question about something said only in English is found most of the time, not always.
How do I remove it? turnbook-uninstall disconnects every app and stops the service; the
memory stays in ~/.graph-mind unless you add --purge.
Beta. Used daily on Windows. macOS and Linux pass every test in CI but have not seen daily use yet.
More
MCP tools · See your memory in 3D
(turnbook-view) · Changelog · Security ·
Development: pip install -r requirements.txt, then python -m unittest discover -s tests
Contributions are welcome under the CLA. License: AGPL-3.0; a commercial license is available for products that cannot publish their changes.
Available Tools
7 toolsbrain_checkpointA
Team project brains: decisions and progress shared with teammates' AIs, per project.
Not for the user's own memory or their other PCs: that is brain_folder. A project brain
holds what a team's AIs need to know about a project, apart from the user's personal
memory and from every other project. Nothing
personal is shared through this; only what is published here, when the user asks. Files
and notifications stay in Slack, drives and GitHub; a project brain keeps the decisions,
the progress, the context and links to where the work is.
Always pass `workspace` = your current working folder: a folder bound to a project makes
it the default `project`.
Publish only when the user asks ("공유해", "프로젝트에 올려줘", "체크포인트 남겨"): that
request is the approval, so do not ask again; ask only if the project is ambiguous.
Afterwards say exactly what went where.
- `projects`: the project brains the user takes part in, with when each was last shared.
- `create_project` + `project` (+ `path` = folder to bind): only when the user names one.
- `publish` + `type` + `summary` (one line, user's language) + `details` (a handover
note: what changed and why, files and functions, test results, links, what is left).
Never paste conversation text. `supersedes`=<id> replaces an earlier decision.
- `context` (with publish or attach): what changed, where (pages, sections, files,
functions), why, verification (test or check results), remaining, review_focus, and
the ids it answers (`addresses`) and its `evidence` (commit, PR, test log, Slack or
document links). Write only what you know; what is left out reads "not recorded".
- `attach` + `path`: a git folder links its commit at the stage it really reached
(committed / pushed / pr_open / merged / released; never call work done when the stage
says otherwise); a URL (a Slack message, a drive document) is kept as a link. Files are
not stored here: if the user wants a file shared, share it in Slack or a drive (with
the tools for those) and attach the link.
- `timeline`: "누가 어디까지 했어?" — answer from it only: who, what, what is left, and
when it was last shared. Do not guess at anything newer. Follow its `instructions`.
- `retract` + `checkpoint_id` (the publisher, or the project's owner);
`set_instructions` + `instructions` (owner) returns `command`: the user confirms the
new text in a terminal; show them the command.
- Members. Whoever creates a project owns it. `invite` + `member` + `role` (owner /
editor / viewer) + `projects`, and `host`, are not done from here: they return
`command` for the user to run in a terminal, which prints the code to give them. Show
the user the command and say what it does. `members` + `project`;
`remove_member` + `member` + `project` (owner; or yourself, to leave). `audit`
(+ `project`). On a teammate's PC: `join_team` + `code` (+ `name`), `leave_team` +
`project`.
- Where projects live: on a Postgres hub (`host`: make this PC one; teammates on the
office network or over Tailscale), where `invite` on the hub's PC also makes their
account (elsewhere they need an account from the hub's operator first); without a
hub, on this PC alone. Someone in several team hubs and none of their own:
`create_project` + `hub` (an address of it).
- `set_name` + `name`: the name teammates see (else this PC's name). If a result says
NAME_REQUIRED, ask the user for it (their own name, e.g. 고요한), set it, then retry.
If the result says UNAVAILABLE, the hub cannot be reached: tell the user the latest
shared state is unknown right now; never fill in from memory.
| Name | Required | Description | Default |
|---|---|---|---|
| hub | No | ||
| code | No | ||
| name | No | ||
| path | No | ||
| role | No | ||
| type | No | ||
| action | Yes | ||
| member | No | ||
| context | No | ||
| details | No | ||
| project | No | ||
| summary | No | ||
| projects | No | ||
| workspace | No | ||
| supersedes | No | ||
| source_refs | No | Links or ids it is based on. | |
| instructions | No | ||
| checkpoint_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: describes permission model (owner vs publisher for `retract`, owner for `remove_member`), that several actions return a `command` the user must run in a terminal, error protocols (UNAVAILABLE = hub unreachable, never fill in from memory; NAME_REQUIRED = ask then retry), and an integrity rule against overstating git stage. Minor ambiguity remains around `destructiveHint:false` given `retract` and `remove_member`, and nothing explains the read actions' cost or pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the approval rule are front-loaded, which is right, but the body is a dense wall of prose with irregular indentation rather than scannable structure; for a 15-action dispatcher some length is justified, yet several clauses (hub topology, invite-command detail) could be tightened or grouped per action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 15 actions, 18 parameters, an output schema and partial annotations, the description is nearly complete: it covers approval semantics, error states, permission boundaries and where projects are hosted. What is left thin is the return shape of the multi-step flows (invite/host command sequences) and how the actions relate when chained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 6% (one parameter documented), so the description must carry the load and largely does: workspace, project, path, type, summary, details, supersedes, checkpoint_id, member, role, projects, hub, code, name and instructions are each tied to specific actions via `action` + param notation, and `context`'s untyped object is expanded into named sub-fields. Some overlap is left unresolved, notably `source_refs` versus `context.evidence`, and the action-parameter pairings remain inferential.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a concrete verb-and-resource statement: project brains holding "decisions and progress shared with teammates' AIs, per project," and explicitly excludes the sibling: "Not for the user's own memory or their other PCs: that is brain_folder." The only weakness is that the tool multiplexes 15 actions, so a single purpose line cannot cover them all — but the core identity is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use and when-not-to-act rules: "Publish only when the user asks ('공유해', ...): that request is the approval, so do not ask again; ask only if the project is ambiguous," plus `create_project` "only when the user names one," and timeline usage keyed to a concrete user question ("누가 어디까지 했어?"). It also routes work that does not belong here to other tools (files stay in Slack/drives/GitHub, invite/host return terminal commands).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brain_contextARead-onlyIdempotent
Answer from the user's past: one bounded text packet to read before replying.
The default memory call: use it whenever a request may depend on earlier conversations,
facts, preferences, decisions or work. It returns `context`, a size-capped text of the
relevant memories and conversation turns, each with its date and source. For structured
rows, ids or one thing's history use brain_recall instead.
Set `recent=true` whenever the question is about what happened lately or what the user was
just doing: "what was I working on?", "where did we leave off?", "what did I do
yesterday?", "최근에", "아까", "어제", "지금 뭐 하고 있었지?". Results then come newest
first instead of by word overlap; naming something ("what did Kongi do lately") keeps them
about that. Set `since` (ISO date or time) to drop anything earlier, e.g. "this week".
Set `about_assistant=true` when the user asks what YOU said earlier: "which restaurant did
you recommend?", "what were the steps you gave me?", "네가 아까 뭐라고 했지?". Your own
past answers are then searched by meaning too, not only by their words.
Set `around` when the question is about WHEN WE TALKED: "what did we discuss last week?",
"지난달에 얘기한 거" -> resolve it yourself to a date or "start..end" (e.g. "2026-09-23"
or "2026-09-01..2026-09-30"). Conversations from then rank first; nothing is dropped.
Do not set it for when something HAPPENED ("the event I went to two weeks ago"): people
mention events days or weeks before or after, so that date misleads (measured: on dev2
it pushed the answering turn out in 2 of 11 questions and helped 2).
Each conversation item is one excerpt of one turn. Never tell the user you don't know
without first opening the item most likely to hold the answer:
brain_recall(source=<the text after "Source: <app> / ">) returns that turn in full with
the turns around it (your reply to that request, the rest of a list, the line before).
Open it too when an item you rely on is cut off.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | No | ISO time: only what had happened by then (default now). | |
| limit | No | Most items to return. | |
| query | Yes | The user's request, in their words. | |
| since | No | ||
| around | No | ||
| policy | No | auto skips requests with no sign of the past. | always |
| recent | No | ||
| scopes | No | Only these scopes, e.g. ["global"] or a project; default all. | |
| max_chars | No | Size cap of the returned text. | |
| about_assistant | No | ||
| knowledge_cutoff | No | ISO time: only what had been saved by then (default as_of). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile needs no restating. The description adds real behavioral detail beyond that: results come newest-first vs. by word overlap, `around` ranks but drops nothing, `about_assistant` searches by meaning, and each item carries date and source. However, it leaves the size-cap interaction (`max_chars`) and the `policy=auto` skip behavior to the schema, so it is strong but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded well: the core purpose and the sibling routing come first. But the body is long and uneven, padding with multilingual example strings and a measured ablation statistic (2 of 11 questions) that informs implementation choices rather than the calling decision, so some sentences do not earn their space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers trigger conditions, return shape, the follow-up path (open an item via brain_recall when it is cut off), and the key false-negative failure mode. An output schema exists, so return structure need not be restated in full. Minor gap: the `policy`, `limit`, and `scopes` knobs and their interaction are not addressed in prose.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 64%, and the description compensates for the four undocumented flags: `recent`, `since`, `about_assistant`, and `around` each get concrete trigger phrases and, for `around`, the expected value syntax ('2026-09-01..2026-09-30'). `as_of`, `limit`, `scopes`, `max_chars`, and `knowledge_cutoff` are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a concrete verb and resource ('answer from the user's past: one bounded text packet'), names the return field (`context`), and positions itself as 'the default memory call.' It explicitly contrasts with brain_recall for structured rows, ids, or one thing's history, so the agent can discriminate it from its closest sibling without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the selection rule (use whenever a request may depend on earlier conversations, facts, preferences, decisions, work), names the alternative tool and its condition (brain_recall for structured rows/ids/history), and adds a case-specific negative instruction: do not set `around` for when something happened, with a stated reason. Nearly every branch is decided for the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brain_folderAIdempotent
Where the user's own personal memory lives, and which of their own PCs share it.
Not for teams: project brains shared with teammates are brain_checkpoint.
Anything that changes where the memory goes (`path`, `share_existing`, `export_to`,
`import_from`) is not done from here: the tool returns `command`, and the user runs it in
a terminal. A web page or file you read can then never move their memory somewhere else.
Show the user the command, say what it does, and call this again without arguments after
they ran it to confirm. Codes and passwords appear only in that terminal.
Call it with `path` when the user names a folder for their memory, e.g. "use my Google
Drive's Turnbook folder as my brain". A folder that OneDrive, Google Drive or Dropbox
syncs makes the same memory available on every PC where the user chooses it too; nothing
else is needed. Without `path` it reports the current folder and the devices writing to it.
`path="local"` keeps the brain in this PC's own Postgres instead, shared the instant it is
written (no sync delay).
Other PCs: when the user asks to let their other PCs use this brain ("다른 PC도 붙게 해줘"),
call it with `path="share"`. It opens this PC's Postgres to the local network and Tailscale
(Windows may ask the user to approve a firewall rule once) and returns a
`connection_code` in the terminal. On the other PC the user runs
`turnbook folder <that code>`; it contains the password, so say not to post it anywhere
public.
Codes: when the user pastes any Turnbook code ("gm1." for their own other PC, "gmt1."
for a team invite), call this with `path=<the code>`; it does the right thing for either
(a team invite is joined at once), so never ask the user which kind it is.
`share_existing=true` sends what this PC remembers and the shared memory lacks (only that:
it also repairs turns that missed a hub that was down). It uploads
it to wherever the folder syncs. Set it only when the user has explicitly agreed to that.
`reindex=true` brings the search index up to date (links new memories, embeds unembedded
ones). Saving already does this; it is for a large imported backlog.
Moving a whole memory as one file ("내 기억 파일로 내보내줘", "이 기억 파일 가져와"):
`export_to=<file path>` writes every memory and conversation turn into that file;
`import_from=<file path>` adds such a file's contents to this memory, skipping what is
already here. Only when the user asks. Tell them the file holds their entire memory
(secrets were masked when saved), so keep it private like a diary.
With `project=<folder>`, `export_to` writes only the conversations held in that folder
(or below it) and the memories drawn from them ("이 프로젝트 대화만 넘겨줘"): every word
of those conversations goes in the file, so say so. Facts saved on request carry no
folder and are not included.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | ||
| project | No | ||
| reindex | No | ||
| export_to | No | ||
| import_from | No | ||
| share_existing | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the safety profile (non-read-only, non-destructive, idempotent, closed-world); the description adds substantial context beyond that: config changes are returned as a `command` for the user to run in a terminal (a deliberate prompt-injection defense), firewall approval may be needed, connection codes contain a password, export files hold the entire memory with secrets masked. No behavior contradicts the annotations — writes like reindex/export justify readOnlyHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the not-for-teams exclusion are front-loaded, and nearly every paragraph maps to a distinct mode, so little is filler. It is nevertheless very long for one tool, with some repeated emphasis ("Only when the user asks" / "Set it only when the user has explicitly agreed") that could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be enumerated, yet the description still flags the key return artifacts (`command`, `connection_code`) and what they contain. For a six-parameter, multi-mode tool with mutation and sharing side effects, nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the full burden, and it does: path (folder / "local" / "share" / a pasted code), share_existing, reindex, export_to, import_from, and project's scoping effect on export_to are all explained with intent and safety conditions. The only minor gap is whether `project` also constrains import_from.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb-and-resource framing: where the user's personal memory lives and which PCs share it. It explicitly names the sibling it is not for ("Not for teams: project brains shared with teammates are brain_checkpoint"), so an agent can route correctly without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It enumerates the selection conditions for each mode: bare call to report current state, path=<folder> when the user names a folder, path="local", path="share" for other PCs, path=<code> for pasted codes, share_existing only on explicit agreement, reindex for a backlog. Alternatives and exclusions are stated rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brain_forgetADestructiveIdempotent
Delete what the user wants gone from memory: "delete the password I typed earlier", "그 토큰 지워줘", "forget what I said about my ex".
Always two calls. First `query`: what to look for, in general words ("password", "wifi",
"DB login"); never repeat a secret the user typed. It returns numbered candidates with
masked previews. Show the user exactly those previews and ask which to delete; never
quote the original text. Then call again with the `ids` the user picked, and only those.
Deleting removes them from this PC, its search indexes, the shared memory and the user's
other PCs. This exchange about deleting is not saved either. The AI app's own chat
history is separate and untouched (Claude Code keeps ~/.claude/projects).
| Name | Required | Description | Default |
|---|---|---|---|
| ids | No | ||
| query | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this destructive/non-read-only/idempotent, and the description goes well beyond them by specifying deletion scope (this PC, search indexes, shared memory, other PCs), that the deletion exchange itself is not saved, and that app chat history is separate. It does not, however, describe failure behavior or what happens if ids match nothing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Longer than most definitions, but front-loaded with the purpose and each block (examples, two-call protocol, deletion scope) earns its place. Slightly more verbose than strictly necessary, but no filler sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value detail is unnecessary; the description instead supplies everything an agent needs to safely drive a destructive, two-step deletion — trigger conditions, privacy constraints, and blast radius. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the load, and it does: query must use general words and never repeat a secret the user typed; ids must be exactly the user-selected ones from the prior call. The mutual exclusivity/two-phase usage of the two optional params is implied clearly though not spelled out formally.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Delete what the user wants gone from memory') and grounds it in three concrete example utterances spanning languages. An agent can immediately distinguish this from brain_remember/brain_recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit two-call protocol: first query with general words, then a second call with the selected ids 'and only those.' It also states the required interaction pattern (show masked previews, ask the user which to delete, never quote the original).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brain_recallARead-onlyIdempotent
Raw lookup: the matching memories and turns as structured rows, not a ready context.
`source`: open the conversation around one turn. Pass the part after "Source: <app> / "
of a conversation item in brain_context's packet. A packet shows one excerpt of each turn;
when it is cut off, or the answer is likely in the rest of that exchange (your reply
right after the user's request, a list you gave, the line before), this returns those
turns in full, in order (`limit` caps how many follow; two come before).
To answer the user's question from their past, use brain_context instead; it returns one
bounded text packet ready to read. Use brain_recall to inspect or list: the ids and fields
of what matched (e.g. before brain_forget or `supersedes_memory_id`), one thing's history
in order, or what the store knows about.
`entity` answers "what happened to X, in order": every memory about that one thing (the
auth module, this project, my address), oldest first, with replaced entries marked and the
current one picked out. Similarity search returns only the nearest one or two of four
decisions made about one thing in four sessions; this returns all four. With neither
`query` nor `entity`, it lists what the store knows about, busiest first.
`recent`, `since`, `about_assistant` and `around` mean the same as in brain_context.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | No | ISO time: only what had happened by then (default now). | |
| limit | No | Most items to return. | |
| query | No | ||
| since | No | ||
| around | No | ||
| entity | No | ||
| recent | No | ||
| scopes | No | Only these scopes, e.g. ["global"] or a project; default all. | |
| source | No | ||
| about_assistant | No | ||
| knowledge_cutoff | No | ISO time: only what had been saved by then (default as_of). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish the read-only, idempotent, non-destructive profile, and the description layers on real behavior: `source` returns following turns in full and in order with two preceding turns included, `entity` returns oldest-first with replaced entries marked and the current one picked out. It doesn't state what happens on an empty match or how rows are shaped, but the remaining gaps are minor given annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the one-line summary, then organizes remaining text by parameter with backticked anchors, so it is scannable despite length. Some phrasing ("when it is cut off, or the answer is likely in the rest of that exchange") is more verbose than needed, but nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return shape needn't be described, and the description covers the modes an agent must choose between plus ordering semantics for the two most important ones. The unanswered parameters and the reliance on brain_context's description for shared parameters keep it short of complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 36% schema coverage and 11 parameters, the description carries heavy burden. It gives rich semantics for `source`, `entity` and `limit` (in the source context), but `query`, `as_of`, `knowledge_cutoff` and `about_assistant` are never explained, and four parameters are deferred wholesale via "mean the same as in brain_context" — a cross-reference that requires the sibling's description to be in context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a precise characterization ("Raw lookup: the matching memories and turns as structured rows, not a ready context") that names both the verb and the resource, and immediately contrasts it with brain_context's packet output. An agent can distinguish it from every sibling without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing guidance: "To answer the user's question from their past, use brain_context instead" versus "Use brain_recall to inspect or list" with three concrete inspection cases (ids before brain_forget, one thing's history, store inventory). It also tells exactly when to escalate from a brain_context packet via `source`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brain_rememberA
Save what the user just told you, in their own words. Call this proactively.
A fact that can change later (where they live or work, a pet, a preference, a plan, a
number they track): also pass `about` (who or what, e.g. "Kongi", "me") and `attribute`
(which property, a short English snake_case name, e.g. "breed", "home_city",
"favorite_coffee"). A later value with the same `about` and `attribute` replaces this
one and recall shows both: the value now and what it was before. Use the same
`attribute` names every time, and never put the value in the name: "last_trip", not
"last_trip_paris", or the next trip will not replace it.
Use it the moment the user mentions anything about their life, work, plans, preferences,
people, places, meals, purchases, health, decisions or events, e.g. "I had kimchi fried
rice today", "my dog is called Kongi", "we moved the meeting to Tuesday". Do not ask
whether to save it and do not wait to be told "remember this". Only `content` is
required: put the user's own sentence there verbatim. Add `entities` (who or what it is
about) and `effective_at` (when it happened, ISO time) when you know them. If it updates
something remembered earlier, pass that memory's id as `supersedes_memory_id`.
Decisions and their reasons are memories too: `memory_type="decision"`, the reason in
`content`, the project or component in `entities`.
Save silently. Do not tell the user you saved it ("I've noted that", "저장해 뒀어"); just
carry on with the conversation. Talk about memory only if the user asks what you remember
or whether something was saved.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Free labels to find it by. | |
| about | No | ||
| scope | No | global, or a project scope to keep it apart. | global |
| title | No | Short title; default: the first line of content. | |
| content | Yes | ||
| entities | No | ||
| modality | No | Optional; usually left empty. | |
| attribute | No | ||
| memory_id | No | ||
| retention | No | Optional; usually left empty. | |
| attributes | No | Optional; usually left empty. | |
| confidence | No | Optional; usually left empty. | |
| importance | No | Optional; usually left empty. | |
| source_ref | No | Where it came from: a file, URL or id. | conversation |
| memory_type | No | fact | |
| source_type | No | Leave as is. | mcp-client |
| effective_at | No | ||
| memory_class | No | Optional; usually left empty. | |
| related_memory_ids | No | Ids of memories this one relates to. | |
| supersedes_memory_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=false): it discloses that a later value with the same `about`/`attribute` REPLACES the earlier one, that recall surfaces both current and prior values, that saving is silent with no user-facing confirmation, and that decisions should be stored with a reason. These are exactly the non-obvious behaviors an agent would otherwise get wrong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core directive, then logically grouped into identity/supersession, triggering, and silence rules. It is long for a tool description and repeats the 'use the same attribute names' point twice, but nearly every sentence carries operational guidance rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the description covers the calling contract, supersession model and the required `content` field. The main gap is the absence of any guidance on `scope` (project vs global) and on when the optional metadata params matter, which for a 20-param tool is a real but secondary omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 60%, so the description must carry weight, and it does for the semantically tricky params: it explains `about`/`attribute` pairing, the snake_case naming convention with a failure example ('last_trip', not 'last_trip_paris'), `content` as verbatim user text, plus `entities`, `effective_at`, `supersedes_memory_id` and `memory_type`. It leaves roughly a third of the 20 params (scope, tags, modality, retention, confidence, importance, memory_class, related_memory_ids) undocumented, though the schema marks most of those 'optional; usually left empty'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+scope: 'Save what the user just told you, in their own words,' which immediately separates it from brain_recall, brain_forget and brain_context. The proactive-call directive further pins down its role in the sibling set.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use with concrete trigger examples ('I had kimchi fried rice today', 'my dog is called Kongi'), explicit when-not ('do not wait to be told remember this'), and an explicit anti-pattern ('do not ask whether to save it'). No alternative tool is named, but the routing conditions are unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
code_activityARead-onlyIdempotent
Code changes the capture service recorded, with diff excerpts, filtered by project,
time range (happened_from/happened_to, ISO), file, symbol or kind. For "what did I
change in auth.py last week?" or "when did the parser change?". Empty unless a code folder
is being watched (automatic-capture.json, code_workspaces).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Most items to return. | |
| symbol | No | ||
| file_path | No | Path inside the project, e.g. src/auth.py. | |
| project_id | No | A watched project's id; default all. | |
| change_kind | No | ADDED, MODIFIED or DELETED. | |
| happened_to | No | ||
| happened_from | No | ||
| max_diff_chars | No | Diff excerpt size per change, 200-20000. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive and closed-world, so the safety profile is covered. The description adds real context beyond that: results carry diff excerpts, results are silently empty without a watched code folder, and it names the config artifacts (automatic-capture.json, code_workspaces) that control that behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads what the tool returns, then the filter axes, then the caveat about watched folders. Dense but every clause carries information; slightly long for a single paragraph, with the caveat tucked at the end where it is easiest to miss.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return fields, and it correctly focuses on filtering, diff excerpting, and the empty-result precondition. Nothing essential for a correct call is missing, though the default limit/max_diff_chars tradeoffs are only in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 63%; the description supplies meaning for the undocumented parameters by naming the filter set (project, happened_from/happened_to as ISO, file, symbol, kind) and tying them to example queries. limit and max_diff_chars are left to their schema text, which already documents them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: code changes recorded by the capture service, with diff excerpts, plus the filter axes (project, time range, file, symbol, kind). This is clearly distinct from the brain_* sibling tools, so an agent can select it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives two concrete example questions ('what did I change in auth.py last week?', 'when did the parser change?') that map directly onto the filters, and states the precondition that results are empty unless a code folder is being watched. It does not name any alternative tool to prefer or avoid, but no sibling overlaps this domain.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.9.39- Changed
brain_folder1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Project" +}
- Changed
brain_recall1 field changed- added
Input schema / properties / sourceAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" +}
5 tool updates
v0.9.5- Changed
brain_checkpoint1 field changed- added
Input schema / properties / source_refs / descriptionAdded value: +"Links or ids it is based on."
- Changed
brain_context7 fields changed- added
Input schema / properties / as_of / descriptionAdded value: +"ISO time: only what had happened by then (default now)." - added
Input schema / properties / knowledge_cutoff / descriptionAdded value: +"ISO time: only what had been saved by then (default as_of)." - added
Input schema / properties / limit / descriptionAdded value: +"Most items to return." - added
Input schema / properties / max_chars / descriptionAdded value: +"Size cap of the returned text." - added
Input schema / properties / policy / descriptionAdded value: +"auto skips requests with no sign of the past." - added
Input schema / properties / query / descriptionAdded value: +"The user's request, in their words." - added
Input schema / properties / scopes / descriptionAdded value: +"Only these scopes, e.g. [\"global\"] or a project; default all."
- Changed
brain_recall4 fields changed- added
Input schema / properties / as_of / descriptionAdded value: +"ISO time: only what had happened by then (default now)." - added
Input schema / properties / knowledge_cutoff / descriptionAdded value: +"ISO time: only what had been saved by then (default as_of)." - added
Input schema / properties / limit / descriptionAdded value: +"Most items to return." - added
Input schema / properties / scopes / descriptionAdded value: +"Only these scopes, e.g. [\"global\"] or a project; default all."
- Changed
brain_remember12 fields changed- added
Input schema / properties / attributes / descriptionAdded value: +"Optional; usually left empty." - added
Input schema / properties / confidence / descriptionAdded value: +"Optional; usually left empty." - added
Input schema / properties / importance / descriptionAdded value: +"Optional; usually left empty." - added
Input schema / properties / memory_class / descriptionAdded value: +"Optional; usually left empty." - added
Input schema / properties / modality / descriptionAdded value: +"Optional; usually left empty." - added
Input schema / properties / related_memory_ids / descriptionAdded value: +"Ids of memories this one relates to." - added
Input schema / properties / retention / descriptionAdded value: +"Optional; usually left empty." - added
Input schema / properties / scope / descriptionAdded value: +"global, or a project scope to keep it apart." - added
Input schema / properties / source_ref / descriptionAdded value: +"Where it came from: a file, URL or id." - added
Input schema / properties / source_type / descriptionAdded value: +"Leave as is." - added
Input schema / properties / tags / descriptionAdded value: +"Free labels to find it by." - added
Input schema / properties / title / descriptionAdded value: +"Short title; default: the first line of content."
- Changed
code_activity5 fields changed- added
Input schema / properties / change_kind / descriptionAdded value: +"ADDED, MODIFIED or DELETED." - added
Input schema / properties / file_path / descriptionAdded value: +"Path inside the project, e.g. src/auth.py." - added
Input schema / properties / limit / descriptionAdded value: +"Most items to return." - added
Input schema / properties / max_diff_chars / descriptionAdded value: +"Diff excerpt size per change, 200-20000." - added
Input schema / properties / project_id / descriptionAdded value: +"A watched project's id; default all."
1 tool update
v0.9.0- Changed
brain_folder2 fields changed- added
Input schema / properties / export_toAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Export To" +} - added
Input schema / properties / import_fromAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Import From" +}
7 tool updates
v0.1.0- First observed
brain_checkpoint - First observed
brain_context - First observed
brain_folder - First observed
brain_forget - First observed
brain_recall - First observed
brain_remember - First observed
code_activity
TDQS
Scored across 7 tools
Tools are mostly distinct by domain: personal memory (remember/context/recall/forget/folder), team project memory (checkpoint), and code capture (code_activity). The main overlap is brain_context vs brain_recall, both retrieving memory, but the descriptions clearly differentiate a ready-to-read packet from structured rows or turn history. An agent could still occasionally hesitate between them, so not a perfect 5.
All names are lower snake_case, with a strong brain_ prefix for memory tools and a single code_activity outlier for a different domain. The style is consistent and predictable, though it is not a strict verb_noun pattern (e.g., brain_folder, brain_context are nouns while brain_remember, brain_forget are verbs).
Seven tools is well within the ideal 3–15 range for a memory and team-collaboration server. Each tool covers a distinct core operation (save, retrieve, delete, configure, team publish, code activity) without obvious filler.
The surface covers personal memory lifecycle (save, context lookup, raw recall, forget, configuration) plus team checkpoint publishing and code activity. Minor gaps exist: team-brain retrieval is mostly limited to the timeline rather than a general query over published decisions, and direct editing of existing memories relies on supersedes rather than an explicit update operation. These are workable but not full lifecycle coverage.
Maintenance
Related MCP Connectors
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Private persistent memory for Claude, ChatGPT & Gemini via MCP - semantic search, zero-code setup.
Persistent, portable memory for AI assistants — your private memory graph, from any MCP client.
- mcpOAuthai.butlerbrain
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Related MCP Servers
- AlicenseAqualityCmaintenancePersistent memory for Claude Code. Automatically indexes every conversation and provides production-grade hybrid search (BM25 + vectors + reranker) via MCP tools. 100% local, zero config, zero API keys, zero invoice.1617 npm7MIT
- AlicenseNot gradedqualityDmaintenanceCross-machine memory system for Claude Code that records sessions as searchable markdown, syncs across machines via Git, and exposes full-text search, semantic search, session summarization, and a knowledge graph through an MCP server.7 npmMIT
- AlicenseAqualityAmaintenanceSaves the user's exact words as immutable, SHA-256-hashed captures before anything else, then derives events, entities, context cards, and causal hypotheses — every fact traceable to its verbatim source. Local-first personal memory for Claude Code, Codex, and any MCP client.133MIT
- AlicenseNot gradedqualityAmaintenanceEnables Claude Code and other LLM agents to capture, consolidate, and retrieve memories from conversation history, building a local-first knowledge graph with semantic search and dream-state consolidation.25 npm1MIT