bettermemory
This MCP memory server gives coding agents a durable, filesystem-backed memory with automatic staleness checking against the working tree and git, plus a separate episodic journal for run-state.
Search memories (
memory_search): deterministic keyword/BM25/hybrid ranking with relevance, staleness verdicts, path drift, commit drift, and related-context expansion.Read and list memories (
memory_show,memory_list): fetch full memory contents or cheap one-line summaries, with optional inline bodies for small stores.Write memories (
memory_write,memory_write_confirm,memory_write_cancel): proactively store facts, user inferences, or ambient context; gates reject transient state, credentials, duplicates, and ungrounded claims.Update and remove (
memory_update,memory_remove): refine memories in place, replace scopes/links, tombstone stale facts with reasons, and restore if needed.Verify memories (
memory_verify): re-check cited paths, claims, commits, and versions against reality, stampinglast_verified_atwhen they hold.Record outcomes (
memory_record_use): mark memories as ignored, contradicted, or corrected so future searches surface recent negative outcomes.Session scoping: disable/enable scopes for the rest of the session (
memory_scope_disable,memory_scope_enable).Overview and audit (
memory_scope_overview,memory_audit_turn): get per-scope counts, curation pressure, conflict/removal signals, and silent-miss telemetry.Episodic journaling (
episode_write,episode_handoff,episode_search,episode_promote): record transient iteration state, hand off takeaways across sessions, search journal entries, and promote lasting lessons into durable memories.
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 are labelled as inferences, so they stay distinguishable and correctable.
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 the opt-in 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 (require_write_confirmation), 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, as on memory_write.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?
With no annotations, the description carries full burden and exceeds it. It discloses the routing through memory_write, the durability gate, dedup, scope-mismatch detection, the exact outcomes for each status (deleted, held, untouched), and the body default logic. No contradiction with annotations (none present).
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 sentence earns its place. It is front-loaded with purpose, then usage, then outcome behavior, then parameters. No fluff; each piece is necessary for correct invocation. Structure aids comprehension without redundancy.
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 6 params, 0% schema coverage, no annotations, but an output schema, this description is exceptionally complete. It covers the return shape (memory_write response plus promoted_from_episode_id), all edge cases, and parameter semantics, leaving no practical gaps for an agent to call it 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%, so the description must compensate fully. It explains each parameter: episode_id as ULID, scopes as required, defaults for category/confidence/source, and the nuanced use_body behavior with the requirement for episodes without a takeaway. Adds meaning far 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 a clear verb-resource pair: 'Promote a journal entry (episode) into a durable memory.' It distinguishes itself from siblings like memory_write and episode_write by explaining it is the promotion path, not a generic write. No ambiguity or tautology.
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 to use it: 'when an iteration's takeaway turns out to be a fact worth keeping across sessions' and contrasts with loop/working state belonging in episodes. It also references the confirmation flow and names memory_write_confirm and memory_write_cancel as related steps, giving clear context for alternatives.
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 — file a claim about the user with memory_write.
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?
No annotations are provided, so the description carries the full disclosure burden and it discharges it thoroughly: body edits clear last_verified_at and verified-* attestations, scopes/links use destructive REPLACE semantics, three distinct warnings (user_claim, transient, truncation) are each explained with their override flags, and the stale-status race condition is disclosed. The only unaddressed behavior is the acknowledge_credential flag (present in schema, absent in description), which is minor against this breadth.
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 the highest-stakes behavioral caveat (verification clearing) before the purpose statement, then flows through parameters, warnings, and return behavior in a logical order. Every sentence carries substantive information for a 10-parameter tool with no annotations. Slightly verbose (the links-types block and docs pointer could be trimmed), but the density is justified by complexity.
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 complex tool (10 params, no annotations, output schema present), the description covers the destructive side effects, replacement semantics, warning/override protocol, stale handling, and link semantics. The output schema covers return structure, so the status="stale" explanation is bonus context. The acknowledge_credential omission and the tail reference to 'docs/api.md carries the rest' leave small but real gaps; otherwise the agent has nearly everything needed to call 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%, so the description must compensate, and it does extensively: id, content, scopes/links (with REPLACE semantics and [] to clear), confidence (allowed values), category (fact/ambient, user-inference rejected), and three acknowledge flags are all semantically explained. Links entry format and the four type values are spelled out. One genuine gap: acknowledge_credential is in the schema but never mentioned, leaving an agent uninformed about that flag's 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 states a specific verb and resource ('Refine an existing memory in place') and immediately differentiates the operation from a composite alternative: 'Preferred over memory_remove + memory_write when correcting a stored fact.' It also carves out a distinct scope for category, rejecting 'user-inference' and routing that to memory_write. An agent can tell this apart from memory_write, memory_verify, and memory_remove without ambiguity.
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 guidance ('Preferred over memory_remove + memory_write when correcting a stored fact') with the reason (preserves id/created/source, bumps updated), and an explicit when-not ('user-inference is REJECTED here — file a claim about the user with memory_write'). The condition for choosing this over siblings is stated directly, leaving nothing to inference.
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. Commits like fact; the label keeps an inference distinguishable from an established fact, and correctable.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 or passacknowledge_user_claim=Trueif the subject is someone else.pending—require_write_confirmationis on (any category); memory_write_confirm or memory_write_cancel.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 provided, the description carries the full burden — and it is exhaustive. It discloses per-category commit behavior (fact vs ambient vs user-inference), the 500-word ambient warning, claim checking against the worktree (false ⇒ refused), the groundedness gate (<30% overlap ⇒ ungrounded), every return status with its remedy/override, dedup corroboration (once per session), and the one-shot curation_hint block. Nothing about side effects is hidden.
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 sentence earns its place for a 15-parameter tool with zero annotation support. It is well-structured and front-loaded: purpose and when-to-use first, then parameter semantics, then a status reference. It is dense, but the density is justified by the 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?
Despite having an output schema, the description still enumerates all return statuses and their payloads, which an agent needs for correct branching. Given the tool's complexity (15 params, 6+ gate conditions, multiple overrides), the description is effectively complete — an agent could call this tool correctly with no other documentation.
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 does comprehensively. All 15 parameters are explained: scopes with the 'avoid the catch-all general' guidance, category with its three enumerated values and distinct behaviors, source/confidence, claims with syntax examples (path, path::symbol, !path), the groundedness_check/source_transcript pairing, supersedes linking semantics, and every acknowledge_* override and force mapped to its gate. No parameter is left unexplained.
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 opening line — 'Create a new memory. Call PROACTIVELY when something durable enters the conversation' — states a precise verb and resource, and immediately signals the tool's distinctive trigger (proactive durable-conversation events). It is clearly distinguished from siblings like memory_search, memory_update, and the confirm/cancel pair, which are named and routed to in the status section.
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 is explicit about when to call ('Call PROACTIVELY... aggressive writing is safe; the gates below catch bad writes'), encouraging liberal use. It routes to memory_write_confirm/cancel for pending writes and memory_health for curation buckets, and implicitly distinguishes write from update via the supersedes mechanism. It lacks an explicit 'use memory_update when...' exclusion, so it stops just short of full sibling differentiation.
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 +}
TDQS
Scored across 18 tools
The memory_* and episode_* prefixes cleanly separate two tiers (durable memories vs. journal entries), and within each tier the operation verbs (search/list/show vs. write/update/remove/verify) are clearly distinct. The confirm/cancel and scope_disable/enable pairs are unambiguous complements. Even the two search tools are well-differentiated: memory_search is ranked while episode_search is explicitly chronological.
All 18 tools follow a strict resource_prefix + action_verb pattern in snake_case: memory_search, memory_write, episode_handoff, memory_scope_disable. Compound names like memory_write_confirm and memory_scope_overview extend the pattern predictably. No camelCase, no vague verbs, no mixed conventions.
18 tools is slightly above the ideal 3-15 band, but the domain is genuinely rich — memory lifecycle, verification, drift detection, scoping, episodes, and audit all earn dedicated tools. One or two (memory_audit_turn, which is hook-dispatched) could arguably be trimmed from the model-facing surface, but none feels redundant.
The core CRUD lifecycle is well covered (write/update/remove/show/verify/search), but the tool descriptions repeatedly reference tools that are absent from the exposed surface: memory_restore, memory_list_tombstones, memory_health, memory_proposals, and memory_conflicts are all invoked as if callable but not listed. An agent following the memory_remove description's 'use memory_restore(id) to undo' instruction would hit a dead end. There is also no episode_update or episode_remove, leaving the journal tier with no correction path other than promotion.
Maintenance
Related MCP Connectors
Long-term memory for AI coding agents: durable project facts, recalled by every MCP client.
An MCP memory server. One memory your agents share — across models, devices and apps.
Hosted MCP memory for coding agents: persistent across sessions, editable markdown, team sharing.
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server that captures and recalls coding session memory (failures, decisions, diffs) for AI agents, enabling cross-agent continuity and preventing repeated mistakes.91 npmMIT
- AlicenseNot gradedqualityDmaintenanceA local MCP memory server that gives AI assistants durable project memory across coding sessions, storing context, changes, and decisions.2 npm1MIT
- FlicenseNot gradedqualityDmaintenanceA 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.21294 npm1MIT