MemAI
MemAI is an MCP server that gives agents persistent, searchable long-term memory in a single SQLite file, with typed memories, domain-scoped retrieval, diagram workflows, and human-in-the-loop curation.
Write typed memories: note, checkpoint, anti_pattern, reasoning, handoff, and diagram records.
Retrieve memories: keyword BM25 search, recall(), list_by_domain(), list_recent(), timeline(), and pulse() for session warm-up.
Work with diagrams: create/edit nodes and edges, attach linked memories, jump between flows, relayout, and read back as SVG, Mermaid, text, or JSON.
Inspect and edit records: get_memory(), edit_memory() (append/replace content, retitle, retag, set source_ref), link_memories(), get_relations(), set_confidence(), forget() (archive), and purge_memory().
Manage domains and projects: cross-list (also_domain), unfile_domain(), list_domains(), list_projects(), move_to_project(), and domain-casing policy.
Curate memory: dedup_scan(), optimize_scan(), optimize_stage(), optimize_runs(), and optimize_status() for proposing, reviewing, and applying cleanup suggestions.
Self-document: help() explains every tool from its full docstring.
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., "@MemAIremember that my name is Alice"
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.
Agents call MemAI's MCP tools to write memories — facts, decisions, checkpoints, pitfalls, documented flows — during a session and read them back in later ones, which is the state an MCP server's own process does not keep between conversations.
The tools answer any MCP host. What surrounds them targets Claude Code: the hook events that put the store in front of a session, the bundled skills, and the warden subagent that consults it on a session's behalf.
Highlights
Types, not one blob.
note,reasoning,anti_pattern,checkpoint,handoff,diagram— a pitfall is read back by the tool that asks for pitfalls, not found by luck among everything else.Domains are paths. A memory filed on
acme/checkout/billingstill answers a read ofacme, andalsocross-lists it under the subjects that cut across that tree.Keyword retrieval, nothing to download. SQLite FTS5 with BM25 over title, content, tags and domain. No embedding model, no network call, no GPU.
The store reaches a session by itself. Hook events warm a cold session and prompt it to write; the warden subagent reports only the memories that bear on what is actually happening.
Curation stays a person's. Confidence, decay dates, dedup and staged suggestions: an agent proposes, a human applies them in the dashboard.
One file holds a project. Rows, keyword index, edit history, relations, diagrams: a project's whole memory in one SQLite file. Keep one for everything, or one per project and switch between them from the dashboard. Copy it, back it up, delete it.
Related MCP server: heropen
What it looks like
Mid-task, an agent writes down what it just paid for:
note(
title="Stripe sends charge.succeeded twice for one charge",
domain="acme/checkout/billing",
tags="idempotency, webhook, retry, duplicate delivery",
content="A retry carries the same event id, so the handler has to key off "
"the event id. Keying off the charge id lets the second delivery "
"book the order again.",
)Days later a cold session opens on that subject and asks for its bearing:
pulse("acme/checkout")It gets the latest checkpoint in full, the open handoffs and anti-patterns filed anywhere under that path, the newest notes — that one among them — and a count of what the scope holds that the warm-up did not show.
Quickstart
python -m venv .venv
.venv/Scripts/pip install -e ".[dev]" # .venv/bin/pip off Windows
npm ci && npm run build # the admin dashboard
.venv/Scripts/python -m pytestRegister the server with your host, then let it reach a session by itself — the hooks put the store in front of an agent that did not ask for it, and the bundled skills and subagent teach it what to do with them:
claude mcp add --scope user memai C:\path\to\MemAI\.venv\Scripts\memai-mcp.exe
memai-hook install # the four hook events
memai-hook install --skills # the bundled skills
memai-hook install --agents # the warden subagent
memai-hook install --check # what is registered, and what is out of dateSee Hooks and the warden for what each event emits and how to turn the warden off.
Two hosts, two different files. Neither reads the other's, so a server registered in one is invisible to the other, and an empty list in one says nothing about the other.
host | the file it reads | how to write it |
Claude Code — CLI and desktop UI alike |
|
|
Claude Desktop — the chat app | Windows: | edit the file, or Settings → Developer → Edit configuration |
Both hosts take the same block, pointing at the console script the install put in the environment:
{
"mcpServers": {
"memai": {
"command": "memai-mcp"
}
}
}A bare memai-mcp resolves only if that environment's Scripts\ (bin/ off
Windows) is on the PATH of the process that launches the server — and a GUI app
inherits the desktop session's PATH, not your shell's. Unless you know it is
there, give the absolute path instead:
{
"mcpServers": {
"memai": {
"command": "C:\\path\\to\\MemAI\\.venv\\Scripts\\memai-mcp.exe"
}
}
}claude mcp list reports what Claude Code loaded; the desktop app lists what it
loaded under Settings → Developer → local MCP servers. A host reads its config
once, at startup, so restart it after an edit.
On Windows, install.bat does the venv, install and dashboard-build steps, and
run-admin.bat starts the dashboard (both activate .venv themselves; extra
arguments pass through, e.g. run-admin.bat --port 8890). stop-mcp.bat and
stop-admin.bat stop what is running.
Windows locks an .exe while a process is running it, so apip install cannot
rewrite .venv\Scripts until every MCP server and the dashboard are down.
An agent installing MemAI on a new machine follows .agents/install.md: requirements, the order that keeps a running server from breaking the install, both MCP config files, and the checks that confirm the result.
Staying current. The stop hook asks GitHub once a day which releases are
published and caches them — tag, page and notes, one record per release — in
MEMAI_HOME/update.json. A session that starts behind is told which version it
runs, how many releases came after it, what each of them changed (their notes,
flattened to a few plain lines) and the two commands that update this checkout
— for the person to run once every session and the dashboard are closed, for
the reason above. The dashboard shows the same thing at leisure: the version
mark in its app bar carries the count and opens Releases, which renders the
packaged CHANGELOG.md with the running version marked and anything published
since it at the top. memai-hook install --check
prints the same comparison. MEMAI_UPDATE_CHECK=0 stops the request, and
belongs in the environment the host itself runs in: the hook makes it, not the
MCP server, which only reads what the hook cached.
The dashboard
memai-admin (or python -m memai.admin) serves the store at
http://127.0.0.1:8888 — loopback only; --host / --port /
MEMAI_ADMIN_PORT to change. It is where memories are read, edited, triaged and
curated by a person, where the diagrams are arranged, and — behind the version
mark in its app bar — where the release history is read.
memai-admin --status says where it is, memai-admin --stop stops it.
A host starts several MCP servers per session, so the dashboard is started once
and shared: each server asks /api/ping whether one already answers before
trying to bind, and the one that wins keeps the port. It is detached on purpose,
so it outlives the session that opened it.
{
"mcpServers": {
"memai": {
"command": "memai-mcp",
"env": {
"MEMAI_HOME": "/path/to/your/memai-store",
"MEMAI_ADMIN_AUTOSTART": "1",
"MEMAI_ADMIN_PORT": "8888"
}
}
}
}Every variable MemAI reads belongs in that block: a server the host launches
sees this environment and no other, not your shell's. MEMAI_HOME is a
placeholder — drop the line to keep the store at ~/.memai, and on Windows mind
that JSON wants its backslashes doubled.
Where the data lives
Under $MEMAI_HOME if it is set, otherwise ~/.memai. Not tracked in git —
user data, created on first run.
path | what it is |
| the |
| every other project, one file each, named as you named it |
| one line naming the project in use; absent means |
|
|
| generated SVGs, and the warden's per-session state |
A project is one whole memory: its own domains, relations, diagrams and
settings. Any name that works as a Windows file name works as a project
name, and two names that differ only in case are one project. The switch is
in the dashboard's top bar, and every MCP server, hook and dashboard on the
machine opens the active project on its next call — no restart. Every
write's result and every pulse() name the project they touched, and
list_projects() lists them all.
Memories move between projects from the dashboard — a selection in
Memories, or a whole domain in Domains — with move_to_project(), or with
memai-store move. A move copies each memory with its history into the
target, checks it there and only then removes the original, after a backup
of the source is written. What the copy cannot carry — a relation to a
memory outside the selection, a diagram jump across it — is reported before
anything moves.
Documentation
How the parts work lives in the wiki:
page | what it covers |
the tables, and what each one is the record of | |
BM25 keyword search, and what a result carries | |
paths, subtree reads, and belonging to more than one | |
documenting a routine as a graph, and reading it back | |
confidence, decay, staged suggestions, dedup | |
every MCP tool, and the sets that trim the schema cost | |
the four hook events, the skills, and the subagent that consults the store on a session's behalf | |
every view, and export/import |
Licence
MemAI is MIT. Roboto is bundled in webui/fonts/ under the SIL Open Font
License 1.1 (webui/fonts/OFL.txt), separate from MemAI's own licence.
Available Tools
38 toolsalso_domainA
Cross-list an existing memory into one more domain path.
For the membership a memory picks up after the fact: it was filed where
it lives, and later turns out to be part of a subject that cuts across
the tree. Every read scoped to domain returns it from now on, without
moving it -- use the dashboard's re-home for that.
Returns {"uid": ..., "also": [...]} with the whole resulting set. A path the memory's own domain already sits under is dropped as redundant, so the echo is what actually holds.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| domain | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and mostly succeeds: it discloses the additive (non-moving) effect, that every read scoped to the domain will return the memory, that duplicate/redundant paths are dropped, and the shape of the response. It omits auth requirements and failure modes, but the core behavioral semantics are unusually well covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action in sentence one, which is good, but the middle paragraph leans on metaphor ('cuts across the tree', 'the echo is what actually holds') that adds ambiguity rather than precision for a simple two-parameter tool.
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?
There is no output schema, but the description compensates by specifying the return object (`uid`, `also`). Behavior, usage, and result shape are all covered; only parameter-level detail for `uid` is thin.
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 compensate. It conveys the meaning of `domain` (a path, subject to redundancy dedup) but says nothing about `uid` beyond the response echo, so one of two parameters stays undocumented.
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 ('Cross-list') and resource ('an existing memory') plus the target ('one more domain path'), and contrasts against a sibling behavior by saying 'without moving it -- use the dashboard's re-home for that.' This distinguishes it from move_to_project/unfile_domain, though it does not name them directly.
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 a clear triggering scenario: a memory was filed where it lives and later turns out to belong to a cross-cutting subject. It also implicitly sets the boundary that the memory is not relocated. No explicit 'do not use when' or named alternative sibling, so not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
anti_patternA
Record a mistake/temptation to avoid repeating, and the correct approach.
Stored as type='anti_pattern'; open ones for a domain are surfaced by pulse().
also cross-lists it into further domain paths, review_after dates
when to recheck it and source_ref says what it came from -- see note().
ONE pitfall per memory: a second temptation from the same session is its own anti_pattern(), connected with link_memories(). See note() on what a body holds and when it is two memories.
title: one line naming what this memory is about, in the words someone would look for it by. It is what a list shows instead of the opening of the body, and it outweighs every other field in search, so a title that repeats the type ("note about the parser") names nothing. At most 120 characters, and a name that needs more than that is summarizing the body instead of naming it.
tags carries the synonyms the body never uses: retrieval is BM25 over
content and tags, so a memory with none is reachable only by quoting
itself. See note() for what belongs there.
| Name | Required | Description | Default |
|---|---|---|---|
| also | No | ||
| tags | No | ||
| title | Yes | ||
| domain | No | ||
| instead | Yes | ||
| pattern | Yes | ||
| session | No | ||
| why_wrong | Yes | ||
| source_ref | No | ||
| review_after | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses key behavioral traits: storage type is 'anti_pattern', open ones surfaced by pulse(), cross-listing via 'also', review_after semantics, source_ref meaning, and the one-pitfall-per-memory rule. However, it doesn't describe permissions, mutation/reversibility, or return format for a creation tool with 10 params.
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 fairly long and contains several paragraphs, but each has purpose. It front-loads the core purpose, then details parameters. However, some sentences are verbose and repetitively reference 'see note()' three times, and the structure mixes usage rules with parameter semantics without clear separation.
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 10 parameters with 0% schema coverage, no annotations, and no output schema, the description does a good job covering the creation semantics, critical constraints (one pitfall per memory), retrieval behavior, and most parameter meanings. It still leaves some parameters (pattern, why_wrong, instead, domain, session) unexplained, which for a 10-param tool leaves notable 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%, so the description must compensate. It does add meaning for multiple params: clarifies 'title' semantics (one line, max 120 chars, outweighs others in search), 'also' cross-lists into further domains, 'review_after' dates rechecking, 'source_ref' says origin, 'tags' carries synonyms for BM25 retrieval. However, it doesn't explain 'pattern', 'why_wrong', 'instead', 'domain', or 'session' directly, and 0% schema coverage means some gaps remain.
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 a specific verb+resource: recording a mistake/temptation to avoid repeating, plus the correct approach. It also names the storage type ('anti_pattern') and the surfacing mechanism via pulse(). It's not fully distinguished from note() and link_memories() which are referenced but not contrasted, so a 4 rather than a 5.
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 provides clear context: open ones are surfaced by pulse(), it explicitly says ONE pitfall per memory and that a second temptation should be its own anti_pattern() connected with link_memories(). It points to note() for related concepts but never explicitly states when to use this tool versus alternatives like note(). Solid but lacks explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
checkpointA
Snapshot current working state (intent/established/pursuing/open_questions).
A summary of where the work stands, so the next session picks up the right bearing via pulse(). Fields are free-length; still prefer a readable summary here and put timeless detail into note() -- checkpoints are read for bearing, not as an archive. One fact per note(), each cited back here by [[uid]] and linked with link_memories(); pulse() returns the latest checkpoint IN FULL, so every session pays for whatever was parked in these fields. Stored as type='checkpoint'.
title: one line naming what this memory is about, in the words someone would look for it by. It is what a list shows instead of the opening of the body, and it outweighs every other field in search, so a title that repeats the type ("note about the parser") names nothing. At most 120 characters, and a name that needs more than that is summarizing the body instead of naming it.
also: other domain paths this belongs to, comma-separated -- the cross-cutting subjects beside the one it is filed under. See note().
tags carries the synonyms the body never uses: retrieval is BM25 over
content and tags, so a memory with none is reachable only by quoting
itself. See note() for what belongs there.
| Name | Required | Description | Default |
|---|---|---|---|
| also | No | ||
| tags | No | ||
| title | Yes | ||
| domain | No | ||
| intent | Yes | ||
| session | No | ||
| pursuing | Yes | ||
| established | Yes | ||
| open_questions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses storage type ('type=checkpoint'), the cost model (every session pays for what's parked here), and how it's retrieved by pulse(). It does not detail permissions or deletion behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, but grows long with detailed guidance on title, also, and tags. While each section is purposeful, it borders on verbose and mixes tool description with field-level instruction that could be in the schema.
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 no annotations, no output schema, and 9 parameters with 0% schema coverage, the description provides critical context on usage, storage, and retrieval. It is nearly complete for an agent to invoke correctly, though it could say more about the impact of session or domain fields.
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% for 9 parameters, so the description compensates substantially: it documents the purpose of title, also, and tags, and lists the intent/established/pursuing/open_questions fields. Uncovered parameters like domain, session, and the required core fields lack detailed semantics beyond naming.
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 action and resource: 'Snapshot current working state' with parenthetical fields. It distinguishes from siblings via explicit references to pulse(), note(), and link_memories(), but does not directly name why this differs from handoff or reasoning.
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 clear routing guidance: use checkpoint for bearing, put timeless detail into note(), cite facts by [[uid]], and understand it's read via pulse(). It does not provide explicit when-not-to-use versus handoff, but strong context relative to its primary consumer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dedup_scanA
Surface likely-duplicate/contradictory memory pairs.
Lexical overlap over near-identical text -- each pair carries its
method. Two takes on one subject in different words do not surface
here. Same-domain/session checkpoint pairs are excluded (timelines, not
dups)
and checkpoint pairs rank below durable-type pairs. Not an automatic
merge -- returns candidate pairs + similarity score for the agent to
review and decide (link_memories / edit_memory / forget as
appropriate).
domain scans a path and everything nested under it, which is usually what you want: near-duplicates collect between a module and its own routines.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | ||
| limit | No | ||
| domain | No | ||
| threshold | 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 behavioral load and does so well: it discloses the matching method, that each pair is tagged with its `method`, that same-domain/session checkpoint pairs are excluded, and that checkpoint pairs rank below durable pairs. It explicitly clarifies this is not an automatic merge, which is the key safety-relevant behavior. It stops short of describing scoring/threshold effects or result volume.
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 content is front-loaded: what it surfaces, then what it excludes, then what it is not. Sentences are dense but each carries distinct information. There is mild redundancy in the closing paragraph, but 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?
An output schema exists, so return values need not be explained, and the description covers the non-obvious essentials: exclusions, ranking, non-mutating behavior, and next steps. The remaining gap is the un-documented tunable parameters (threshold/limit/type), which an agent needs in order to call it well.
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% for four parameters, so the description must carry parameter meaning and only partly does. It explains `domain` well (scans a path and everything nested under it, with a rationale for why that is usually desired), but `type`, `limit`, and `threshold` (the key similarity cutoff at 0.6) are left entirely undefined.
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+resource (surface likely-duplicate/contradictory memory pairs) and immediately narrows the mechanism (lexical overlap over near-identical text). It differentiates itself from what an agent might reach for instead by declaring that paraphrased takes on one subject do not surface here, which separates it from semantic search/recall siblings.
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 gives a clear when-it-fires / when-it-does-not condition (lexical overlap only; different-words pairs excluded) and routes the agent to the right follow-ups (link_memories / edit_memory / forget). It does not explicitly compare against sibling scan tools like optimize_scan or get_relations, so the alternative-selection guidance is implied rather than complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagramA
Document what a routine does, start to end, as a graph. Stored as type='diagram'.
For a PROCESS, not a fact: note() records what is true, checkpoint() where the work stands, this one how a routine runs. Every step is a separate object that can carry its own explanation and its own links to other memories, which is what makes a diagram the source of truth for its domain instead of one more wall of prose.
Keep every label objective -- what happens at that step, nothing
more. The reasoning, caveats and history belong in that node's
note, where they explain without cluttering the flow.
nodes: [{"key": "load", "label": "Read the export window", "shape": "step", "note": "optional long explanation"}] edges: [{"from": "load", "to": "check", "label": "optional branch"}]
key: stable id the edges refer to; letters, digits, '_' or '-'. shape: start|step|decision|io|end. Exactly one 'start' is required and every node must be reachable from it. Cycles are allowed -- a retry loop is a real flow, not a mistake.
also: other domain paths this flow belongs to, comma-separated. domain
is the routine's own place in the tree; also is for the flows that run
ACROSS routines -- several of them can be steps of one end-to-end
process without any of them being the parent of the others. Cross-list
each into that process's path and asking about it returns all of them,
instead of hoping one search phrasing reaches every one.
review_after and source_ref behave as in note(), and a flow is
exactly the kind of memory they are for: it describes code, and the
code moves.
Returns {"uid": ...}, or {"ok": False, "errors": [...]} with nothing written at all. Node positions are computed and stored server-side, so the flow renders identically for every reader -- see get_diagram().
| Name | Required | Description | Default |
|---|---|---|---|
| also | No | ||
| kind | No | flowchart | |
| tags | No | ||
| edges | Yes | ||
| nodes | Yes | ||
| title | Yes | ||
| domain | No | ||
| session | No | ||
| summary | No | ||
| source_ref | No | ||
| review_after | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers: validation constraints (exactly one 'start', all nodes reachable, cycles allowed), atomicity ('nothing written at all' on error), server-side position computation, and the cross-linking semantics of 'also'. This is unusually rich behavioral disclosure for a mutation tool.
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 purpose before the schema examples, and each block (nodes/edges, key rules, also semantics) earns its place for a complex tool. Some sentences lean editorial ('one more wall of prose', 'not a mistake'), which adds length without operational 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?
For an 11-parameter tool with no output schema and no annotations, the description covers validation, return shape ({uid} vs {ok:False,errors}), and the linking model well. It falls short only on the auxiliary metadata params (kind, tags, session, summary) that an agent still has to guess at.
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 compensate, and it does substantial work: node fields (key/label/shape/note), the key character rules, the shape enum (start|step|decision|io|end), edge from/to/label, and the meaning of 'also', 'domain', 'review_after' and 'source_ref'. However 'kind', 'tags', 'session', 'summary' and 'title' remain entirely undocumented, so it does not fully close the gap.
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 ('Document what a routine does, start to end, as a graph') and pins the storage type ('type=\'diagram\''). It explicitly distinguishes itself from siblings note() and checkpoint(), so an agent can select it 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?
Gives an explicit when-to-use rule: 'For a PROCESS, not a fact: note() records what is true, checkpoint() where the work stands, this one how a routine runs.' It names the alternatives and the discriminating condition, 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.
diagram_edgeA
Wire two steps of a diagram together, relabel that wire, or remove it.
label carries the condition on a branch out of a decision node ('yes', 'no', 'on timeout'). Calling again with the same endpoints updates the label instead of adding a second edge between them.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| label | No | ||
| delete | No | ||
| to_key | Yes | ||
| from_key | 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 add non-obvious value: it discloses upsert/idempotent semantics ('calling again with the same endpoints updates the label instead of adding a second edge'), which is exactly the kind of trait an agent needs. It does not cover permissions, error behavior, or the return shape.
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 tight and front-loaded: the primary action comes first, followed by the label semantics and the idempotency note. Every sentence earns its place with no 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 mutation tool with no annotations, no output schema, and 0% schema coverage across five parameters, the definition covers the core workflow and idempotency but omits 'uid', endpoint semantics, and any error/return context. It is adequate but leaves real gaps for an agent invoking 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. It explains 'label' well (condition on a decision branch, with examples) and implicitly covers from/to via 'two steps' and delete via 'remove it', but 'uid' is never mentioned and endpoints are not named explicitly, leaving part of the 5-parameter surface undocumented.
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 names specific verbs and resource: wire two diagram steps together, relabel the wire, or remove it. It clearly frames this as an edge-mutation tool. However, it does not differentiate itself from the sibling 'diagram_link', which an agent might plausibly confuse with 'diagram_edge'.
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?
Usage is implied by the three operations listed (wire, relabel, remove), and the 'calling again with the same endpoints' note hints at repeated invocation. But there is no explicit when-to-use vs alternatives guidance (e.g. vs diagram_link or diagram_node), and no prerequisites are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagram_jumpA
Continue one step of a flow into ANOTHER flow, optionally at one of its steps.
Not the same statement as diagram_link: that attaches prose explaining a step, this says the rest of this branch is documented elsewhere. Use it where a routine hands off -- a sub-process, an error path owned by another flow, a variant of the same job.
Leave peer_node empty to arrive at the target diagram as a whole.
Stored once and read from both ends, so the return trip already exists
and get_diagram(format='json') reports it on both diagrams. uid and
node_key are this diagram's side either way, which is also how a jump
is deleted from the receiving end.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| label | No | ||
| delete | No | ||
| node_key | Yes | ||
| peer_uid | Yes | ||
| peer_node | No |
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 disclose non-obvious behavior: the jump is 'stored once and read from both ends,' the reverse edge already exists, get_diagram reports it on both diagrams, and a jump can be deleted from the receiving end. It stops short of describing permissions, side-effect profile for the delete flag, or reversibility guarantees.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, and the sibling-contrast and behavioral notes are ordered usefully. Slightly verbose with inline code formatting and parenthetical asides, but no sentence is purely 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 six-parameter mutation-style operation with no annotations and no output schema, the description covers purpose, usage, and some behavior, but leaves label and peer_uid semantics and the delete flag's exact effect under-specified, so an agent still has gaps before invoking 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 only partly does: it clarifies that leaving peer_node empty targets the whole diagram and that uid/node_key denote 'this diagram's side,' plus implicit delete semantics. It never explains label or peer_uid, leaving several of the six parameters undocumented.
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 ('Continue one step of a flow into ANOTHER flow') and immediately differentiates itself from the sibling diagram_link by contrasting what each one represents. An agent can distinguish the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternative (diagram_link) with an explicit contrast of meaning, and gives concrete when-to-use cases: a sub-process hand-off, an error path owned by another flow, or a variant of the same job. Nothing is left to inference about routing between the two link tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagram_linkB
Attach another memory to one specific step of a diagram.
What turns a diagram into an index of its domain: the step states what happens, the linked note/anti_pattern/reasoning states why it is that way. Point at the step the memory actually concerns -- for an edge to the diagram as a whole use link_memories() instead.
get_memory() on the linked memory reports the diagrams that reference it, so the connection is visible from both ends.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| delete | No | ||
| node_key | Yes | ||
| target_uid | Yes | ||
| relation_type | No | explains |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It does add the useful reciprocal-visibility fact (get_memory on the linked memory reports referencing diagrams), but it never explains what the `delete` flag does, whether re-linking the same node_key overwrites or duplicates, or what permissions are required for this mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first line, but the middle paragraph ('What turns a diagram into an index of its domain...') is abstract rationale rather than operational information and dilutes an otherwise compact description. It is not bloated, but it spends words on philosophy instead of on the undocumented delete/relation_type parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations, no output schema, and 0% schema description coverage, the description is the only source of behavioral truth, and it leaves the destructive `delete` flag, the relation_type vocabulary, and overwrite/permission behavior unaddressed. It covers the conceptual model well but not enough for an agent to call a 5-parameter mutation tool safely.
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% across 5 parameters, and the description supplies no parameter-level detail beyond an implicit mapping of 'step' to node_key and 'another memory' to target_uid. `delete` (a destructive toggle) and `relation_type` (with its 'explains' default) are completely undocumented anywhere the agent can see.
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: 'Attach another memory to one specific step of a diagram.' The second sentence clarifies the granularity (per-step, not per-diagram) and explicitly routes whole-diagram links to the sibling link_memories(), so an agent can distinguish it from that tool without reading either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative ('for an edge to the diagram as a whole use link_memories() instead') and the condition that selects it, which is exactly the kind of routing guidance agents need. It stops short of any prerequisites, ordering constraints, or guidance on when NOT to link a given memory.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagram_nodeA
Add, patch or remove one step of a diagram.
Only the arguments you pass are touched, so patching a note leaves the label alone; pass note="" to clear one. delete=True removes the step together with its edges and its memory links.
The whole-graph rules are relaxed here on purpose: a step may sit unattached until you add its edges, which is what lets a flow be built up across several calls. diagram() enforces them.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | ||
| uid | Yes | ||
| note | No | ||
| label | No | ||
| shape | No | ||
| delete | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and discloses important behavior: only passed arguments are touched, note="" clears a note, delete=True removes the step plus its edges and memory links, and unattached steps are allowed. It does not cover error conditions or whether deletion is reversible, but the mutation semantics are well described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action, then efficiently layers in patch semantics, delete behavior, and the intentional relaxation of whole-graph rules. No wasted sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and 0% schema description coverage, the description covers purpose and key mutation behaviors but is incomplete for a 6-parameter tool. It omits meaning for most parameters and does not address error or return behavior.
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% across 6 parameters, so the description must compensate. It clarifies 'note' and 'delete' semantics but leaves 'key', 'uid', 'label', and 'shape' unexplained, leaving the agent without definitions for most parameters.
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 set (add, patch, remove) and resource (one step of a diagram), and distinguishes itself from diagram() by noting that whole-graph rules are relaxed here while diagram() enforces them. The edge mention also implicitly separates it from diagram_edge.
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?
Explains that whole-graph rules are intentionally relaxed so a flow can be built across multiple calls, and contrasts with diagram() which enforces them. However, it does not explicitly state when to use this versus diagram_edge or when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagram_relayoutA
Recompute a diagram's stored node positions from scratch.
Positions live in the store, not in a viewer, so every reader sees the same picture and positions hand-adjusted in the admin dashboard persist. This discards those adjustments and rebuilds the layered arrangement -- the fix for a diagram dragged into a mess.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes |
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 well: it discloses that manual adjustments are discarded, that positions live in the shared store (so all readers see the same picture), and that a layered arrangement is rebuilt. It omits whether the operation is reversible, what permissions are needed, or what the response returns.
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 action is front-loaded in the first sentence, followed by supporting rationale about storage and consequence. Three sentences with little waste, though the middle sentence about store-vs-viewer 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?
For a single-parameter mutation with no output schema and no annotations, the description conveys the key effect (destroys manual positions, rebuilds layout) and the shared-store semantics. The only real gap is that what 'uid' refers to is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the sole parameter 'uid' is undocumented in both schema and description. The phrase 'a diagram's' weakly implies uid identifies the target diagram, but the description does not compensate for the coverage gap.
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: 'Recompute a diagram's stored node positions from scratch.' An agent immediately knows this rewrites layout data rather than editing nodes or edges. It does not, however, name or contrast itself with any sibling (diagram_node, diagram_edge, get_diagram), so it stops short of full differentiation.
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 gives a clear use case -- 'the fix for a diagram dragged into a mess' -- which tells the agent when this tool is appropriate. There is no explicit when-not guidance or named alternative, but the trigger condition is concrete enough for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_memoryA
Correct a memory's content or its source reference, keeping the previous version.
Corrections are common in append-only memory stores that only support delete, not edit; this preserves the old content instead of losing it.
mode='append' adds new_content as a new line at the end instead of
replacing the body. Use it when a memory gains a fact rather than
turning out to be wrong: the alternative is reading the whole thing,
restating it and sending it back, which pays for the body twice and
stakes the existing text on it being copied faithfully. Append what
THIS memory gained. A fact about a further subject is a new memory plus
an edge, not a line at the bottom -- appended text is ranked as part of
the body it lands in and comes back with it.
source_ref points the memory at what its claim came from -- the field
note() takes at write time, and the one a later pass checks the claim
against. It is settable on its own, with no new_content, for the
common case of a body that is right and a reference that is missing or
has moved; an empty source_ref leaves the stored one alone, and
clearing one is a dashboard edit. Passing neither is an error rather
than a silent no-op.
title renames the memory: the one line a list shows it by, and the field weighing most in search, at most 120 characters. Settable on its own, like source_ref. A diagram is renamed through its graph instead -- its title is part of what generates the body, so a rename here would be overwritten by the next structural change.
tags REPLACES the tag set, comma-separated: pass the whole set that should survive, not the one being added. Settable on its own, and indexed, so this is how an untagged memory becomes findable by the words its body never uses. An empty string leaves the stored tags alone -- clearing them, like clearing a source_ref, is a dashboard edit.
Refuses to rewrite a diagram's content: that is generated from the graph, so a hand-written replacement would be silently overwritten by the next structural change -- edit the flow through diagram_node/diagram_edge. Its source_ref is ordinary metadata and is editable here like any other memory's.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| mode | No | replace | |
| note | No | ||
| tags | No | ||
| title | No | ||
| source_ref | No | ||
| new_content | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers: it preserves prior versions, refuses to rewrite diagram content (and why), treats empty strings as no-ops while an empty call is an error, caps titles at 120 characters, and states tags replace rather than merge. This is unusually rich behavioral disclosure.
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 organized per-parameter, with each paragraph earning its place. It is on the long side and the append rationale is somewhat discursive, but little is pure 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 7-parameter, no-annotation, no-output-schema mutation tool the coverage is strong: safety of prior versions, per-field semantics, error vs no-op behavior, and the diagram exclusion are all present. The unexplained `note` parameter and absent return-value behavior are the remaining 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 coverage is 0%, so the description must compensate, and it thoroughly explains mode, new_content, source_ref, title, tags, and uid. However, the `note` parameter is never addressed as an argument (only 'note()' as a function), and the relationship between `note` and `new_content` in replace mode is left to inference, which is a real gap given zero schema documentation.
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?
Names a specific verb and resource ('Correct a memory's content or its source reference') and adds the distinguishing constraint 'keeping the previous version'. This separates it clearly from siblings like forget, purge_memory, and note, which an agent can tell apart 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 states when to use mode='append' (a memory gaining a fact vs turning out wrong), when source_ref/title/tags are settable alone, that clearing is a dashboard edit rather than a call here, and that passing neither content nor source_ref is an error. It also names diagram_node/diagram_edge as the alternative for diagram edits and warns that an unrelated fact belongs in a new memory plus an edge.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forgetA
Archive a memory (soft delete -- content is kept, just excluded from default search/list).
A reason is recorded as a status-change audit entry, without touching
the content.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| reason | No | ||
| superseded_by | No |
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 well: it discloses that content is preserved, that only default search/list is affected, and that a reason is written as a status-change audit entry without modifying content. This is genuinely behavior-relevant. It stops short of 5 by not stating reversibility, permission requirements, or what happens on the response side.
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 short sentences, front-loaded with the core action and its key property (soft delete), with the secondary 'reason' detail following. 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?
Adequate for a small 3-param tool with no output schema: the destructive-vs-non-destructive distinction is covered. However, with 0% param coverage and no annotations, the undocumented uid and superseded_by semantics leave the definition incomplete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It explains 'reason' (recorded as an audit entry, content untouched), which is real added meaning, but says nothing about 'uid' or 'superseded_by', leaving two of three params unexplained in both schema and description.
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 (archive) and resource (a memory) with the critical clarification that it is a soft delete where content is kept. The distinguishing detail from purge_memory is implied by 'soft delete' but the description never names that sibling, so it stops short of full differentiation.
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?
Implies the use case (excluding a memory from default search/list without destroying it), which usefully contrasts with hard deletion, but gives no explicit when-to-use/when-not and never routes the agent between forget, purge_memory, or edit_memory.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_diagramA
Read a diagram back: format='svg-interactive' to show it, 'json' to reason about it.
Formats: 'svg-interactive' (canvas drawing in a pan/zoom shell -- the one to SHOW), 'svg' (same drawing as a plain file, to attach or link), 'mermaid' (portable, but re-lays out and DISCARDS the arrangement the user made), 'text' (the prose projection), 'json' (the full graph with positions, notes and links -- the only round-trippable one, and the one to reason over).
Both SVG formats write the markup to a file and return its path plus a
thin index of the steps; the payload is deliberately too small to draw
from. The returned next_step says what to do with the path, at the
point where it matters. help(command='get_diagram') has the rest.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| format | No | mermaid |
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 well: it discloses that both SVG formats write markup to a file and return only a path plus a thin index ('the payload is deliberately too small to draw from'), that mermaid DISCARDS the user's arrangement, and that `next_step` tells the caller what to do with the path. That is exactly the kind of non-obvious behavioral context annotations would otherwise 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 key routing rule (which format for show vs. reasoning) is front-loaded in the first sentence, and the rest is organized as a compact format inventory followed by return behavior. Slightly verbose with parentheticals, but every sentence carries 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?
For a 2-param, no-output-schema, no-annotation read tool, the description covers format semantics, the actual return shape (file path + thin index + next_step), and defers detail to help(command='get_diagram'). Only the meaning of `uid` is left unaddressed.
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 there are no enums, so the description must define the format values — which it does thoroughly, including round-trippability and side effects per value. The `uid` parameter receives no explanation at all, leaving one of two params undocumented.
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 'Read a diagram back' gives a specific verb (read) plus resource (diagram), and the format list immediately differentiates this from write-oriented siblings like diagram_node, diagram_edge, and diagram_relayout. An agent can tell what it retrieves and in what shapes without opening anything else.
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?
Guidance is explicit per format: 'svg-interactive' is 'the one to SHOW', 'json' is 'the one to reason over', 'mermaid' is portable but re-lays out, 'text' is the prose projection. It stops short of naming when to prefer a sibling (e.g. `diagram` or `diagram_jump`) instead of calling this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_domain_caseA
Report the store's domain-casing policy.
Returns {"mode": "preserve"|"lower"|"upper"}. 'preserve' stores
domains as written; 'lower'/'upper' coerce every domain to that case
on write (a non-conforming domain is adjusted, not rejected, and the
writer's result carries a domain_adjusted note). Read this before
coining a new domain so its casing matches what will be stored.
| Name | Required | Description | Default |
|---|---|---|---|
No 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: it enumerates the returned mode values, explains what each mode means, and discloses a non-obvious behavioral rule — that a non-conforming domain is adjusted rather than rejected and the writer's result carries a domain_adjusted note. That is exactly the kind of cross-tool consequence an agent cannot infer elsewhere.
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 tight sentences: purpose first, return shape second, write-time consequence third, then the usage cue. Every sentence adds information; none restates the name or schema.
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?
No parameters, no output schema, and the description fills that gap by specifying the return payload and the semantics of each value, plus how it interacts with writes. Nothing needed to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate beyond the schema. Baseline for a 0-param tool applies.
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: 'Report the store's domain-casing policy.' It is immediately distinguishable from the sibling set_domain_case, which mutates rather than reads. An agent can classify the tool without opening anything else.
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 usage context: 'Read this before coining a new domain so its casing matches what will be stored.' That is a clear when-to-use trigger, though it never names the counterpart set_domain_case or states when not to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_memoryA
Fetch a single memory's full record, including its edit history and relations.
A diagram also comes back with its mermaid source, its per-node links
and its jumps to and from other flows; any other memory comes back
with referenced_by_diagrams, the flows that point a step at it -- so
a note tells you which processes depend on it without a second lookup.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | 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 behavioral burden. It discloses valuable return-shape behavior -- edit history, relations, and diagram-specific payloads (mermaid source, node links, jumps) vs. referenced_by_diagrams for other memories -- which is genuinely useful context. However it omits the uid format/source, error behavior for missing or wrong-type memories, and whether the record is truncated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose in one clause, then branches into the type-specific return behavior. The mermaid-detail sentence is dense but each clause earns its place by distinguishing diagram vs. non-diagram returns. Slightly verbose in the second paragraph.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations and no output schema, the description correctly compensates by explaining the two return shapes (diagram vs. other memory). It is close to complete for a single-arg fetch tool. Missing only edge-case behavior such as unknown uid or cross-type retrieval, which keeps it from a 5.
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?
Only one parameter, and schema coverage is 0%, so the description's implicit constraint that the target is 'a single memory' that may be a diagram or other type is the only context on parameter semantics. With a single param and unknown uid format, this borders on needing more, but there is little the description could add beyond identifying what the uid addresses. Baseline 4 for a single-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 (Fetch) and resource (a single memory's full record), and scopes it to a single item, which distinguishes it from search/recall/list_recent siblings. It stops short of naming an alternative for retrieving multiple memories, so differentiation is implied rather than 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?
Usage is implied by 'single memory' versus the list/search siblings, but there is no explicit when-to-use or when-not-to-use guidance, and no named alternative for the multi-memory case. Adequate but with a clear gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_relationsA
List all relations (incoming and outgoing) for a memory.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description bears full responsibility for behavioral disclosure. It accurately states that the tool lists both incoming and outgoing relations, implying a read-only operation. However, it omits potential details like pagination or ordering, but for a simple list tool this is adequate.
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 sentence of 8 words with no filler or redundancy. It is front-loaded with the action and resource, making it easy to parse quickly.
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 simplicity (one parameter), and the existence of an output schema documenting return values, the description sufficiently covers its purpose. It clearly states what is listed (incoming and outgoing relations) and for which memory, meeting completeness needs.
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 indicates that 'uid' is the unique identifier of a memory, adding basic context. However, it does not specify the expected format of the UID (e.g., UUID or string pattern), leaving some ambiguity.
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 'list' and specifies the resource 'relations (incoming and outgoing) for a memory'. It clearly distinguishes from siblings like 'get_memory' (gets a single memory) and 'link_memories' (creates relations).
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 states it lists all relations for a memory, but provides no guidance on when to use it over alternatives like 'search' or 'list_by_domain'. No explicit when-not-to-use or prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
handoffA
Leave a note for another agent/session picking up this work.
Stored as type='handoff'; open ones for a domain are surfaced by pulse().
also cross-lists it into further domain paths -- see note().
content holds the message and what the next agent needs to act on it.
Durable knowledge goes to note() and is cited from here -- see note()
on when a body is two memories.
title: one line naming what this memory is about, in the words someone would look for it by. It is what a list shows instead of the opening of the body, and it outweighs every other field in search, so a title that repeats the type ("note about the parser") names nothing. At most 120 characters, and a name that needs more than that is summarizing the body instead of naming it.
tags carries the synonyms the body never uses: retrieval is BM25 over
content and tags, so a memory with none is reachable only by quoting
itself. See note() for what belongs there.
| Name | Required | Description | Default |
|---|---|---|---|
| also | No | ||
| tags | No | ||
| title | Yes | ||
| domain | No | ||
| content | Yes | ||
| session | No |
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 well: it discloses the storage type ('handoff'), that open ones surface via pulse(), that `also` cross-lists into further domain paths, and that retrieval is BM25 over content+tags so an untagged memory is reachable only by quoting itself. It omits permissions, error/overwrite behavior, and return format, keeping it short of a 5.
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 purpose and the type/pulse/also facts efficiently. However, the 'see note()' pointer is repeated three times and the title/tags paragraphs run long, so a few sentences are redundant rather than earning their place.
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 6-param tool with no annotations, no output schema, and 0% schema coverage, the description covers the core write semantics well. The gaps are the unexplained domain/session parameters and no hint of the result, so it is close to but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It explains title (with a hard 120-char limit and search-weighting rationale), content, tags, and `also` (cross-listing), but leaves `domain` and `session` entirely unexplained, so two of six parameters remain undocumented anywhere.
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 ('Leave a note for another agent/session picking up this work') and immediately distinguishes it from its closest sibling by routing durable knowledge to note(). An agent can tell handoff apart from note() and pulse() 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?
Gives clear selection context: use this to hand work to another session, while 'Durable knowledge goes to note().' It also names pulse() as the surfacing mechanism. It stops short of explicit when-not-to-use conditions, but the note()/handoff split is well drawn.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
helpA
Explain the memai tools, read directly from their code docstrings.
Without arguments: every tool with its one-line summary, and which of them this process did not load (MEMAI_TOOLS). With command='': that tool's signature and its FULL documentation -- longer than the schema description, because the schema is paid for on every request and this is paid for when someone reads it.
| Name | Required | Description | Default |
|---|---|---|---|
| command | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses that the no-arg mode also reports which tools this process did not load (MEMAI_TOOLS), and explains the docstring-vs-schema tradeoff. It doesn't state auth or rate-limit behavior, but for a read-only help tool that gap is minor.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then the two modes. Mostly earning its place, though the parenthetical about schema cost being 'paid for on every request' is a bit of editorializing that could be trimmed without losing 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 single-optional-param help tool with no output schema and no annotations, the description covers both invocation modes and what each returns, which is what an agent needs to call it correctly. It stops short of describing the exact docstring format, but that is not essential to invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% (the 'command' param has no schema description), so the description must compensate. It does: command='<name>' selects a specific tool's signature and full documentation, versus an empty/omitted value returning the full list. The syntax format is given, though the exact accepted name set is not enumerated.
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: 'Explain the memai tools, read directly from their code docstrings.' It is unmistakably the meta/help tool and cannot be confused with any sibling like search or recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly branches usage by input: 'Without arguments' returns the full tool list, and 'With command=<name>' returns that tool's signature and full docs. The conditions that select each mode are named 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.
link_memoriesA
Create a queryable edge between two memories.
relation_type is free text but keep it consistent, e.g. 'supersedes', 'relates_to', 'contradicts', 'links_to'.
This is what splitting a body into several memories costs: a [[uid]] written inside prose is a reference a reader follows, and only an edge created here is visible to get_relations() and to the graph.
Refuses an unknown uid, a memory related to itself, and an edge that already exists with that same type -- each as {"ok": False, "errors": [...]}, so a typo comes back as something to fix instead of a dangling edge or a raw database error.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | ||
| to_uid | Yes | ||
| from_uid | Yes | ||
| relation_type | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavior burden and does well: it discloses validation rules (unknown uid, self-edge, duplicate edge with same relation_type) and the exact failure shape {"ok": False, "errors": [...]}. It does not mention permissions, transactionality, or whether an edge is reversible/deletable, so a small gap remains.
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 core action is front-loaded in one sentence, followed by the relation_type convention and the error contract. The 'what splitting a body into several memories costs' passage is motivational rather than operational, but it earns its place by justifying the tool's existence.
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 4-parameter mutation tool with no annotations, no output schema, and 0% schema description coverage, the description covers the error contract and relation_type but leaves the 'note' parameter and uid semantics unexplained. Usable, but not complete enough to fully compensate for the missing structured metadata.
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 compensate and only partly does. It documents relation_type as free text with example values, and from_uid/to_uid are implied as memory uids by context, but the optional 'note' parameter is never mentioned and no uid format is specified.
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 first sentence states a specific verb and resource: 'Create a queryable edge between two memories.' It also names the downstream consumer, get_relations(), which implicitly separates it from sibling graph tools like diagram_link. It stops short of explicitly contrasting with diagram_edge/diagram_link, so it is clear but not fully sibling-differentiating.
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 the condition that motivates the tool: a [[uid]] inside prose is only a reference, whereas an edge is what get_relations() and the graph can see. That gives clear context for when to reach for it, but there is no explicit when-not or named alternative (e.g., when to prefer diagram_link instead).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_by_domainA
List active memories for a domain and its subdomains, most recent first.
Fallback when search misses. domain is a path, matched from the outermost segment in: 'acme/x100' lists the module's own memories plus every routine under it. Pass subtree=False for what is filed at exactly that path and nowhere deeper.
A domain that matches no path is retried as a run of segments INSIDE
one, so list_by_domain('p200') still finds the routine once it lives
at 'acme/x100/p200'. The literal reading wins whenever it has rows,
and an ambiguous name (the same code under two modules) covers both
branches rather than picking one -- each row's domain says which
branch it came from. list_domains() is the way to see the paths first.
Returns {"results": [...], "est_tokens": N}. Content is
snippet-truncated per result -- call get_memory(uid) for the full
record; a result's est_tokens estimates what that full record costs,
and the top-level est_tokens is the sum over the results.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | ||
| limit | No | ||
| domain | Yes | ||
| subtree | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full load and does so thoroughly: path-segment matching from the outermost segment, substring retry when no path matches, literal-reading-wins precedence, ambiguity covering both branches with the `domain` field disambiguating, result truncation to snippets, and est_tokens semantics. These are genuine runtime behaviors an agent cannot infer from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and routing before the mechanics; four short paragraphs each carrying distinct rules (fallback, path matching, substring/ambiguity retry, return shape). It is somewhat long, but almost every sentence conveys unique behavioral information rather than restating the title or schema.
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?
No output schema exists, yet the description supplies the return shape ({"results": [...], "est_tokens": N}), the truncation caveat, and the pointer to get_memory(uid) for full records. With annotations absent and 0% schema coverage, it covers nearly everything except the meaning of the `type` and `limit` parameters.
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 `domain` (path semantics, segment matching, ambiguous-name coverage) and `subtree` (exact-path vs. descendant listing) in real depth. However, `type` and `limit` receive no explanation anywhere, leaving two of four parameters undefined.
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 sentence names a specific verb and resource ('List active memories for a domain and its subdomains') plus an ordering guarantee ('most recent first'). It further positions itself against siblings by framing the tool as a 'Fallback when search misses' and pointing to list_domains() for path discovery. An agent can distinguish this from search, recall, and list_recent 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?
Explicit routing rule ('Fallback when search misses'), explicit prerequisite guidance ('list_domains() is the way to see the paths first'), and explicit switch semantics ('Pass subtree=False for what is filed at exactly that path'). The fallback/ambiguity behavior tells the agent when this tool is preferable to search. Nothing material 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.
list_domainsA
List the domain tree: every path with its counts and latest activity.
Warm-up discovery. domain is free text and drifts over time (e.g. 'proj-1042' vs 'proj-1042-cache-warmup'), so this surfaces the paths actually in use instead of leaving you to guess one. Ordered by most recent activity.
Per entry: domain (the full path), parent, depth, count (filed
at exactly this path), subtree (that plus everything nested under
it), children, and implicit -- true for a level that exists only
because something deeper is filed under it. Read subtree to pick the
scope worth warming up: a parent holding nothing of its own can still
be where the work is.
also and subtree_also are the same two counts for memories
CROSS-LISTED here rather than filed here -- the cross-cutting subjects.
A path with count 0 and also above it is one of those and nothing
else: an end-to-end flow whose steps all live under other branches.
Reads scoped to it return them all.
Casing may be enforced store-wide -- call get_domain_case() to see the active policy before coining a new domain.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
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 ordering by most recent activity, implicit levels, cross-listed counts (also and subtree_also), and casing policy enforcement. For a zero-param read/list tool, this is substantial transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the main purpose in the first sentence, then proceeds through usage and output semantics. It is long and explains return fields despite an output schema existing, so some content is verbose, but the structure is logical and the extra detail is mostly useful.
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 a zero-param list tool with an output schema and no annotations, the description is complete. It covers purpose, discovery context, return-field meanings, cross-listing behavior, and the related casing-policy tool, leaving no major ambiguity for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter schema for the description to clarify. Baseline for zero params is 4, and the description appropriately focuses on output semantics instead.
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: 'List the domain tree: every path with its counts and latest activity.' It also frames the tool as warm-up discovery for surfacing domain paths in use, which distinguishes it from guessing or searching for a domain. The core purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context: warm-up discovery, reading subtree to pick a scope worth warming up, and calling get_domain_case() before coining a new domain. It does not explicitly name when-not-to-use or compare against sibling tools like list_by_domain, but the intended context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_projectsA
The projects in this home, and which one every call here reads and writes.
A project is one SQLite file with its own memories, domains, relations
and diagrams. The active one is switched in the admin dashboard, and a
running server follows on its next call -- so every write's result names
the project it landed in, and pulse() names the one it read. Each entry
carries name, memories (the active rows) and active. Names are
matched without regard to case wherever a tool takes one.
| Name | Required | Description | Default |
|---|---|---|---|
No 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 meaningful work: it explains the active-project switching semantics, that running servers follow on the next call, that write results name their landing project, and that pulse() names the read project. It omits whether the list itself is read-only or paginated, but discloses the key behavioral context.
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 first sentence is well front-loaded and states the core purpose, but the paragraph then expands into cross-tool narrative (pulse(), write results, case matching) that is tangential to a zero-argument list tool, adding length without directly serving invocation.
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 no-parameter, no-output-schema list tool, the description supplies the field names returned (`name`, `memories`, `active`) and the semantics of the active project, which is enough to call and interpret it. It stops short of stating pagination or ordering behavior.
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?
Zero parameters, so the baseline is 4. The description usefully adds case-insensitive name matching semantics that apply wherever a tool takes a project name, which is relevant context even though no parameter exists here.
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 resource (projects in this home) and clarifies the scope that no parameter controls. It does not explicitly differentiate from the sibling list_domains, which lists a different resource type, but the resource is stated clearly.
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?
Usage is implied by describing what the tool returns and how the active project is switched (admin dashboard). There is no explicit when-to-use or when-not-to-use guidance, and no named alternatives like list_domains or move_to_project.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_recentA
List the most recent active memories, optionally filtered by type/domain.
A domain covers its subdomains, and a bare deep segment resolves to the branches holding it (see list_by_domain); subtree=False narrows to that exact path.
Returns {"results": [...], "est_tokens": N}. Content is
snippet-truncated per result -- call get_memory(uid) for the full
record; a result's est_tokens estimates what that full record costs,
and the top-level est_tokens is the sum over the results.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | ||
| limit | No | ||
| domain | No | ||
| subtree | No |
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 well: it discloses that content is snippet-truncated per result, explains that est_tokens on a result estimates the full-record cost while the top-level est_tokens is the sum, and directs the agent to get_memory for complete records. It omits ordering guarantees, pagination, and auth requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then domain-resolution nuance, then return-shape details. Every sentence carries information, though the est_tokens explanation is dense enough to require careful reading.
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?
No output schema exists, but the description supplies the return shape and truncation behavior, and it addresses three of four parameters. Only the `limit` parameter remains undocumented, which is a minor gap for a list tool with zero required arguments.
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 adds real meaning for type/domain filtering and especially subtree (domain covers subdomains; subtree=False narrows to the exact path), but the `limit` parameter is never mentioned and no accepted `type` values are given.
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 (list the most recent active memories) with a clear scope (optionally filtered by type/domain). It references the sibling list_by_domain for domain semantics, giving partial sibling differentiation, though it never contrasts itself against search or recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the name and the 'optionally filtered' clause, and it routes the agent to get_memory(uid) for full records. However, it never states when to prefer this over search, recall, or list_by_domain, so the agent must infer the selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_to_projectA
Carry memories from the active project into another one, and remove them here.
uids is comma-separated, domain a path (its subdomains and archived
rows go too); give either or both. Each memory travels whole -- body,
cross-listings, usage counts, edit history, the relations and diagram
graph inside the slice -- into target, is checked there, and only
then purged from the active project, after a backup of it is written.
dry_run is the default and moves nothing: it reports what would move,
conflicts (uids target already holds, which stay here) and
outside -- the relations, diagram links and jumps, superseded_by
marks and [[uid]] references that cross the edge of the slice, all of
which the move drops. Read that report with the user, then widen the
slice or accept the loss BEFORE calling again with dry_run=False: the
purge is irreversible short of the backup. create makes a target
that does not exist yet. list_projects() names the projects there are.
| Name | Required | Description | Default |
|---|---|---|---|
| uids | No | ||
| create | No | ||
| domain | No | ||
| target | Yes | ||
| dry_run | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers: the purge is irreversible short of the backup, a backup is written, conflicts (uids target already holds) stay put, and 'outside' edge artifacts (relations, diagram links/jumps, superseded_by marks, [[uid]] references) are dropped. This is precisely the destructive, lossy behavior an agent must know.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, then parameters, then the dry_run workflow. Slightly dense with parentheticals and backticks, but every clause carries operational weight and nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-param destructive move with no annotations and no output schema, the description is close to complete: it covers scope, loss, backup, conflicts, target discovery, and the safe dry-run-first workflow. It doesn't explicitly describe the shape of the dry_run report fields beyond naming conflicts and outside, which is a minor gap.
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 does: uids is comma-separated, domain is a path whose subdomains and archived rows go too, either or both may be given, dry_run's default and meaning are spelled out, and create makes a missing target. Meaningful semantics far beyond the bare schema titles.
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: carry memories from the active project into another and remove them here. It goes beyond a simple rename by describing exactly what travels and what is purged, and names the sibling list_projects() as the way to discover targets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use and a strong workflow rule: dry_run defaults to reporting-only, read the report with the user, then widen the slice or accept the loss BEFORE calling again with dry_run=False. It also explains the create flag for non-existent targets. This is genuine when/how guidance, not inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
noteA
Save a general long-term memory (fact, decision, finding). Stored as type='note'.
Timeless knowledge -- retrieved by relevance, not recency. Bring it back with recall() (or search(type='note')); pulse() also shows the few most recent ones as warm-up breadcrumbs.
title: one line naming what this memory is about, in the words someone would look for it by. It is what a list shows instead of the opening of the body, and it outweighs every other field in search, so a title that repeats the type ("note about the parser") names nothing. At most 120 characters, and a name that needs more than that is summarizing the body instead of naming it.
content: ONE fact, and what a reader needs to use it -- what holds, where it holds, what it rules out. Retrieval ranks whole memories, so a body answering four questions comes back for all four and is read for one: write the second subject as its own memory, on its own domain, and connect the two with link_memories(). A [[uid]] typed inside a body is a reference a reader can follow, not an edge -- get_relations() and the graph do not see it until link_memories() creates one. Past a couple of thousand characters, a body is usually several memories written as one.
domain: the subject this belongs to, as a path from the outermost scope in ('acme/x100/p200'). File it as deep as the fact is specific -- a note about one routine goes on the routine, and still comes back when someone asks about the module or the product above it.
also: other domain paths this belongs to, comma-separated. domain is
where the memory LIVES -- one path, one parent chain. also is for the
subjects that cut ACROSS that tree: the same routine belongs to the
module it runs in and to the end-to-end flow it is one step of, and
neither of those is the other's ancestor. Every read scoped to any of
those paths returns it. A path that domain already sits under is
dropped as redundant -- the result echoes what was stored.
tags: comma-separated keywords and synonyms. Retrieval is BM25 over content, tags and domain paths, and tags weigh second only to the body, so they are where a memory becomes findable by words its own text never uses -- the identifier, the symbol, the error string, the plain-language phrasing someone will actually type. A memory with none is reachable only by quoting itself.
review_after: when this stops being safe to trust unchecked, as a date
('2026-11-01') or a span from today ('90d'). pulse() counts what is
overdue in a scope as scope.stale and optimize_scan lists it. Leave
it empty for anything that does not go stale -- most facts do not, and
a date nobody meant is worse than none.
source_ref: what the fact came FROM -- a path, a URL, a table name -- so a later pass can check the claim against the thing itself instead of inferring what to check from the wording.
| Name | Required | Description | Default |
|---|---|---|---|
| also | No | ||
| tags | No | ||
| title | Yes | ||
| domain | No | ||
| content | Yes | ||
| session | No | ||
| source_ref | No | ||
| review_after | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and discloses real behavior: input weighting in BM25 (title outweighs all, tags second to body), redundant domain paths being dropped and echoed back, [[uid]] not creating graph edges until link_memories(), review_after surfacing as scope.stale in pulse()/optimize_scan, and length warnings. This is well beyond a bare field list.
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 purpose sentence, then header-per-parameter structure, which is appropriate given 0% schema coverage. The length is largely earned, though a few editorial asides ("warm-up breadcrumbs") could be trimmed.
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-param, no-annotation, no-output-schema tool, the description is nearly complete: storage semantics, retrieval behavior, and all params but `session` are covered. Return values need not be explained absent an output schema, but the undocumented session param leaves a small gap.
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 richly documents 7 of 8 params (title, content, domain, also, tags, review_after, source_ref) with formats and examples. The `session` parameter is entirely unmentioned, leaving one gap in an otherwise strong effort.
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 ("Save a general long-term memory") and clarifies the stored type (type='note'), and routes retrieval to recall()/search()/pulse(). It implies differentiation from specialized save siblings (checkpoint, handoff, anti_pattern) via the word "general," but never names those siblings explicitly to draw the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear when-to-use context ("Timeless knowledge -- retrieved by relevance, not recency") and names the retrieval alternatives. However it offers no explicit when-NOT-to-use guidance and does not route between this and the other write-time siblings (checkpoint, handoff, reasoning), leaving that selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
optimize_runsA
List optimization runs with their review progress.
Read-only companion to optimize_stage: after staging, use this to see whether the user has applied/rejected your suggestions in the admin dashboard. Each run carries total/pending/applied/rejected counts, its note, and the safety-backup path once the first apply happened. Applying/rejecting stays in the dashboard by design -- the agent proposes, the human disposes.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, the description fully discloses read-only nature, the counts, note, and safety-backup path, and the workflow division. Could be 5 but lacks explicit mention of no side effects beyond read.
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 paragraphs with front-loaded purpose and concise supplementary context. Slightly wordy but every sentence adds value; no 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?
The description fully covers purpose, usage timing, output contents, and relationship to sibling tool, leaving no gaps for this simple list tool with no parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters and 100% schema coverage, baseline is 4. The description adds value by explaining the output fields (counts, note, backup path) which enriches understanding beyond the empty 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 verb 'List' and the resource 'optimization runs', and distinguishes itself from optimize_stage by specifying it's a read-only companion for post-staging review.
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 'after staging, use this to see whether the user has applied/rejected your suggestions in the admin dashboard' and clarifies that applying/rejecting stays in the dashboard, effectively guiding when and when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
optimize_scanA
Dump the memory corpus compactly so you can plan a curation pass.
Step 1 of the "optimize my memories" workflow: every memory's
curation-relevant fields, the relation edges among them, usage counts,
dedup and domain hints, and per-memory anchors (URLs, paths,
identifiers) to check against live facts. Read it, then stage what you
decided with optimize_stage.
Start with what the store already says is suspect: due: true on a
memory means its own writer dated it for a recheck and the date has
passed, and source_ref says what to check it against.
recalls and stats.never_recalled are NOT that. A low count means
unproven, not useless -- a memory about a rare subject looks exactly
like a memory nobody wants, and the rare subject is frequently the
reason the store is there. Use the aggregate to judge the STORE and
never a single row: do not propose archiving something because it is
unread.
The listing is slim so a big store fits one response, and a page ends
early at an internal size budget -- truncated means page onward with
offset + count. since limits the scan to a delta for recurring passes;
full=True keeps whole bodies.
BEFORE PROPOSING ANY CHANGE, CHECK IT AGAINST LIVE FACTS, and record what
you checked in each suggestion's verified. Destructive kinds are
rejected without it. help(command='optimize_scan') has the rest: what
every hint means, how since stays cross-window, and what "live facts"
covers per memory type.
| Name | Required | Description | Default |
|---|---|---|---|
| full | No | ||
| type | No | ||
| limit | No | ||
| since | No | ||
| domain | No | ||
| offset | No | ||
| include_archived | No |
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 heavily: it explains that the listing is slim, that pages can end early at an internal size budget, and that `truncated` signals continued paging. It explains hint semantics like due/source_ref and repeats a critical safety rule about verification before destructive proposals. Missing is the pagination/size mechanics spelled out precisely, but the safety and truncation behaviors are well disclosed.
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?
It is front-loaded with the purpose and step-1 framing, which is good, but the description is long and repetitive across paragraphs, with a mid-text all-caps warning and repeated emphasis. Some sentences earn their place; others (the recalls/stats paragraph) are defensive and 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?
For a 7-parameter read tool with no output schema and no annotations, the description covers purpose, workflow placement, hint semantics, and a critical verification rule. However, because there is no output schema, the definition does not fully specify the returned listing shape or all parameter behaviors, and it explicitly offloads detail to the help tool. That deferral leaves the standalone definition incomplete.
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 only meaningfully explains `since` (delta scans), `full` (whole bodies), and `truncated`/offset/count paging. Parameters `type`, `domain`, `limit`, `offset`, and `include_archived` are barely or not addressed, and the description defers to help(command='optimize_scan') for the rest. This leaves several param semantics implicit.
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: dump the memory corpus compactly for a curation pass. It positions itself as step 1 of a named workflow and names the sibling (optimize_stage) to use next. It is distinguishable from dedup_scan and other read siblings, though the 'dump' framing is slightly informal.
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 gives explicit context: use as step 1 of the optimization workflow, then stage with optimize_stage. It also warns not to treat low recall counts as archiving signals. It lacks explicit when-not-to-use guidance relative to siblings like search or get_memory, but the workflow framing is unusually clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
optimize_stageA
Stage a batch of curation suggestions for human review in the dashboard.
Step 2 of the "optimize my memories" workflow. NOT applied here: the user reviews and applies or rejects each one in the admin dashboard, which backs up before the first apply and can undo any of them.
Each suggestion is {"kind", "target_uid", "payload", "rationale", "verified"}. Kinds: compact/reword {"new_content"}, retag {"tags"}, redomain {"domain"}, crosslist {"also": [...]}, set_confidence {"confidence"}, review {"review_after"} (a date or a span like '180d'; '' clears it), archive {"reason"}, link {"from_uid","to_uid", "relation_type"}, merge {"keep_uid","drop_uid"}, distill {"source_uids","new_type","new_content","title"}. link/merge derive target_uid from the payload and distill creates its target -- omit it for those.
Destructive kinds (archive, set_confidence=contradicted, merge,
distill) require a non-empty verified describing the live-facts
check behind them. Invalid suggestions are skipped and reported in
errors; the rest are staged. Returns {run_id, staged, errors}.
note is one short summary of the pass, at most 250 characters; a
longer one raises and stages nothing. What a single suggestion needs
said belongs in its own rationale and verified, which are not
capped.
help(command='optimize_stage') explains each kind in full.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | ||
| suggestions | Yes |
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: it discloses that nothing is applied, that the dashboard backs up before the first apply and can undo, that destructive kinds require a non-empty `verified`, that invalid suggestions are skipped and reported in `errors`, and that an over-long `note` raises and stages nothing. This is exactly the mutation/safety context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and workflow position, then the suggestion contract, then failure modes. The kind enumeration is long but each entry carries unique information the schema does not, so little is wasted; density is high but 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?
For a mutation tool with no annotations and no output schema, the description still supplies the return shape ({run_id, staged, errors}), the skip-and-report error semantics, the destructive-verification requirement, and a pointer to help(command='optimize_stage') for deeper kind documentation. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and it does: it fully documents the shape of each suggestion (kind, target_uid, payload, rationale, verified), enumerates every kind with its payload fields, explains target_uid derivation for link/merge/distill, and gives `note`'s 250-character cap and raise 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?
States a specific verb and resource — staging curation suggestions for human review — and immediately positions itself as 'Step 2 of the "optimize my memories" workflow', which separates it from the scan/apply siblings. An agent knows this stages rather than applies without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly states the context (step 2 of the optimize workflow) and an explicit when-not: 'NOT applied here: the user reviews and applies or rejects each one in the admin dashboard.' It does not name the specific sibling to run first (e.g. optimize_scan), leaving sequencing to inference, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
optimize_statusA
Inspect one optimization run: every suggestion and its decision.
Read-only. Returns the run header plus each suggestion's kind, target_uid, payload, rationale, verified, status (pending/applied/rejected) and decided_at -- so you can tell which proposals landed, follow up on rejected ones, or build on applied ones in a later pass.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It declares read-only behavior and lists all returned fields (run header, suggestion details including decision status), giving good insight into what the tool provides without side effects.
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 front-loaded with the core purpose in the first sentence. The second sentence is informative but slightly verbose listing fields; could be more concise. No wasted words overall.
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 one parameter and no output schema, the description is adequate. It explains what the tool returns. However, it lacks context on how run_id is obtained, error handling for invalid IDs, and doesn't mention pagination or large runs, leaving some 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?
The only parameter, 'run_id', has no description in the schema (0% coverage). The tool description does not explain what run_id represents or how to obtain it (e.g., from optimize_runs), leaving the agent with minimal guidance beyond the integer type.
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 specific verb 'inspect' and the resource 'optimization run'. It distinguishes itself from siblings like 'optimize_runs' (lists runs) and 'optimize_scan' (scans) by focusing on a single run's details.
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 indicates this tool is for inspecting a single run in detail, providing context on its scope. However, it lacks explicit when-to-use vs alternatives, such as when you would use 'optimize_scan' instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pulseA
Session warm-up: latest checkpoint + open handoffs/anti-patterns + recent notes.
Picks the checkpoint by created_at DESC, never by similarity -- a similarity-ranked top-1 can return a stale checkpoint over a same-day one, which is exactly the failure mode this avoids. latest_checkpoint is returned in full (that's the point of pulse), with its relations attached so linked memories are visible without a separate get_relations call. handoffs and anti_patterns are notes left for whoever resumes; recent_notes are the newest note()'d facts, as recency breadcrumbs -- for relevance-ranked recall use recall()/search(). Those three lists are snippet-truncated -- call get_memory(uid) for one in full.
latest_checkpoint and those three lists carry est_tokens, the
estimated cost of a record's FULL content: on a truncated one that is
what the get_memory(uid) would cost, on latest_checkpoint it is what
this response already spent. diagrams has no bodies to price.
diagrams lists the documented flows by title only, never inlined: a whole graph would swamp a warm-up. Read one with get_diagram(uid) when the work actually touches that routine.
domain warms up a path and everything under it, so pulse('acme/x100')
is the module-wide brief and pulse('acme/x100/p200') the routine's.
A domain that names only the deep end of a path ('p200') is resolved
to the branches it sits in -- scope.paths reports which, and an
ambiguous name resolves to ALL of them.
scope is the rest of the brief: what the scope HOLDS, next to what
came back. This is a warm-up, so each list stops at a handful and the
newest few of a busy child can fill it on their own -- scope.not_shown
counts what that left behind, per type, and scope.subdomains says
which level it is sitting in (own = filed there, subtree = with its
descendants). Read them as the drill-down plan: search(query,
domain=...) or list_by_domain(domain, type=..., limit=...) on the child
that holds what this pass only counted. A pulse is the state of a
scope, never its contents.
scope.stale is the one thing here about DECAY rather than contents:
how many memories in the scope carry a review_after date that has
passed. Present only when non-zero. It means somebody who knew the
subject said when to look again and nobody has -- optimize_scan lists
which ones, with their source_ref.
A scope holds what is CROSS-LISTED into it as well as what is filed
there, so warming up an end-to-end flow brings back the routines that
are steps of it wherever they live. scope.also counts how much of the
brief arrived that way, and a subdomain carries its own also --
present only when non-zero, so a store that never cross-lists never
sees the field.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No |
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 unusually well: it discloses that the checkpoint is selected by created_at DESC rather than similarity (and why), that latest_checkpoint is returned in full with relations attached, how est_tokens is priced differently for truncated vs full records, and that the three lists are snippet-truncated requiring get_memory(uid).
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?
It is long (several hundred words) for a one-optional-param tool, but it is front-loaded with the payload summary and virtually every paragraph introduces distinct, non-derivable behavior (est_tokens pricing, scope.stale, scope.also). Prose density is the only weakness; no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema and no annotations, so the description must define the response shape, which it does field-by-field — latest_checkpoint, handoffs, anti_patterns, recent_notes, diagrams, and the full scope sub-structure (paths, not_shown, subdomains, stale, also). An agent can interpret the result without guessing.
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% for the single `domain` param, so the description must compensate, and it does in depth: pulse('acme/x100') vs pulse('acme/x100/p200'), resolution of a deep-end-only name to all branches, scope.paths reporting the resolution, ambiguity resolving to ALL matches.
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 names a specific verb-resource and scope: 'Session warm-up: latest checkpoint + open handoffs/anti-patterns + recent notes,' then enumerates every component of the payload (checkpoint, three lists, diagrams, scope). It explicitly distinguishes itself from siblings recall()/search() as the recency-based alternative.
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 routes the agent elsewhere in several places ('for relevance-ranked recall use recall()/search()', 'Read one with get_diagram(uid)', 'optimize_scan lists which ones', 'search(query, domain=...) or list_by_domain(...)'). It lacks an explicit forward statement of when to call pulse itself, but the surrounding guidance is rich and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
purge_memoryA
PERMANENTLY delete a memory + its edit history + relations. Irreversible.
Use forget() instead unless the user explicitly asked to permanently remove data -- forget() is reversible (archived, content kept), this is not. Guardrail: confirm_phrase must exactly equal "DELETE ", typed by the user in their own message. Do not construct this string yourself from an inferred "yes"/"confirm" -- it must come from the user actually stating the uid back.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| confirm_phrase | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses the destructive irreversible nature, the exact deletion scope, and the confirm_phrase requirement. However, it does not mention authorization needs or response format.
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 few sentences long, each adding value. It is well-structured with a warning and guidelines, though slightly verbose. Every sentence earns its place.
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 no output schema, no annotations, and only 2 parameters, the description is fairly complete. It covers purpose, usage, and parameter semantics. Missing information about return values or permissions, but still adequate for a simple 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%, but the description adds critical meaning: it explains that confirm_phrase must exactly equal 'DELETE <uid>' and must come from the user's own message, and that uid identifies the memory. This partially compensates for the lack of 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?
The description clearly states the tool permanently deletes a memory along with its edit history and relations, using specific verbs and resources. It distinguishes itself from the sibling 'forget' tool by highlighting irreversibility.
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 advises using 'forget' instead unless permanent removal is requested, and gives a strict guardrail for the confirm_phrase parameter, preventing the agent from constructing the confirmation string itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reasoningA
Record an analysis worth keeping: what was thought, and what it settled.
For the PROCESS, not the fact it produced -- note() takes the fact. Stored as type='reasoning'; filter search/list_* with type='reasoning' to get these back. ONE analysis per memory: a second hypothesis tested in the same session is its own reasoning(). See note() on what a body holds and when it is two memories.
title: one line naming what this memory is about, in the words someone would look for it by. It is what a list shows instead of the opening of the body, and it outweighs every other field in search, so a title that repeats the type ("note about the parser") names nothing. At most 120 characters, and a name that needs more than that is summarizing the body instead of naming it.
hypothesis: what you believed going in, as a claim that could be wrong. reasoning: how you tested it -- what you read, ran or compared. result: what came back. The measurement, not the interpretation. revised_belief: what you believe now, and where it differs from the hypothesis. Say plainly when the hypothesis survived unchanged. next_time: what someone hitting this again should do differently.
also, review_after and source_ref behave as in note().
tags carries the synonyms the body never uses: retrieval is BM25 over
content and tags, so a memory with none is reachable only by quoting
itself. See note() for what belongs there.
| Name | Required | Description | Default |
|---|---|---|---|
| also | No | ||
| tags | No | ||
| title | Yes | ||
| domain | No | ||
| result | Yes | ||
| session | No | ||
| next_time | Yes | ||
| reasoning | Yes | ||
| hypothesis | Yes | ||
| source_ref | No | ||
| review_after | No | ||
| revised_belief | Yes |
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 much of it: it discloses the storage type ('type=reasoning'), the retrieval mechanism ('BM25 over content and tags'), and search-ranking behavior ('a title ... outweighs every other field in search'). It omits auth/permission needs, error behavior, and any body-size limits, so it falls short of full behavioral disclosure.
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 purpose and the note() routing are front-loaded, and the required-field explanations are laid out in sequence. It is on the long side — the title paragraph in particular runs several sentences — but nearly every sentence carries field-level or retrieval information rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter, 6-required mutation tool with no annotations and no output schema, the description supplies purpose, storage semantics, retrieval behavior, and field meanings. The gaps are domain and session semantics, and nothing about failure or permission behavior, but the core calling information an agent needs is present.
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 compensate and largely does: it gives explicit semantics for all six required fields (title, hypothesis, reasoning, result, revised_belief, next_time) plus tags, and delegates also/review_after/source_ref to note(). domain and session, however, are never explained anywhere, leaving two of twelve parameters undocumented.
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 ('Record an analysis worth keeping: what was thought, and what it settled') and immediately distinguishes itself from the closest sibling: 'For the PROCESS, not the fact it produced -- note() takes the fact.' An agent can route between reasoning() and note() without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternative (note()) and the condition that selects it, plus the cardinality rule ('ONE analysis per memory: a second hypothesis tested in the same session is its own reasoning()'). It also tells the agent how to retrieve these later (filter search/list_* with type='reasoning'), which is explicit when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallA
Recall long-term knowledge saved with note() (type='note').
The dedicated verb for "bring back what I noted": a BM25 search scoped to type='note', ranked by relevance -- which is what you want for timeless facts/rules/decisions. note() has no recency warm-up hook the way checkpoints have pulse(); this (or search(type='note')) is how notes come back.
Returns {"results": [...], "est_tokens": N}. Content is
snippet-truncated -- call get_memory(uid) for the full record; a
result's est_tokens estimates what that full record costs, and the
top-level est_tokens is the sum over the results.
domain scopes to a path and everything nested under it, and resolves a
bare deep segment the same way search() does. Results carry the same
succeeded_by / collapsed annotations search() explains.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| domain | No |
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 well: it discloses snippet truncation, the est_tokens cost semantics (per-result and top-level sum), domain scoping/resolution behavior, and the succeeded_by/collapsed annotations carried by results. It stops short of stating permission/auth requirements, but for a read tool this is a strong disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core verb and scope, then layered detail. Multi-sentence and somewhat dense, but each sentence (alternatives, return shape, truncation, domain) earns its place 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?
No output schema exists, and the description fills that gap by describing the return shape and token-cost fields; it also covers truncation and the domain parameter. The undocumented limit parameter is the main remaining gap, keeping it from a 5.
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 compensate. It gives useful semantics for domain (path scoping, bare-segment resolution) but says nothing about limit (default 10) or query beyond the implied search. Partial compensation for a 0%-coverage 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?
States a specific verb ('recall') plus resource and scope ('long-term knowledge saved with note()', 'BM25 search scoped to type='note''), and cleanly distinguishes itself from siblings search() and get_memory(). An agent can tell exactly what this does 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 names when to use it ('timeless facts/rules/decisions'), names the alternative ('search(type='note')') that also works, and names the follow-up tool ('call get_memory(uid) for the full record'). 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.
searchA
Keyword search over memory content+tags+domain: FTS5 BM25.
Each result is annotated with match_source ("fts", or "uid" for the row a pasted identifier names) and fts_rank (bm25, lower = better). The search only widens the candidate set -- judge the returned candidates yourself.
SPEND TERMS FREELY. Every space-separated term is asked for separately and a row matching more of them ranks higher, so piling on synonyms, the identifier, the routine name and the plain-language phrasing into one query costs one call and finds strictly more. Twenty terms beat ten. Write a sentence if that is what you have -- common words score near zero and cost nothing, so there is nothing to strip.
Only active memories by default.
Returns {"results": [...], "est_tokens": N}. Content is
snippet-truncated per result -- call get_memory(uid) for the full
record; a result's est_tokens estimates what that full record costs,
and the top-level est_tokens is the sum over the results.
Two annotations worth acting on. succeeded_by means something in the
store supersedes this memory: read that one instead. collapsed lists
near-identical results folded into this one, so a fact written five
times spends one slot -- raise limit if you want the copies.
A memory marked confidence='contradicted' sorts behind everything that still holds, but it does come back: knowing a claim was ruled out is worth a slot, and it is what stops it being written again.
A diagram ranks like any other memory: it comes back when it matches the query, in the position its score earns. Nothing lifts a type to the top, so a flow in the results is a flow this query actually hit -- and when one does show up it is worth opening first, because it states a whole routine the surrounding notes only annotate.
type filters (one writer each): 'note', 'reasoning', 'checkpoint', 'anti_pattern', 'handoff', 'diagram'. Ask for type='diagram' to sweep the documented flows on purpose. To recall note()'d knowledge specifically, recall() is the sugar for search(type='note') -- which also means recall() never surfaces a diagram; use search() for that.
domain scopes to a path AND everything under it: domain='acme/x100'
searches the module and each of its routines. Give more of the path to
narrow it. A domain naming only the deep end of a path ('p200') is
resolved to the branches it sits in -- every result carries its real
domain, which is where to read what the filter actually covered.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | ||
| limit | No | ||
| query | Yes | ||
| domain | No |
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: BM25 ranking with 'lower = better', candidate-set-only semantics ('judge the returned candidates yourself'), active-memories-only default, succeeded_by/collapsed/confidence='contradicted' handling, snippet truncation, and est_tokens accounting. Almost every behavioral trait an agent needs is disclosed.
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?
Strongly front-loaded with purpose and scoring semantics first, then behavioral notes, then filters. Each paragraph earns its place, though the 'SPEND TERMS FREELY' block is somewhat long and occasionally repetitive for a 4-parameter search tool.
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?
No output schema exists, yet the description documents the return shape ({"results": [...], "est_tokens": N}), per-result est_tokens, match_source/fts_rank fields, and the two annotations. Nothing an agent needs to interpret results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate and does: it enumerates the type values ('note','reasoning','checkpoint','anti_pattern','handoff','diagram'), explains domain path-scoping with inheritance ('the module and each of its routines'), describes multi-term query semantics, and explains limit via the collapsed mechanism. This exceeds what the bare schema provides.
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 ('Keyword search over memory content+tags+domain: FTS5 BM25') and explicitly distinguishes itself from the recall sibling ('recall() is the sugar for search(type='note')... which also means recall() never surfaces a diagram; use search() for that'). An agent can pick this over near neighbours 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?
Gives explicit when-to-use and alternative routing: use recall() for note()'d knowledge, use search() when you want diagrams, ask type='diagram' to sweep flows deliberately, and call get_memory(uid) for full records. It also prescribes query construction ('SPEND TERMS FREELY', pile on synonyms) as concrete guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_confidenceB
Set a memory's confidence: unverified | confirmed | contradicted.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| confidence | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description does not disclose behavioral traits such as whether the mutation is destructive, permissions required, or error handling. The tool modifies a memory, but side effects are not mentioned.
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?
Single sentence, direct and to the point, no redundant information. Efficiently conveys the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple mutation tool with no output schema or annotations, the description covers the basic purpose and allowed values. However, it lacks details on return value, error conditions, and behavioral context, leaving 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%, so description must compensate. Description lists the three confidence values, aiding understanding of the 'confidence' parameter, but does not explain the 'uid' parameter (e.g., it identifies a memory). Provides partial semantic value.
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?
Description clearly states the tool 'Set a memory's confidence' and lists the three allowed values (unverified, confirmed, contradicted). This distinguishes it from sibling tools like edit_memory or forget.
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?
No guidance on when to use this tool versus alternatives. Does not mention prerequisites (e.g., memory must exist) or scenarios where it is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_domain_caseA
Set the store's domain-casing policy. mode: 'preserve' | 'lower' | 'upper'.
'preserve' keeps free-text casing; 'lower'/'upper' coerce every domain written from now on to that case. This only governs new writes -- to bring already-stored domains into line, run the "Normalize domains" action in the admin dashboard (it previews collisions before merging variant spellings). Returns the stored {"mode": ...}.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden and does so: it discloses the forward-only scope ('only governs new writes'), the separate remediation path, the collision-preview behavior of that path, and the return value. This is rich behavioral context rarely seen.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb, then modes, then the critical caveat. Slightly longer than minimal but every clause carries new information about scope or remediation.
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 one-parameter mutation tool with no annotations and no output schema, the description supplies everything an agent needs: valid values, effect semantics, scope limitation, and return shape.
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 no enum is defined in the schema, so the description must define the parameter. It does precisely: lists all three legal values and explains the effect of each, compensating fully for the schema gap.
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 ('Set the store's domain-casing policy') and enumerates the exact policy values. Clearly distinguishable from siblings like get_domain_case or list_domains.
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?
Explains what each mode does and, critically, the boundary condition: this only governs new writes, and existing domains require a separate admin action. It does not explicitly name a sibling alternative, but the constraint is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
timelineA
What else was being written around one memory, in creation order.
For the question search cannot ask: not what mentions this record, but what was being written when it was. Neighbours are picked by time alone, so they come back whether or not they share a word with the anchor -- around a checkpoint, that is the notes and pitfalls of the same stretch of work.
One of uid or query is required. uid names the anchor outright; query
searches for it and takes the top hit (the same search search() runs,
scoped by domain/type). Give both and uid wins. The response
reports anchored_by ('uid' or 'query') and the whole anchor record,
so which record the timeline is built around is never a guess.
Returns {"anchored_by": ..., "anchor": {...}, "before": [...],
"after": [...]}: before is the before records created immediately
before the anchor and after the after records created immediately
after it, both oldest first, so before + [anchor] + after reads
straight down the clock. Neither list contains the anchor.
domain and type narrow the NEIGHBOURHOOD, not the anchor: a memory named by uid comes back as named, and the records around it are the ones matching the filters. domain covers a path and everything under it, plus what is cross-listed into it, and resolves a bare deep segment the way the other scoped reads do. Archived records are left out of the neighbourhood, as everywhere else by default.
Each record is snippet-truncated with est_tokens for its full content
-- call get_memory(uid) to open one.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | No | ||
| type | No | ||
| after | No | ||
| query | No | ||
| before | No | ||
| domain | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and mostly succeeds: neighbour selection is by time only, archived records are excluded from the neighbourhood, output is snippet-truncated with est_tokens, and lists are ordered oldest-first with the anchor excluded. It does not mention permissions, error behaviour when query matches nothing, or limits, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded and the returns block earns its place given no output schema, but the prose is leisurely and repeats the anchor/neighbour distinction in several forms ("Neighbours are picked by time alone," then "domain and type narrow the NEIGHBOURHOOD, not the anchor"). Reduce without losing 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 6-parameter tool with no annotations and no output schema, the description covers the return shape (anchored_by, anchor, before, after), ordering, anchor inclusion/exclusion, filtering scope, archiving defaults, and truncation. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and largely does: it defines before/after counts and ordering, the uid/query precedence, and clarifies that domain/type filter the neighbourhood rather than the anchor (including path-prefix, cross-listing, and bare-segment resolution). The `type` parameter's accepted values are never enumerated, leaving a gap.
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 resource (the records created immediately around one anchor memory, in creation order) and explicitly separates itself from search: "not what mentions this record, but what was being written when it was." An agent can distinguish this from search/recall/list_recent without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the condition that selects this tool versus search (semantic neighbours vs temporal neighbours), specifies the uid-vs-query requirement and precedence ("Give both and uid wins"), and routes to get_memory for full content. Alternatives and exclusions are explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unfile_domainA
Drop one of a memory's cross-listings. Does not touch where it is filed.
Matched on the exact path: dropping 'acme' leaves a separate membership in 'acme/x100' alone, because that is a different scope. Returns {"uid": ..., "also": [...]} with what remains.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | ||
| domain | 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. It discloses the exact-path matching semantics ('acme' vs 'acme/x100' are separate scopes) and the return shape, which is meaningful behavioral context. It doesn't state reversibility or permission requirements, keeping it just short of 5.
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 short sentences, front-loaded with the action, then the scoping caveat, then the return shape. 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 2-param mutation with no annotations and no output schema, the description covers effect, matching semantics, scope examples, and return shape. Missing only permission/reversibility notes, which is a minor gap.
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 clarifies that 'domain' is matched on exact path and gives a concrete example distinguishing scopes, which adds real meaning beyond the bare 'uid'/'domain' schema titles.
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 ('Drop') and resource ('cross-listings' / membership), and explicitly distinguishes from its inverse concept by saying it 'Does not touch where it is filed.' This separates it from move_to_project and link_memories.
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?
Clear context: removes a cross-listing without affecting primary filing. The 'Does not touch where it is filed' clause implicitly signals when-not-to-use (for moving, use move_to_project), but no sibling tool is named explicitly.
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.
24 tool updates
v0.1.1- Added
also_domain - Changed
anti_pattern6 fields changed- added
Input schema / properties / alsoAdded value: +{ + "default": "", + "title": "Also", + "type": "string" +} - added
Input schema / properties / review_afterAdded value: +{ + "default": "", + "title": "Review After", + "type": "string" +} - added
Input schema / properties / source_refAdded value: +{ + "default": "", + "title": "Source Ref", + "type": "string" +} - added
Input schema / properties / tagsAdded value: +{ + "default": "", + "title": "Tags", + "type": "string" +} - added
Input schema / properties / titleAdded value: +{ + "title": "Title", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "pattern", - "why_wrong", - "instead" -]New value: +[ + "title", + "pattern", + "why_wrong", + "instead" +]
- Changed
checkpoint4 fields changed- added
Input schema / properties / alsoAdded value: +{ + "default": "", + "title": "Also", + "type": "string" +} - added
Input schema / properties / tagsAdded value: +{ + "default": "", + "title": "Tags", + "type": "string" +} - added
Input schema / properties / titleAdded value: +{ + "title": "Title", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "intent", - "established", - "pursuing", - "open_questions" -]New value: +[ + "title", + "intent", + "established", + "pursuing", + "open_questions" +]
- Added
diagram - Added
diagram_edge - Added
diagram_jump - Added
diagram_link - Added
diagram_node - Added
diagram_relayout - Changed
edit_memory6 fields changed- added
Input schema / properties / modeAdded value: +{ + "default": "replace", + "title": "Mode", + "type": "string" +} - added
Input schema / properties / new_content / defaultAdded value: +"" - added
Input schema / properties / source_refAdded value: +{ + "default": "", + "title": "Source Ref", + "type": "string" +} - added
Input schema / properties / tagsAdded value: +{ + "default": "", + "title": "Tags", + "type": "string" +} - added
Input schema / properties / titleAdded value: +{ + "default": "", + "title": "Title", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "uid", - "new_content" -]New value: +[ + "uid" +]
- Added
get_diagram - Added
get_domain_case - Changed
handoff4 fields changed- added
Input schema / properties / alsoAdded value: +{ + "default": "", + "title": "Also", + "type": "string" +} - added
Input schema / properties / tagsAdded value: +{ + "default": "", + "title": "Tags", + "type": "string" +} - added
Input schema / properties / titleAdded value: +{ + "title": "Title", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "content" -]New value: +[ + "title", + "content" +]
- Changed
list_by_domain2 fields changed- added
Input schema / properties / subtreeAdded value: +{ + "default": true, + "title": "Subtree", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "items": { - "additionalProperties": true, - "type": "object" - }, - "title": "Result", - "type": "array" - } - }, - "required": [ - "result" - ], - "title": "list_by_domainOutput", - "type": "object" -}New value: +null
- Added
list_projects - Changed
list_recent2 fields changed- added
Input schema / properties / subtreeAdded value: +{ + "default": true, + "title": "Subtree", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "items": { - "additionalProperties": true, - "type": "object" - }, - "title": "Result", - "type": "array" - } - }, - "required": [ - "result" - ], - "title": "list_recentOutput", - "type": "object" -}New value: +null
- Added
move_to_project - Changed
note5 fields changed- added
Input schema / properties / alsoAdded value: +{ + "default": "", + "title": "Also", + "type": "string" +} - added
Input schema / properties / review_afterAdded value: +{ + "default": "", + "title": "Review After", + "type": "string" +} - added
Input schema / properties / source_refAdded value: +{ + "default": "", + "title": "Source Ref", + "type": "string" +} - added
Input schema / properties / titleAdded value: +{ + "title": "Title", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "content" -]New value: +[ + "title", + "content" +]
- Changed
reasoning12 fields changed- added
Input schema / properties / alsoAdded value: +{ + "default": "", + "title": "Also", + "type": "string" +} - removed
Input schema / properties / contentRemoved value: -{ - "title": "Content", - "type": "string" -} - added
Input schema / properties / hypothesisAdded value: +{ + "title": "Hypothesis", + "type": "string" +} - added
Input schema / properties / next_timeAdded value: +{ + "title": "Next Time", + "type": "string" +} - added
Input schema / properties / reasoningAdded value: +{ + "title": "Reasoning", + "type": "string" +} - added
Input schema / properties / resultAdded value: +{ + "title": "Result", + "type": "string" +} - added
Input schema / properties / review_afterAdded value: +{ + "default": "", + "title": "Review After", + "type": "string" +} - added
Input schema / properties / revised_beliefAdded value: +{ + "title": "Revised Belief", + "type": "string" +} - added
Input schema / properties / source_refAdded value: +{ + "default": "", + "title": "Source Ref", + "type": "string" +} - added
Input schema / properties / tagsAdded value: +{ + "default": "", + "title": "Tags", + "type": "string" +} - added
Input schema / properties / titleAdded value: +{ + "title": "Title", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "content" -]New value: +[ + "title", + "hypothesis", + "reasoning", + "result", + "revised_belief", + "next_time" +]
- Changed
recall2 fields changed- changed
Input schema / properties / limit / defaultPrevious value: -20New value: +10 - changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "items": { - "additionalProperties": true, - "type": "object" - }, - "title": "Result", - "type": "array" - } - }, - "required": [ - "result" - ], - "title": "recallOutput", - "type": "object" -}New value: +null
- Changed
search2 fields changed- changed
Input schema / properties / limit / defaultPrevious value: -30New value: +10 - changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "items": { - "additionalProperties": true, - "type": "object" - }, - "title": "Result", - "type": "array" - } - }, - "required": [ - "result" - ], - "title": "searchOutput", - "type": "object" -}New value: +null
- Added
set_domain_case - Added
timeline - Added
unfile_domain
24 tool updates
v0.1.0- First observed
anti_pattern - First observed
checkpoint - First observed
dedup_scan - First observed
edit_memory - First observed
forget - First observed
get_memory - First observed
get_relations - First observed
handoff - First observed
help - First observed
link_memories - First observed
list_by_domain - First observed
list_domains - First observed
list_recent - First observed
note - First observed
optimize_runs - First observed
optimize_scan - First observed
optimize_stage - First observed
optimize_status - First observed
pulse - First observed
purge_memory - First observed
reasoning - First observed
recall - First observed
search - First observed
set_confidence
TDQS
Scored across 38 tools
Tools are largely distinct in purpose, helped by detailed descriptions that clarify overlapping retrieval paths (search vs recall vs list_recent/timeline) and diagram operations (diagram_link vs link_memories, diagram_jump vs diagram_link). A few boundaries remain subtle—e.g., search/recall/list_by_domain/list_recent all retrieve memories with different filters—so an agent may need to reason about scope before selecting.
All tool names use snake_case, giving a consistent surface; prefixes like get_/list_/set_/optimize_/diagram_ group related operations. Some tools are named as memory-type nouns (note, checkpoint, anti_pattern, reasoning, handoff, diagram) rather than verb_noun, but that reflects the domain's entities and remains readable.
38 tools is a lot for an MCP server; while most tools have a distinct role, the count places a heavy context/schema burden on the agent and exceeds the 25+ threshold for 'too many' in this rubric. The scope of the server may justify some breadth, but the set is over-large rather than tightly scoped.
Coverage is very strong: memory CRUD/lifecycle (note, get, edit, forget, purge), multiple memory types, relationships, domains/cross-listing, diagrams, projects, and curation workflows (dedup/optimize) are all represented. No obvious major gaps for the stated memory-management purpose; only niche admin actions (e.g., project switching/creation) are delegated to the dashboard.
Maintenance
Related MCP Connectors
An MCP memory server. One memory your agents share — across models, devices and apps.
Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Persistent memory for AI agents — log and recall conversation context over MCP.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAn MCP server that provides persistent long-term memory for AI agents via local SQLite storage with low token overhead, enabling memory storage, retrieval, and management across sessions.1MIT
- AlicenseNot gradedqualityAmaintenanceA local memory server for AI agents that stores and retrieves information via MCP, keeping all data in SQLite on your machine.225 PyPI1Apache 2.0
- AlicenseAqualityCmaintenancePersistent memory MCP server for AI agents, using SQLite with hybrid keyword and semantic search for long-term memory storage.5Do What The F*ck You Want To Public
- AlicenseAqualityBmaintenanceMCP server for persistent, cross-session, local-first memory for AI agents, storing memories as Markdown files with SQLite indexing for hybrid search.24Apache 2.0