bettermemory
bettermemory is a local memory server for AI coding agents that stores durable facts and journal entries, automatically checking staleness against the filesystem and git to flag outdated or incorrect information. It requires intentional retrieval (no auto-injection) and stores each memory as a markdown file for git-syncability.
Core memory operations: Search (with relevance ranking, staleness verdicts, path/commit drift), view full content, list active memories, and get a scope overview with counts and curation pressure.
Writing & managing: Create memories with categories (fact, user-inference, ambient) and confidence; write gates reject transient state, secrets, near-duplicates, and ungrounded claims. Pending user-inference writes require explicit confirm or cancel. Update preserves ID and metadata; removal is tombstone-only (soft-delete) with a reason. Verify attests reality match. Record usage outcomes (ignored, contradicted, corrected) to improve retrieval.
Staleness & verification: Every retrieval includes a staleness verdict (fresh / spot_check_recommended / spot_check_required) based on age, file existence, and git commits since last verification. Audit turns silently detect missed memories.
Scope management: Temporarily disable/enable scopes per session.
Episodes: Journal-style entries (30-day TTL) for transient notes, handoff from prior sessions, cross-session search, and promotion to durable memory with full validation. Supports multi-agent swarm tagging.
The server is fully local, no cloud or account needed.
Uses Git to check stored memories against the working tree and commit history, providing staleness verdicts and detecting path/commit drift so outdated facts are flagged rather than trusted.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@bettermemorywhat's stored about the checkout flow?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
An MCP memory server for coding agents. Stored facts get checked against the filesystem and git before the model relies on them, so a memory that has rotted is flagged instead of quoted back at you.
Install
Claude Code — two slash commands, zero config:
/plugin marketplace add 0Mattias/bettermemory
/plugin install bettermemory@bettermemoryAnything else that speaks MCP:
uv tool install bettermemory
bettermemory init --client claude-desktop # or cursor / cline / claude-code / hermesRestart the client. bettermemory doctor exits 0 when it's wired
correctly and prints a one-line fix for anything that isn't.
Try it without installing: uvx bettermemory try writes a memory
citing a file, deletes the file, and shows the next search flagging it.
Offline, throwaway store.
Related MCP server: Project Brain
What it does
Checks memory before believing it. Every hit carries a staleness verdict: calendar age, whether the paths it cites still exist, the commits landed since it was last confirmed, and how the record entered the store (written here, pulled, or placed by hand). Declared claims (
path,path::symbol,path::NAME=literal) are re-checked against the working tree; a claim that stops being true blocks the stamp instead of riding along.Retrieval is deliberate. Memory is a tool call, not an injection. Write gates bounce transient state, secret-shaped tokens and near-duplicates; claims about you stage for confirmation.
The code is the model. Search is deterministic lexical ranking — keyword + BM25, fused — over your own vocabulary. No embedding models, no downloads, nothing to warm up, same answer every time.
Plain files. One markdown file per memory. Greppable, git-syncable, no cloud, no account. The SQLite index beside the files is a derived cache you can delete;
bettermemory reindexrebuilds it.Rot gets acted on, not accumulated. Episodes journal per-session run-state without polluting durable search; health telemetry and curation tools surface what drifted, what went cold, and what contradicts what.
Receipts, not adjectives. The claims above are measured by preregistered benchmarks whose frozen result artifacts — misses included — live in bench/ (
results/*.json, each carrying the declared terms it was scored under), andbettermemory evalscores whether memory actually helped against your own log (ours is published).
For agents
You were likely handed this link with "set this up." On Claude Code, the two plugin commands above are the whole install — skip to step 3. Everywhere else, steps are idempotent and safe to re-run:
uv tool install bettermemory— orpipx install bettermemory, orpip install bettermemoryinto a venv. Python 3.11–3.14.bettermemory init --client claude-code— likewiseclaude-desktop,cursor,cline,hermes. For any other MCP host, plainbettermemory initprints the canonicalmcpServersJSON snippet plus known config locations. (Continue needs a hand-written YAML entry — see docs/clients.md.)bettermemory doctor— exit 0 means correctly wired; every failed check prints a one-line fix.Have the user restart the client so the server loads, then confirm by asking the model "what memory tools do you have?"
Your operating contract — tool signatures, retrieval discipline,
write gates — is docs/api.md; the server's
instructions block delivers the core policy automatically. For the
long-form policy in your system prompt: bettermemory init --with-addendum. Migrating from Claude Code's built-in auto-memory:
bettermemory ingest imports those files once.
Everything else
The rest is written down: mechanics, storage format, the full tool surface, CLI, configuration and limitations in internals; per-client setup in clients and installation; eval methodology in eval; postmortems in incidents; release history in CHANGELOG; dev setup and the compatibility contract in CONTRIBUTING.
MIT licensed — see LICENSE.
Available Tools
18 toolsepisode_handoffA
Read the most-recent journal takeaways from a prior session in this worktree. Call this FIRST at a /loop iteration entry: it answers 'what did the last session conclude here?' without memory_search. Episodes are the sibling-to-memory primitive for journal-shaped writes (see episode_write).
When prior_session_id is omitted the handler auto-resolves it from the event log under two implicit filters: caller-worktree strict equality (None matches only None) and the disabled_scopes cascade (a session whose only takeaways are scope-disabled is skipped; surviving episodes are scope-filtered). Pass it explicitly to override.
Returns a dict:
prior_session_id: the resolved session id, or None when no prior session exists in the log.episodes: list of {id, created, takeaway, scopes, provenance} dicts, oldest first, capped atmax_episodes(default 5, cap 50).provenanceis read from the event log:local(an episode_write event names the id),untracked(no event could have) orunaccounted(the file appeared with no event: the planted shape).bodyis present only withinclude_bodies=True(default False) and never for an unaccounted episode; episode_search(ids=[...]) is the explicit read for one body.note(optionalstr): set ONLY when the immediately-prior worktree session left nothing visible; names the cause: floor-only, zero-episode, promoted-out, or all-scope-hidden. The last two DID journal, so anotenever means 'wrote no journal'.episodesMAY be non-empty: the walk rewinds to an older takeaway.
| Name | Required | Description | Default |
|---|---|---|---|
| max_episodes | No | ||
| include_bodies | No | ||
| prior_session_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and delivers richly: it discloses the auto-resolution algorithm for prior_session_id (caller-worktree strict equality and the disabled_scopes cascade), the provenance taxonomy (local/untracked/unaccounted), body-presence rules, and subtle note semantics ('The last two DID journal, so a note never means wrote no journal'). This goes well beyond what any annotation set would normally provide.
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?
The description is long but front-loaded: core purpose in sentence one, then usage guidance, then parameter semantics, then a clean bulleted return contract. Each sentence carries distinct information, and the density is justified by the tool's genuine complexity rather than padding.
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?
For a tool with this complexity — auto-resolution, two implicit filters, provenance values, note causes — the description is nearly exhaustive, and the raw return shape is already covered by the declared output schema. The residual gap is error semantics: what happens when an explicit prior_session_id does not exist in the log, and whether the call itself records any event, are unspecified.
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%, and the description fully compensates: max_episodes is explained as a result cap (default 5, cap 50), include_bodies gates the body field (and never for unaccounted episodes), and prior_session_id gets its auto-resolve/override semantics spelled out. Every parameter gains meaning far beyond its bare type and default in 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 specific verb+resource+scope: 'Read the most-recent journal takeaways from a prior session in this worktree.' It explicitly positions itself against memory_search ('without memory_search') and names episode_write as its sibling primitive, so an agent can distinguish it from the memory_* and episode_* siblings without opening their schemas.
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: 'Call this FIRST at a /loop iteration entry: it answers what did the last session conclude here?' It names the alternative it avoids (memory_search) and routes body retrieval to episode_search(ids=[...]), providing both an exclusion and a fallback path. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
episode_promoteA
Promote a journal entry (episode) into a durable memory. Routes through memory_write — the durability gate, scope-mismatch detection, dedup, and user-inference confirmation flow all apply.
Use this when an iteration's takeaway turns out to be a fact worth keeping across sessions, not just a run-state note.
Loop/working state belongs in episodes; session close is when to promote the takeaways that hardened.
On successful commit the source episode is deleted (its content has been distilled). On pending (user-inference category), the source episode is held for memory_write_confirm to delete — memory_write_cancel keeps the episode so you can retry. On any other non-committed status (duplicate, previously_removed, transient_warning, scope_mismatch, ungrounded) the source episode is left untouched so you can adjust and re-promote.
Body default: when use_body=False (default), the durable memory's body is the episode's takeaway. Set use_body=True to use the full episode body. An episode with no takeaway requires use_body=True.
Returns the memory_write response shape plus promoted_from_episode_id, on every outcome.
Parameters:
episode_id: ULID of the source episode.scopes: scopes for the durable memory. Required.category(default 'fact'): memory category. user-inference still requires explicit user confirmation.confidence(default 'medium'),source(default 'explicit-statement'): standard memory_write fields.use_body=False: when True, use the episode's body instead of its takeaway.
| Name | Required | Description | Default |
|---|---|---|---|
| scopes | Yes | ||
| source | No | explicit-statement | |
| category | No | fact | |
| use_body | No | ||
| confidence | No | medium | |
| episode_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries full burden and delivers: it discloses the side effect that the source episode is deleted on commit, and enumerates the exact status handling for every non-committed outcome (pending holds episode, duplicate/previously_removed/scope_mismatch/ungrounded leave it untouched). This is exactly the mutation/reversibility context an agent needs.
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 core action, then layers routing, when-to-use, and outcome semantics in tight paragraphs. Every sentence earns its place; no padding despite the density of behavior covered.
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 operation is complex (deletion side effects, multi-status outcomes, cross-tool routing), and the description covers nearly all of it, including return shape. One minor gap: it notes 'Returns the memory_write response shape' relying on the agent knowing that sibling, though an output schema exists so return-value detail is not required.
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 must compensate. It documents every meaningful parameter: what episode_id is, that scopes is required, category defaults and the user-inference confirmation constraint, confidence/source defaults, and critically the use_body default and the edge case that an episode with no takeaway requires use_body=True.
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 ('Promote a journal entry (episode) into a durable memory') and immediately distinguishes it from siblings by naming the underlying route (memory_write) and the loop-state sibling concept (episodes). An agent can tell this apart from episode_write and memory_write without opening schemas.
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 ('when an iteration's takeaway turns out to be a fact worth keeping across sessions, not just a run-state note') and when-not ('Loop/working state belongs in episodes; session close is when to promote'). Also names alternatives (memory_write_confirm, memory_write_cancel) with the conditions that select them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
episode_searchA
Cross-session lookup for journal-shaped entries (episodes). NOT ranked — episodes are chronological and the filter set (scope / since / session_id) is the discovery surface. For the loop-iteration-entry case prefer episode_handoff, which auto-resolves the prior session and caps the surface.
Rows are oldest-first INSIDE the most-recent-max_results window: over the cap it keeps the MOST-RECENT N, so 'what did I conclude lately?' reads the tail, not the head.
WORKTREE SCOPING: by default (auto_scope=True) the bare discovery walk (no swarm_id / parent_session_id) drops episodes whose captured git worktree differs from yours. PERMISSIVE, not a boundary, and weaker than the strict equality episode_handoff applies — it passes an episode through when there is nothing to compare (none captured, or you outside any git checkout), when the recorded worktree is gone from disk, and when you are in a LINKED worktree of the checkout that wrote it, so under agent fan-out the primary checkout's episodes stay visible. An EXPLICIT swarm_id / parent_session_id / ids is never worktree-filtered: naming a cohort or session is deliberate cross-worktree intent.
Parameters (full reference in docs/api.md):
scopes(optional): keep only episodes whose scope list intersects this filter.parent_session_id(optional): restrict to one session's directory. Composes withswarm_idto narrow a fan-in.swarm_id(optional): fan-in filter — episodes tagged with this cohort id, across all sessions.since(optional ISO-8601): created at-or-after this instant.auto_scope(default True): worktree-scope the bare walk (see WORKTREE SCOPING). False sweeps every worktree sharing the root.max_results(default 20, cap 200): surfaces the most-recent N.ids(optional): only these episode ULIDs — explicit selector, never worktree-filtered; unknown ids are absent, not an error.include_bodies(default True): False OMITSbody— takeaway-only rows. Scan, then re-read one viaids.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | No | ||
| since | No | ||
| scopes | No | ||
| swarm_id | No | ||
| auto_scope | No | ||
| max_results | No | ||
| include_bodies | No | ||
| parent_session_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so richly: it discloses that results are NOT ranked, are chronological oldest-first, that the window keeps the MOST-RECENT N so 'lately' reads the tail, and that default worktree scoping is PERMISSIVE rather than a boundary — enumerating the exact pass-through cases. This is precisely the kind of context annotations would otherwise have to supply.
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 two highest-value facts (not ranked; prefer episode_handoff) and organizes the scoping caveats under a heading. It is dense and long, but nearly every sentence adds non-obvious semantics; only the Rows bullet is somewhat repeated in spirit by max_results.
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?
For an 8-parameter, output-schema-backed retrieval tool with zero annotation and zero schema-description coverage, the description supplies everything needed to call it correctly: ordering semantics, scoping behavior, parameter reference, and sibling routing. Return values needn't be explained since an output schema exists.
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 must carry all semantics, and it documents every one of the 8 parameters with defaults and effects: auto_scope's trade-off, max_results' default/cap, include_bodies omitting body, ids as an explicit never-worktree-filtered selector where unknown ids are absent rather than an error. It fully compensates for the empty schema descriptions.
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 ('Cross-session lookup for journal-shaped entries (episodes)') and immediately distinguishes itself from the sibling episode_handoff for the loop-iteration case. An agent can tell which retrieval tool to open without inspecting schemas.
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?
Names the alternative explicitly ('For the loop-iteration-entry case prefer episode_handoff, which auto-resolves the prior session and caps the surface') and gives a concrete workflow ('Scan, then re-read one via ids'). The when/when-not routing is explicit rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
episode_writeA
Append a journal-shaped entry for the current session — for run-state, iteration takeaways, 'what we tried'. Episodes are NOT durable facts; the durability gate that rejects transient memory_write content (TRANSIENT_PHRASE_MARKERS) does not apply here. Stored at /episodes//.md with a default 30-day TTL.
Use this for content memory_write would reject as transient:
'iteration N tried X, fell over at step 3'
'currently blocked on Y; next step is Z'
'this branch's release plan' (state that changes weekly)
Episodes are invisible to memory_search / memory_health / memory_list — they are a sibling tier, not a memory category. Surface them via episode_handoff at iteration entry or episode_search for cross-session lookup. Promote a takeaway to durable memory via episode_promote (routes through memory_write, durability gate fires as normal).
Parameters:
body: free-form markdown. Required, non-empty. Capped bymax_content_bytes(default 1 MB).swarm_id(optional): cohort id for multi-agent fan-in — a sub-agent passes the coordinator's session id so the coordinator can gather every sub-agent's takeaways viaepisode_search(swarm_id=…). A cross-cutting label, not a move: the episode still lives under this writer's own session, and it is distinct fromepisode_handoff's predecessor link.takeaway(optional): one-sentence summary. Surfaced preferentially at episode_handoff; when None, handoff falls back to the first line of body. Capped bymax_takeaway_bytes(default 4 KB).scopes(optional): list of scope tags. Empty list is valid (handoff keys on session_id, not scope). Capped bymax_scopes_per_write(default 64).
Both caps guard one thing: takeaway and scopes serialise into the YAML frontmatter (64 KB ceiling), so an over-cap value corrupts the file and the episode vanishes from every read surface despite the write returning committed.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | ||
| scopes | No | ||
| swarm_id | No | ||
| takeaway | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so richly: default 30-day TTL, exact storage path (<root>/episodes/<session_id>/<ulid>.md), the 'committed' return value, and the critical failure mode where an over-cap value corrupts frontmatter and silently removes the episode from every read surface. That hidden-failure disclosure is exactly the kind of context an agent cannot infer.
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 purpose and usage before parameter detail, and the bulleted parameter block is easy to scan. It is long, and the closing paragraph on caps slightly restates the per-parameter cap notes, but nearly every sentence carries distinct information.
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 explained, yet the description still notes the 'committed' status. Combined with the tier model, TTL, storage location, and cap-failure caveat, an agent has everything needed to invoke this correctly and interpret the result.
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 must compensate, and it documents all four parameters thoroughly — including subtle semantics like swarm_id being a cross-cutting label rather than a move, empty scopes being valid, the takeaway fallback to body's first line, and per-parameter caps. This goes well beyond a restatement of field names.
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 ('Append a journal-shaped entry for the current session') and immediately positions it as a distinct tier, explicitly contrasting with memory_write ('Episodes are NOT durable facts'). It also names sibling alternatives (episode_handoff, episode_search, episode_promote) so an agent can differentiate without opening any 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?
Explicitly says when to use it ('content memory_write would reject as transient') and reinforces with three concrete examples of qualifying content. It also states what it is not (invisible to memory_search/memory_health/memory_list) and routes each adjacent need to the right sibling tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_audit_turnA
Not for in-conversation use. This tool is dispatched by the client's end-of-turn Stop hook; the model should never call this directly.
Silent-miss telemetry (full reference in docs/api.md). Runs the search probe memory_search would have run for user_message (assistant_response optional), then checks whether a memory_search, memory_show, memory_list, or hook-injected prompt_recall event fired in the same session within lookback_seconds (default 60). A high-relevance probe hit with no retrieval in that window is a miss. Auto-scopes to the caller's repo so the probe matches the model's view; honours session-disabled scopes. Returns a MissReport with verdict in {'miss', 'ok', 'no_signal'} plus the top probe hits. Side-effects: emits turn_audited always, plus search_miss when the verdict is miss.
| Name | Required | Description | Default |
|---|---|---|---|
| user_message | Yes | ||
| lookback_seconds | No | ||
| assistant_response | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility. It discloses side effects ('emits turn_audited always, plus search_miss when miss'), scoping behavior ('auto-scopes to the caller's repo'), the miss detection logic, and return values (MissReport with verdict). This is highly transparent.
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?
The description is dense but every sentence earns its place. It opens with the most critical warning ('Not for in-conversation use'), then covers mechanics, scoping, return, and side effects in three sentences with no 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?
Despite complexity (telemetry, hooks, side effects, output schema), the description covers all necessary aspects: invocation constraints, probe behavior, scoping, miss criteria, events, and return type. It even summarizes verdict values, making it complete even without reading the output 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 0%, so the description must explain parameters. It does so effectively: 'for `user_message` (`assistant_response` optional)' and 'within `lookback_seconds` (default 60)' explains the role and default of each parameter, adding meaning beyond the raw 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?
The description clearly states the tool's purpose with specific verbs: 'Runs the search probe', 'checks whether a retrieval event fired', 'Returns a MissReport'. It distinguishes from siblings by explicitly noting it is 'not for in-conversation use' and is dispatched by the Stop hook, not meant for direct model invocation.
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?
The description explicitly states when NOT to use it ('The model should never call this directly') and when it is used (dispatched by end-of-turn Stop hook). However, it does not explicitly name an alternative tool for direct memory search, though the reference to `memory_search` as the probe implies it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_listA
List active memories. By default returns one-line summaries (IDs, scopes, summary, no body) — cheap triage. Pass with_bodies=True to inline full bodies in one call; useful for small stores where N round trips of list -> show -> show would be wasteful. Don't reach for with_bodies casually — it pulls every memory in scope into your context, which is the failure mode this project exists to avoid. Filter by scopes if you only care about a subset, or by client / model — each row's DECLARED actor, exact. A row's staleness_verdict is CALENDAR-ONLY — no path, claim or commit drift — so a row can read fresh while memory_show on it returns spot_check_required. Read a non-fresh row as a signal to look, never a fresh one as a clearance.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | ||
| client | No | ||
| scopes | No | ||
| with_bodies | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, and it delivers: default vs. body-inlined output, exact-match filtering semantics on declared actor, and a precise caveat that `staleness_verdict` is calendar-only and does not include path/claim/commit drift. The guidance 'never a fresh one as clearance' prevents a dangerous misinterpretation of results.
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?
The description is longer than average, but every sentence adds operational value: purpose, default output shape, the with_bodies trade-off, filter semantics, and the staleness caveat. It front-loads the core behavior and keeps warnings adjacent to the features they qualify.
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 four optional parameters and an output schema, the description is complete: it covers all parameter semantics, warns about the main failure mode (context bloat), and explains output fields like `staleness_verdict`. There is no missing operational guidance an agent would need to call this tool correctly.
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%, yet the description compensates for every parameter: `with_bodies` is explained in depth, `scopes` is defined as subset filtering, and `client`/`model` are clarified as exact filters on each row's declared actor. The defaults are implied by the focus on default triage mode.
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?
The description opens with a specific verb and resource — 'List active memories' — and immediately differentiates the default mode (one-line summaries with IDs, scopes, summary, no body) from the `with_bodies=True` variant, which is clearly distinct from siblings like `memory_show`. An agent knows exactly what this tool returns and how it differs from closer alternatives.
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 explicitly tells the agent when `with_bodies=True` is justified (small stores avoiding N round trips of `list -> show -> show`) and warns against casual use due to context bloat. It also gives clear filtering advice (`scopes`, `client`/`model`) and says a non-`fresh` verdict is a 'signal to look', implicitly directing follow-up to `memory_show`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_record_useA
Override the auto-applied outcome. Default behavior: every memory_search hit settles as applied at turn end (excerpts when the reply used it, auto=true otherwise). The common case handles itself — only call this tool when the model needs to record one of the three actionable outcomes below.
Outcome | When | What it does |
| retrieved but off-topic | annotates later hits; under |
| stored fact disagreed AND not yet fixed | raises the unresolved-contradiction flag until a later memory_update or memory_verify clears it; demotes 2x under the same flag |
| drifted and you fixed it inline (memory_update and/or memory_verify already called) | audit-only; does NOT raise the flag, never demotes |
applied is also accepted explicitly (rarely needed — auto handles it; call only to force-commit early).
Parameters:
memory_ids: list (1+).outcome: see table above.note(optional, ≤800 chars): free-form context.claim_excerpts(optional): list parallel tomemory_ids(same length,Noneslots OK) carrying the load-bearing phrase that shaped the response. ≤500 chars per excerpt. PassNonefor 'no specific claim' — empty strings are rejected (they're ambiguous: missing claim vs. zero-length claim). Especially useful oncontradicted/correctedso the audit log records WHICH claim was wrong, not just that the memory drifted. Surfaces back inrecent_negative_outcomeson later search hits.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | ||
| outcome | Yes | ||
| memory_ids | Yes | ||
| claim_excerpts | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses side effects: demotion under `outcome_demotion`, unresolved-contradiction flag, audit-only for `corrected`, and the auto-applied default. It also explains `claim_excerpts` constraints (empty strings rejected) and their surfacing in `recent_negative_outcomes`.
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?
Although long, the description is well-structured with a markdown table and bullet list. The core purpose is front-loaded, and every sentence adds value, making the length justified.
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 the decision process, side effects, parameter constraints, and edge cases. With an output schema present, return values are unnecessary to explain. It is complete for the tool's complexity.
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?
The schema has no parameter descriptions (0% coverage), so the description fully compensates. The outcome table defines meaningful values, `claim_excerpts` gets detailed parallel-list semantics, and constraints (length limits, None vs empty) are explained.
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?
The description clearly states the tool's purpose: 'Override the auto-applied outcome.' It explains default behavior and when to call, distinguishing it from siblings that modify memory content. The table of outcomes further clarifies its specific scope.
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?
The description explicitly says 'only call this tool when the model needs to record one of the three actionable outcomes below' and explains that the common case handles itself. It also notes that explicit `applied` is rarely needed, giving clear when-to/not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_removeA
Tombstone a memory. The file is moved to .tombstones/ with a removal reason and the originating session id — never hard-deleted. Use when a stored fact is wrong or no longer relevant. Tombstones remain searchable via memory_list_tombstones and are surfaced as removed_matches on memory_write when a new body looks similar to a previously-removed fact, so the lesson encoded in the removal reason isn't lost. Use memory_restore(id) to undo an accidental removal.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| reason | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses the tool's behavior: files are moved to .tombstones/ with removal reason and session id, never hard-deleted. It also reveals downstream effects (searchable tombstones, removed_matches on memory_write) and reversibility via memory_restore, providing rich operational detail.
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?
The description is compact yet information-dense, with each sentence adding value. It opens with the core action, then explains mechanism, use case, searchability, and undo—achieving completeness without unnecessary words.
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 the tool's complexity and the lack of annotations, the description covers the full lifecycle: what happens on removal, where data goes, how it can be searched, how it affects memory_write, and how to undo. It is self-contained and leaves no critical gaps for an agent to safely invoke the tool.
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%, and the description compensates by explaining that 'reason' is the removal reason stored in the tombstone. However, 'id' is only implicitly understood as the memory identifier; the description could explicitly map both parameters. Still, it adds meaningful context beyond the bare 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?
The description opens with 'Tombstone a memory,' a specific verb and resource, and distinguishes it from hard deletion by explaining the tombstone mechanism. It also clearly states when to use it ('when a stored fact is wrong or no longer relevant'), setting it apart from siblings like memory_update.
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?
The description provides explicit usage context: use when a fact is wrong or irrelevant. It names alternatives and complements (memory_restore for undo, memory_list_tombstones for searching) and explains how tombstones surface via memory_write, giving the agent clear guidance on selecting this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_scope_disableA
Disable a scope for the rest of this session. Subsequent memory_search and memory_list calls will exclude memories tagged with this scope. Useful when the user says 'this is unrelated to project X'. Resets when the server restarts.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses the session-scoped effect, which tools are affected (memory_search and memory_list), and the reset behavior on server restart. This goes well beyond the bare schema and gives the agent a clear mental model, though it doesn't mention idempotency or error cases.
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?
Three concise sentences: what it does, the effect, and the persistence. The most critical information is front-loaded in the first sentence, with no filler or repetition. Every sentence adds value.
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 fully covers the tool's purpose, effect on subsequent operations (memory_search/memory_list), the use case, and the reset boundary. Since an output schema exists, return values don't need to be described. It is complete for a simple state-changing operation with one parameter.
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?
The schema provides only a string property with no description, and the description doesn't explicitly define the format or valid values for 'scope'. However, it does clarify the semantic role ('memories tagged with this scope'), which lets the agent infer that scope is a label. For a single parameter this is adequate but not deeply explanatory.
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?
The description uses a specific verb ('Disable') and names the resource ('a scope') with explicit scoping ('for the rest of this session'). It clearly distinguishes from sibling tools, especially memory_scope_enable, by stating the opposite action. The effect on other tools (memory_search, memory_list) is precisely described.
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?
Provides a concrete usage trigger ('when the user says “this is unrelated to project X”') and clarifies session-only behavior with reset on restart. It does not explicitly mention when not to use or directly name memory_scope_enable as the alternative, but the contrast is strongly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_scope_enableA
Re-enable a previously disabled scope for this session.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It discloses that the tool re-enables a scope and that the effect is session-scoped, which is useful context. However, it does not mention edge cases such as attempting to re-enable an already-enabled scope, invalid scope identifiers, or whether the action is reversible. The description offers the basic behavior but lacks depth.
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?
The description is a single, front-loaded sentence: 'Re-enable a previously disabled scope for this session.' It is concise, contains no filler, and communicates the essential purpose immediately. Every word contributes to the meaning.
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?
For a tool with one required parameter, no annotations, and an output schema (not shown), the description is minimally adequate. It clarifies the core operation and session scoping, but it does not explain what a 'scope' is, how to reference it, or what error conditions may arise. The presence of an output schema mitigates the need to describe return values, but there is still ambiguity around scope semantics and edge cases.
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?
The schema has one required parameter 'scope' with no description (0% coverage). The description implies that the parameter is the identifier of the previously disabled scope, giving it some meaning. However, it does not specify the expected format (e.g., name vs. ID), whether there are constraints, or how the scope value relates to other memory tools. It adds minimal semantic value beyond 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?
The description clearly states the action: 'Re-enable a previously disabled scope for this session.' It specifies a precise verb (re-enable), the resource (scope), and contextual constraints (previously disabled, session-scoped). This distinguishes it from its sibling tool memory_scope_disable, which performs the inverse operation.
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?
The description implies usage after a scope has been disabled (it references 'previously disabled scope'), but it does not explicitly state when to use this tool versus alternatives, nor does it name the inverse sibling (memory_scope_disable). There is no guidance on prerequisites or conditions when not to use it. The context is implied but not fully elaborated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_scope_overviewA
Cheap session-start hint: per-scope counts, no bodies / ids / summaries. Call once at the start of a conversation; if total is 0, skip memory_search for the rest of the session unless explicitly asked.
proposals_pending is the count of write-reflex proposals the Stop hook has captured awaiting review via memory_proposals (0 unless the opt-in [proposals] auto_propose is on). pending_writes is this session's staged writes awaiting memory_write_confirm/cancel — a dangling confirmation (silent 1h expiry). curation_pending is an integer-count rollup the model should branch on; the response names its legs. conflicts = contradiction pairs awaiting a memory_conflicts verdict. unaccounted = memories that entered outside every recorded path. curation_unmeasured names legs whose 0 is not a measurement (git or the index did not answer); never read a listed leg's 0 as clean. Non-zero dead or drifted is a cue to suggest a curation pass when there is time; non-zero silent_misses / cold_endorsement_memories is actionable audit backlog. A memory retrieved many times with zero explicit applies is weakly endorsed — worth a look, not a verdict.
Non-zero recently_removed_in_worktree is a 'where did X go?' signal — material was deliberately trimmed here recently; don't blindly re-suggest it.
curation_pending_new_since_last_session is the same shape, filtered to events emitted and memories created since the previous session ended (not memories that aged into a bucket; an older record aging into stale between sessions stays visible only in the absolute curation_pending view — note this is distinct from the separate drifted bucket, which tracks working-tree drift). Branch on it when deciding whether to prompt about curation — non-zero means new rot since the last session, vs. the absolute view which persists until resolved. null on the very first session — fall back to curation_pending.
Default-scoped to the caller's current repository; memories with no origin always pass as global. Set auto_scope=False for the cross-project view. Counts respect session-disabled scopes.
| Name | Required | Description | Default |
|---|---|---|---|
| auto_scope | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does an excellent job: it explains that counts respect session-disabled scopes, that null appears on the first session, that dangling confirmations have a silent 1h expiry, and that certain zero values are not measurements. It also warns against blindly re-suggesting recently removed material. The only minor gap is that it doesn't describe the exact response shape beyond naming fields, but the output schema exists and the description covers the semantics of each field thoroughly.
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?
The description is dense and information-rich, but it is quite long and somewhat sprawling. The first sentence is a strong front-loaded summary, but the middle paragraphs read like a field-by-field reference manual. Every sentence earns its place in terms of content, but the structure could be tightened with bullet points or clearer separation between 'what the fields mean' and 'how to act on them.' It is not concise, but it is structured enough to be navigable.
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 the tool's complexity — many named fields, subtle semantics, session-scoping behavior, and a branching decision for the model — the description is remarkably complete. It covers the return fields' meanings, the null case, the expiry behavior, the measurement caveats, and the action cues. The output schema exists, so the description doesn't need to explain return structure. An agent has everything it needs to call this tool correctly and interpret its results.
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 must compensate for the single parameter auto_scope. It does: 'Default-scoped to the caller's current repository; memories with no origin always pass as global. Set auto_scope=False for the cross-project view.' This adds real meaning beyond the bare boolean schema. It doesn't explain the exact default behavior of auto_scope=True in exhaustive detail, but it gives enough for an agent to use it correctly.
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?
The description opens with a clear verb and resource: 'Cheap session-start hint: per-scope counts, no bodies / ids / summaries.' It immediately distinguishes itself from sibling tools like memory_search and memory_list by stating it returns counts only, not content. The name memory_scope_overview is reinforced by the description's focus on per-scope counts and session-start usage.
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?
The description explicitly says 'Call once at the start of a conversation' and gives a concrete conditional: 'if total is 0, skip memory_search for the rest of the session unless explicitly asked.' It also explains when to use auto_scope=False for the cross-project view and how to branch on curation_pending_new_since_last_session. This is strong when-to-use guidance with clear alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_searchA
Search stored memories. Default: do NOT call — reach for it only when the user references shared context you lack ("my project", "the script we wrote") or a request is ambiguous in a way stored preferences could resolve. When a hit shapes your reply, announce it ("Using your stored preference for…") — non-negotiable. (Full policy: the server instructions block.)
Returns ranked hits with snippets. Per-hit fields the model should branch on:
relevance(high/medium/low) — how much of your query wording the hit literally contains, not how good it is. Weak hits: re-query with different nouns.staleness_verdict(fresh / spot_check_recommended / spot_check_required) — rolled-up signal; != fresh, act onpath_driftbelow.match_terms— which query words actually hit.path_drift_missing(int) +path_drift({checked, missing, verified} when drift detected) — body-cited paths gone.claim_anchored_missing(added when non-empty) is the escalating subset: memory_update those, memory_verify the rest. Prose-scrapedmissingridesfresh— evidence, not a tier.commit_drift_count(int, when applicable) — commits since last_verified_at on the memory's origin repo. Non-zero means the project moved even if calendar-fresh.depends_on_resolved(when present) — bounded auto-pull ofdepends_onlink targets (max 3 per hit, max 10 per call). Each entry:{id, scopes, summary, link_note}. Surfaces context the query wouldn't on its own; saves a memory_show round-trip. OMITTED when the hit has nodepends_onlinks.recent_negative_outcomes(when present) — list of recent ignored/contradicted events for this memory (max two, one per outcome). The user already rejected this; don't re-surface unless you have new reason. OMITTED when none.
Parameters:
query: nouns a memory would contain (tool, file, error names) — vocabulary is the lever, not question phrasing. Weak hits: re-query, different nouns.scopes(optional): filter to scope union.client/model: writer's DECLARED actor, exact; undeclared matches neither.max_results(default 5, cap 50).expand_top=True: inline the full body of the top hit when it has highrelevanceor a decisive score lead over the runner-up — saves a memory_show round trip and surfaces the full path_drift + commit_drift detail.auto_scope=True(default): filter to current repo+worktree; memories with no recorded origin always pass as global. Set False for explicit cross-project queries.since_prior_session=False(default): when True, filter to memories whoseupdatedis strictly after the prior session boundary (latest event from a different session_id in the log). The semantic is 'what has changed in the current session, since the last activity by other sessions' — i.e. this session's intra-session diff. A /loop iteration uses this to track what IT has written/updated; for what the prior iteration did, call episode_handoff instead. Returns empty when there's no prior session in the log; distinguish 'nothing new' (results=[]) from 'no baseline' by also calling memory_scope_overview and checkingcuration_pending_new_since_last_session is None.mode(optional, default from config; package defaulthybrid):keyword,bm25, orhybrid(RRF fusion of both). Every mode is deterministic lexical ranking, so vocabulary is the lever — seequery.
Outcome is recorded automatically via the use_token within ~2 turns; only call memory_record_use to override (ignored / contradicted / corrected).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | ||
| model | No | ||
| query | Yes | ||
| client | No | ||
| scopes | No | ||
| auto_scope | No | ||
| expand_top | No | ||
| max_results | No | ||
| since_prior_session | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden and meets it: it discloses the mandatory announcement obligation, automatic outcome recording via use_token, the exact semantics of since_prior_session vs episode_handoff, the empty-results vs no-baseline distinction, and the cap semantics (max 3 depends_on per hit / 10 per call). This is rich behavioral context well beyond a typical schema.
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 decisive routing rule ('Default: do NOT call') before any field documentation, then organizes return-field semantics as a bulleted list. It is long, but the length is justified by 9 undocumented parameters and 8 output fields. Minor deduction for density — some clauses (annotated can't call it 'padding' but the depends_on cap parenthetical is hard to parse) 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?
Despite an output schema existing, the description goes further and explains how to branch on each returned field (relevance vs quality, staleness_verdict rollup, path_drift_missing vs claim_anchored_missing escalation, commit_drift_count meaning). Combined with parameter semantics and cross-tool routing, nothing an agent needs to call and interpret this tool 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 must compensate entirely — and it does, defining every one of the 9 parameters with non-obvious semantics: query vocabulary guidance, client/model exact-match on declared actor, auto_scope default behavior and the global fallback, expand_top trigger conditions, since_prior_session's strict-after-baseline semantic, and mode defaulting. This is exceptional coverage for an unannotated 9-parameter tool.
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 (search stored memories) and distinguishes itself from siblings by naming memory_show, episode_handoff, memory_scope_overview, and memory_record_use as alternatives for related tasks. An agent can route between memory_search and its siblings from the description alone.
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?
Explicitly states when NOT to call ('Default: do NOT call'), the trigger conditions ('shared context you lack', 'ambiguous in a way stored preferences could resolve'), and names alternatives for adjacent needs (episode_handoff for prior-iteration activity, memory_scope_overview for baseline distinction). This is about as prescriptive as guidance gets.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_showA
Fetch a single memory's full content by id. Typically used after a memory_search snippet looks relevant. The response carries the same staleness signals as a search hit:
verification.status('never' / 'stale' / 'fresh') with an actionablerecommendationwhen not fresh.staleness_verdict(fresh / spot_check_recommended / spot_check_required) — rolled-up signal across calendar, path and commit drift.path_drift(the full report; missing-on-disk paths listed).commit_drift(when caller is inside the memory's origin repo) —status: 'clean' | 'drift'+commits_since_verify.Forward
linksandreverse_linksfor navigation.
When the verdict isn't fresh, spot-check one claim before relying. memory_verify(id, …) if it holds; memory_update if drifted (content updates reset last_verified_at, so verify again after the fix).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It thoroughly explains the response's staleness signals, including conditional commit_drift behavior (only when caller is inside the origin repo), the meaning of path_drift, and the effect of memory_update on verification state. This is far beyond a basic fetch and gives the agent actionable insight.
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?
The description is longer than average, but every sentence earns its place: it explains the purpose, describes the response fields, and gives actionable follow-up advice. The use of bullet-like formatting improves scannability. It is dense but not wasteful, earning a 4 rather than a 5.
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?
Despite having only one parameter and an output schema that presumably describes return fields, the description adds critical interpretive context: how to interpret staleness signals, when commit_drift is present, and what to do in each scenario. This makes the tool's behavior and workflow complete for an agent, with no significant gaps.
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%, but there is only one parameter (id) of type string. The description says 'by id' but does not specify where the id comes from or its format. However, the context of memory_search implies the id originates from search results. Since the parameter is simple and the description is not misleading, a score of 3 is appropriate.
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?
The description opens with a specific action and resource: 'Fetch a single memory's full content by id.' It clearly distinguishes this from sibling tools like memory_search by noting it is typically used after a search snippet looks relevant, making its role in the workflow explicit.
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?
Provides explicit usage context: 'Typically used after a memory_search snippet looks relevant.' It also gives conditional next steps—using memory_verify if the content holds, memory_update if drifted—and warns to spot-check before relying. This is clear when-to-use and alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_updateA
Body edits clear last_verified_at; scope-only edits preserve it. Bundling a scope rename with a body edit clears verification.
Refine an existing memory in place. Preferred over memory_remove + memory_write when correcting a stored fact — preserves id, created, and source; bumps updated.
Parameters (pass at least one):
id: required.content: new body. Replacing the body clearslast_verified_at, the verified-* attestations, andclaims(the prior verification was for prose that no longer exists; call memory_verify again after, re-declaring claims). A body that reads as a claim ABOUT THE USER returnsuser_claim_warningunless the record is alreadyuser-inference; passacknowledge_user_claim=Trueif the subject is someone else. A transient-state body returnstransient_warning;acknowledge_transient=Trueoverrides. An edit that SHRINKS the body and leaves it ending mid-sentence returnstruncation_warning; passacknowledge_truncation=Truewhen the cut is deliberate.scopes/links: REPLACE semantics — pass the full new list, or[]to clear.confidence: low / medium / high.category: acceptsfactandambient.user-inferenceis REJECTED here — that category exists to gate WRITES through the pending-confirm flow; updates have no equivalent gate.
Returns status="stale" when another agent updated the memory first; the hint says to re-fetch and retry. Each links entry is {type, target_id (a ULID), note?}. The types: supersedes (prefer this over the target), contradicts (both cannot be true), extends (adds nuance to it), depends_on (only makes sense in its context). docs/api.md carries the rest.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| links | No | ||
| scopes | No | ||
| content | No | ||
| category | No | ||
| confidence | No | ||
| acknowledge_transient | No | ||
| acknowledge_credential | No | ||
| acknowledge_truncation | No | ||
| acknowledge_user_claim | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral transparency and does so thoroughly. It discloses side effects (clearing last_verified_at and claims), replace semantics for scopes/links, warning triggers and acknowledgment flags, and the stale-status retry behavior. This is rich, non-obvious information beyond the schema.
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?
The description is long but appropriately sized for the tool's complexity. It front-loads the most impactful side effect first, then moves from purpose to parameters to return behavior, using clear section separators. It closes with 'docs/api.md carries the rest' to avoid unnecessary bloat.
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 the 10-parameter complexity and no annotations, the description is remarkably complete. It covers all parameters, warnings, concurrency behavior, link type definitions, and even the stale return condition. With an output schema available for return structure, no critical information is missing for safe invocation.
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?
The schema provides zero descriptions for its 10 parameters, so the description must and does fully compensate. It explains each parameter's role, allowed values (e.g., confidence low/medium/high), special constraints (user-inference rejected), array replace semantics, and the meaning of each acknowledgment flag.
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?
The description clearly states 'Refine an existing memory in place' with a specific verb and resource, and explicitly positions it as the preferred alternative to memory_remove + memory_write when correcting a stored fact. This distinguishes it from siblings and makes its purpose 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?
It explicitly recommends using this tool over memory_remove + memory_write for corrections, explains what it preserves, and includes a concrete exclusion: 'user-inference is REJECTED here' because updates lack the write flow's pending-confirm gate. It also advises calling memory_verify after body edits, offering clear when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_verifyA
Bump last_verified_at to now after spot-checking that a memory's claims still match reality (file paths exist, version still matches, configuration still what it says).
Orthogonal to content edits: this tool does NOT bump updated; memory_update does NOT bump last_verified_at. A typo fix bumps updated only; a verify call bumps last_verified_at only. Idempotent — calling twice slides the timestamp forward.
Parameters:
id: memory id.note(optional, ≤800 chars): what was checked, for the event log.verified_paths(optional list of strings): the ONLY attestation the drift legs read — checked against the memory's own worktree, and the anchor narrowing commit drift. Prefer it when the memory cites paths. Paths absent here are REFUSED. Stored entries re-check whenNonepreserves them — a vanished one blocks the stamp; pass a corrected list.verified_commits/verified_versions(optional lists): audit trail only; nothing on the read path resolves them.verified_absent_paths(optional): attest paths INTENTIONALLY absent here (remote host, other platform, not-the-location) — reported underexpected_absent, notmissing. Never for real drift.claims(optional): memory_write's claim syntax; checked NOW, false ⇒ refused. Stored claims re-check on every verify — a false one blocks the stamp; memory_update first. All five lists are REPLACE, not append —Nonepreserves the prior attestation,[]clears it, a populated list supersedes it. Attest the full set each time. A verify attesting nothing on a memory whose cited paths resolve is refused; the error lists them as the paths to attest.
The stamp records the origin checkout's HEAD as verified_head; commit drift then counts the commits reachable since it (basis: reachability), which sees a branch merged after the stamp.
After memory_update on a memory you later spot-check, verify again — memory_update clears last_verified_at because the prior verification was for prose that no longer exists.
Returns status="stale" when another agent verified first; the hint says to re-fetch and re-attest.
Also resolves an unresolved record_use(contradicted) flag in memory_health when the body still matches reality.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| note | No | ||
| claims | No | ||
| verified_paths | No | ||
| verified_commits | No | ||
| verified_versions | No | ||
| verified_absent_paths | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and fully delivers: idempotency, no mutation of `updated`, replace-not-append list semantics, refusal conditions, `verified_head` tracking, stale status behavior, and resolution of the contradicted flag. It discloses side effects and edge-case behavior in detail.
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?
The description is long, but every section earns its place: parameters, list replacement semantics, stamping behavior, post-memory_update guidance, stale status, and health flag resolution. It is front-loaded with the core purpose and uses clear paragraph breaks for distinct behavioral concerns, with no 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?
For a tool with 7 parameters and subtle behavioral rules, the description is complete: it covers all parameters, refusal cases, preservation vs. clearing semantics, drift detection, stale return status, and interaction with memory_update and memory_health. An agent has enough information to invoke the tool correctly without external knowledge.
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 must explain all seven parameters. It does so thoroughly: `id`, `note` with character limit, `verified_paths` with the critical attestation semantics, `verified_commits`/`verified_versions` as audit-only, `verified_absent_paths` as intentional absences, and `claims` with false-claim refusal behavior.
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?
The description opens with a specific verb and resource: it bumps `last_verified_at` after spot-checking claims against reality. It also names the sibling distinction explicitly by stating that memory_update does not bump `last_verified_at` and this tool does not bump `updated`, making the tool immediately distinguishable.
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?
The description gives clear when-to-use guidance: use it after spot-checking, re-verify after memory_update because that operation clears `last_verified_at`, and it contrasts against memory_update for content edits. This is explicit enough for an agent to choose correctly between siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_writeA
Create a new memory. Call PROACTIVELY when something durable enters the conversation — aggressive writing is safe; the gates below catch bad writes.
Parameters:
content: the memory body.scopes: non-empty list. Avoid the catch-all 'general'; prefer narrow tags liketools,infrastructure,projects:<name>.category(default 'fact'): one offact,user-inference,ambient.fact: project / infra / reference / tooling. Commits immediately (unlessrequire_write_confirmation).user-inference: claims ABOUT THE USER. Always returns {status:'pending', pending_id} regardless of config — ask the user in plain language, then memory_write_confirm or memory_write_cancel. Misattribution sticks; user gets the veto.ambient: context that shapes replies without being cited. Commits like fact, excluded from dead-weight curation; a body over 500 words gets a non-blockingambient_body_longwarning.
confidence('low' / 'medium' / 'high'),source('explicit-statement' / 'inferred').claims(optional): claims the body makes about this repo —path,path::symbol,path::NAME=literal,!path(absent). Checked against the worktree NOW (false ⇒ refused); drift watches the claimed bindings, not whole files. Declare when citing code.groundedness_check=True+source_transcript: optional gate. Sentences with <30% token overlap to the transcript return {status:'ungrounded', claims:[…]}. Override viaacknowledge_ungrounded=Truewhen grounding came from outside the transcript (file reads, tool results).supersedes(optional): ids of active memories this write replaces (each gets asupersedeslink,superseded_byon the stale hit). Also set unasked when a claim-sized body updates a stored claim — a change cue plus a diverging value; with no cue the pair is filed for memory_conflicts.
Return statuses:
committed— write succeeded; payload carries the new id,relatedmatches, and anysupersedes/conflicts_filedrows.duplicate— content dedup fired; the matched memory is credited a corroboration (corroboration_recorded: true, once per session); thehintcarries the remedy.transient_warning/credential_warning/previously_removed/scope_mismatch— gate rejects; each returns what matched and ahintwith the remedy and itsacknowledge_*/force=Trueoverride.user_claim_warning— the body reads as a claim ABOUT THE USER butcategoryisn'tuser-inference. Re-issue as that (the user gets the veto) or passacknowledge_user_claim=Trueif the subject is someone else.pending—category='user-inference'orrequire_write_confirmation.pending_reasondistinguishes.ungrounded— groundedness gate fired.
A committed or confirm response may carry a one-shot per-session curation_hint block ({pressure, threshold, counts, message}) when curation pressure (dead_weight + drifted + cold_endorsement_memories) crosses the configured threshold; memory_health has the full buckets.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | ||
| claims | No | ||
| scopes | Yes | ||
| source | No | explicit-statement | |
| content | Yes | ||
| category | No | fact | |
| confidence | No | medium | |
| supersedes | No | ||
| source_transcript | No | ||
| groundedness_check | No | ||
| acknowledge_transient | No | ||
| acknowledge_credential | No | ||
| acknowledge_ungrounded | No | ||
| acknowledge_user_claim | No | ||
| acknowledge_scope_mismatch | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and disloses extensively: commit vs pending vs duplicate statuses, gate rejects and override remedies, user-inference veto, the grounding gate, supersedes linking, and the one-shot curation_hint. It also frames expected failures as safe: 'the gates below catch bad writes.'
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?
The description is long but front-loaded with core purpose and structured into parameter bullets and return-status bullets, making dense information navigable. Some gate detail is restated in statuses, but the length is justified for a 15-parameter write tool with no annotations.
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?
For a high-complexity mutation tool with no annotations, this covers invocation timing, parameter semantics, refusal modes, override flags, return statuses, and post-write curation. Even though an output schema exists, the extra status documentation removes ambiguity; nothing critical for correct invocation 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%, and the description compensates with rich meaning for nearly every parameter: content, scopes usage, category enum semantics, confidence/source, claims syntax, groundedness_check/source_transcript, supersedes, and the acknowledge/force overrides. This goes well beyond the schema's type/default information.
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 'Create a new memory' – a specific verb+resource that clearly distinguishes this from memory_update (modify) and memory_write_confirm/cancel (pending-write lifecycle). The first line also frames proactive use: 'Call PROACTIVELY when something durable enters the conversation.'
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 clear when-to-use guidance: 'Call PROACTIVELY when something durable enters the conversation' and 'agressive writing is safe.' It also gives scoping advice like avoiding the catch-all 'general'. It does not explicitly say when NOT to use memory_write in favor of memory_update or memory_show, though 'Create a new memory' and the supersedes semantics imply the boundary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_write_cancelA
Drop a pending memory_write without committing. Pass the pending_id from the original write response. Pending writes expire after 1 hour; if the TTL elapsed (or the id never existed) the call returns existed=False.
| Name | Required | Description | Default |
|---|---|---|---|
| pending_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It goes beyond the basic action by disclosing TTL expiration, the behavior when the ID never existed, and the returned `existed=False` field. This is transparent for a cancellation operation.
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?
Two sentences, zero waste. The main action is stated first, then the parameter source, then the expiration behavior. Ideal size for the information provided.
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 tool is simple (one parameter, no nested objects) and the description fully explains what to pass and what to expect in edge cases. An output schema exists, so return values are already structured, and the description adds the necessary nuance.
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 must compensate. It explains that `pending_id` comes from the original write response, which is crucial context not in the schema. For a single parameter, this is sufficient guidance.
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?
The description uses a specific verb ('Drop') and resource ('a pending memory_write') and clearly states the action is cancellation without committing. It distinguishes from sibling tools like memory_write_confirm (which commits) and memory_write (which creates the pending write).
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?
The description explains when to use the tool ('Pass the pending_id from the original write response') and provides essential context (1-hour expiration). It doesn't explicitly name alternatives or exclusions, but the sibling tool names imply these, and the context is clear enough for an agent to select this tool for cancelling pending writes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_write_confirmA
Commit a memory_write that returned status='pending'. Pass the pending_id from that response. Pending writes expire after 1 hour; the confirm call will tell you which case fired (expired vs. never-existed). Re-gated at commit: duplicate / previously_removed / credential_warning can return instead of committed when the store changed during the wait. The staged write survives (pending_retained: true, same pending_id) — memory_write_cancel or resolve the match. The original write's overrides carry over.
| Name | Required | Description | Default |
|---|---|---|---|
| pending_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden, and it delivers. It discloses expiry, the cases that can fire (expired vs. never-existed), re-gated outcomes (duplicate, previously_removed, credential_warning), and that the staged write survives with pending_retained: true. This is rich behavioral detail beyond a simple commit operation.
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?
The description is moderately long but every sentence adds essential information: the commit action, the pending_id source, expiry, re-gating cases, and survival behavior. No fluff, but it could be slightly more concise by grouping related facts. Overall, efficient and well-structured.
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 the tool's complexity and the presence of an output schema, the description covers the main behavioral aspects: what triggers the commit, possible outcomes, and the effects on the staged write. It doesn't explain the output schema itself (not required) but provides enough context to use the tool correctly. Slightly missing is the exact meaning of 'committed' versus other outcomes, but that's implied.
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?
The sole parameter pending_id has no schema description (0% coverage), but the description explains it comes from the memory_write response that returned 'pending'. This adds meaningful context to an otherwise bare string parameter, though it doesn't specify format or constraints. Given the single parameter, this is sufficient.
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?
The description opens with a specific verb and resource: 'Commit a memory_write that returned status='pending''. This clearly states the tool's action and target, distinguishing it from siblings like memory_write_cancel. The mention of pending_id further clarifies its role as a confirmation step.
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 explicitly states when to use the tool (after a memory_write returned 'pending'), and provides guidance on alternatives: 'memory_write_cancel or resolve the match' when the staged write survives. It also warns about the 1-hour expiry and possible re-gated outcomes, giving clear context for decision-making.
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
v7.15.0- Changed
memory_list2 fields changed- added
Input schema / properties / clientAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / modelAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
memory_search2 fields changed- added
Input schema / properties / clientAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / modelAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
1 tool update
v7.4.0- Changed
memory_write1 field changed- added
Input schema / properties / supersedesAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null +}
1 tool update
v7.1.0- Changed
episode_handoff1 field changed- added
Input schema / properties / include_bodiesAdded value: +{ + "default": false, + "type": "boolean" +}
1 tool update
v5.1.0- Changed
memory_update1 field changed- added
Input schema / properties / acknowledge_transientAdded value: +{ + "default": false, + "type": "boolean" +}
3 tool updates
v3.40.0- Changed
memory_update2 fields changed- added
Input schema / properties / acknowledge_truncationAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / properties / acknowledge_user_claimAdded value: +{ + "default": false, + "type": "boolean" +}
- Changed
memory_verify1 field changed- added
Input schema / properties / claimsAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
memory_write1 field changed- added
Input schema / properties / claimsAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null +}
18 tool updates
v3.34.0- First observed
episode_handoff - First observed
episode_promote - First observed
episode_search - First observed
episode_write - First observed
memory_audit_turn - First observed
memory_list - First observed
memory_record_use - First observed
memory_remove - First observed
memory_scope_disable - First observed
memory_scope_enable - First observed
memory_scope_overview - First observed
memory_search - First observed
memory_show - First observed
memory_update - First observed
memory_verify - First observed
memory_write - First observed
memory_write_cancel - First observed
memory_write_confirm
TDQS
Scored across 18 tools
Each tool targets a clearly distinct resource and action (search vs list vs show; write vs update vs remove vs verify; memory vs episode tier; scope enable/disable). Memory_write_confirm and memory_write_cancel are separate and unambiguous, and memory_audit_turn is explicitly not for model use.
All tools follow a consistent pattern: memory_<verb> and episode_<verb>, using snake_case throughout. Verbs are descriptive (write, update, remove, verify, search, list, show). No mixed conventions or vague verbs.
18 tools is on the heavier side but appropriate for a memory server covering memory lifecycle, scoping, verification, usage tracking, and an episode tier. Each tool has a distinct role; no redundancy. Slightly above the ideal 3-15 range but justified by the breadth of the domain.
Core CRUD and verification flows are fully covered (write, confirm/cancel, update, remove, verify, restore via reference). However, tools referenced in descriptions like memory_restore, memory_list_tombstones, memory_conflicts, and memory_proposals are not actually exposed, creating minor gaps. Agents can work around these by using memory_remove and memory_write, but the surface is not entirely self-contained.
Maintenance
Related MCP Connectors
An MCP memory server. One memory your agents share — across models, devices and apps.
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
- KogniteOAuthdev.kognite
Hosted agent memory: store, search, and recall facts across sessions from any MCP client.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server that captures and recalls coding session memory (failures, decisions, diffs) for AI agents, enabling cross-agent continuity and preventing repeated mistakes.41 npmMIT
- AlicenseNot gradedqualityDmaintenanceA local MCP memory server that gives AI assistants durable project memory across coding sessions, storing context, changes, and decisions.5 npm1MIT
- FlicenseNot gradedqualityCmaintenanceA local-first MCP server that manages developer memory for coding agents, enabling shared project context, permissions, and audit trails across different agents.1-
- AlicenseAqualityAmaintenanceMCP server that gives coding agents persistent, verified memory of codebase decisions, conventions, and skills, with evidence-based claims that are re-checked via git hooks and human-gated review. Enables memory search, propose/approve, chat harvesting, and critique across MCP-compatible tools.2158 npm1MIT