Skip to main content
Glama

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/billing still answers a read of acme, and also cross-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 pytest

Register 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 date

See Hooks and the warden for what each event emits and how to turn the warden off.

NOTE

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.json, top-level mcpServers

claude mcp add --scope user memai <command>

Claude Desktop — the chat app

Windows: %APPDATA%\Claude\claude_desktop_config.jsonmacOS: ~/Library/Application Support/Claude/claude_desktop_config.json

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.

IMPORTANT

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

memai.db

the General project, the one every install starts with

projects/<name>.db

every other project, one file each, named as you named it

active

one line naming the project in use; absent means General

backups/

VACUUM INTO copies of General, named General-<stamp>.db; any other project's go in backups/<name>/

renders/, warden/

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

Storage

the tables, and what each one is the record of

Retrieval

BM25 keyword search, and what a result carries

Domains

paths, subtree reads, and belonging to more than one

Diagrams

documenting a routine as a graph, and reading it back

Curation

confidence, decay, staged suggestions, dedup

Tools

every MCP tool, and the sets that trim the schema cost

Hooks and the warden

the four hook events, the skills, and the subagent that consults the store on a session's behalf

Dashboard

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 tools
also_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes
domainYes

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
alsoNo
tagsNo
titleYes
domainNo
insteadYes
patternYes
sessionNo
why_wrongYes
source_refNo
review_afterNo

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness3/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
alsoNo
tagsNo
titleYes
domainNo
intentYes
sessionNo
pursuingYes
establishedYes
open_questionsYes

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNo
limitNo
domainNo
thresholdNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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().

ParametersJSON Schema
NameRequiredDescriptionDefault
alsoNo
kindNoflowchart
tagsNo
edgesYes
nodesYes
titleYes
domainNo
sessionNo
summaryNo
source_refNo
review_afterNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes
labelNo
deleteNo
to_keyYes
from_keyYes

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes
labelNo
deleteNo
node_keyYes
peer_uidYes
peer_nodeNo

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyYes
uidYes
noteNo
labelNo
shapeNo
deleteNo

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes
modeNoreplace
noteNo
tagsNo
titleNo
source_refNo
new_contentNo

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes
reasonNo
superseded_byNo

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes
formatNomermaid

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
alsoNo
tagsNo
titleYes
domainNo
contentYes
sessionNo

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
commandNo

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNo
limitNo
domainYes
subtreeNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNo
limitNo
domainNo
subtreeNo

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidsNo
createNo
domainNo
targetYes
dry_runNo

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
alsoNo
tagsNo
titleYes
domainNo
contentYes
sessionNo
source_refNo
review_afterNo

TDQS

A4.2/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
fullNo
typeNo
limitNo
sinceNo
domainNo
offsetNo
include_archivedNo

TDQS

A3.5/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
noteNo
suggestionsYes

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
run_idYes

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes
confirm_phraseYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
alsoNo
tagsNo
titleYes
domainNo
resultYes
sessionNo
next_timeYes
reasoningYes
hypothesisYes
source_refNo
review_afterNo
revised_beliefYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
domainNo

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

set_confidenceB

Set a memory's confidence: unverified | confirmed | contradicted.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes
confidenceYes

TDQS

B3.3/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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": ...}.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeYes

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidNo
typeNo
afterNo
queryNo
beforeNo
domainNo

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYes
domainYes

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 24 tool updatesv0.1.1
    • Addedalso_domain
    • Changedanti_pattern6 fields changed
      • addedInput schema / properties / also
        Added value: +{
        +  "default": "",
        +  "title": "Also",
        +  "type": "string"
        +}
      • addedInput schema / properties / review_after
        Added value: +{
        +  "default": "",
        +  "title": "Review After",
        +  "type": "string"
        +}
      • addedInput schema / properties / source_ref
        Added value: +{
        +  "default": "",
        +  "title": "Source Ref",
        +  "type": "string"
        +}
      • addedInput schema / properties / tags
        Added value: +{
        +  "default": "",
        +  "title": "Tags",
        +  "type": "string"
        +}
      • addedInput schema / properties / title
        Added value: +{
        +  "title": "Title",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "pattern",
        -  "why_wrong",
        -  "instead"
        -]New value: +[
        +  "title",
        +  "pattern",
        +  "why_wrong",
        +  "instead"
        +]
    • Changedcheckpoint4 fields changed
      • addedInput schema / properties / also
        Added value: +{
        +  "default": "",
        +  "title": "Also",
        +  "type": "string"
        +}
      • addedInput schema / properties / tags
        Added value: +{
        +  "default": "",
        +  "title": "Tags",
        +  "type": "string"
        +}
      • addedInput schema / properties / title
        Added value: +{
        +  "title": "Title",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "intent",
        -  "established",
        -  "pursuing",
        -  "open_questions"
        -]New value: +[
        +  "title",
        +  "intent",
        +  "established",
        +  "pursuing",
        +  "open_questions"
        +]
    • Addeddiagram
    • Addeddiagram_edge
    • Addeddiagram_jump
    • Addeddiagram_link
    • Addeddiagram_node
    • Addeddiagram_relayout
    • Changededit_memory6 fields changed
      • addedInput schema / properties / mode
        Added value: +{
        +  "default": "replace",
        +  "title": "Mode",
        +  "type": "string"
        +}
      • addedInput schema / properties / new_content / default
        Added value: +""
      • addedInput schema / properties / source_ref
        Added value: +{
        +  "default": "",
        +  "title": "Source Ref",
        +  "type": "string"
        +}
      • addedInput schema / properties / tags
        Added value: +{
        +  "default": "",
        +  "title": "Tags",
        +  "type": "string"
        +}
      • addedInput schema / properties / title
        Added value: +{
        +  "default": "",
        +  "title": "Title",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "uid",
        -  "new_content"
        -]New value: +[
        +  "uid"
        +]
    • Addedget_diagram
    • Addedget_domain_case
    • Changedhandoff4 fields changed
      • addedInput schema / properties / also
        Added value: +{
        +  "default": "",
        +  "title": "Also",
        +  "type": "string"
        +}
      • addedInput schema / properties / tags
        Added value: +{
        +  "default": "",
        +  "title": "Tags",
        +  "type": "string"
        +}
      • addedInput schema / properties / title
        Added value: +{
        +  "title": "Title",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "content"
        -]New value: +[
        +  "title",
        +  "content"
        +]
    • Changedlist_by_domain2 fields changed
      • addedInput schema / properties / subtree
        Added value: +{
        +  "default": true,
        +  "title": "Subtree",
        +  "type": "boolean"
        +}
      • changedOutput 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
    • Addedlist_projects
    • Changedlist_recent2 fields changed
      • addedInput schema / properties / subtree
        Added value: +{
        +  "default": true,
        +  "title": "Subtree",
        +  "type": "boolean"
        +}
      • changedOutput 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
    • Addedmove_to_project
    • Changednote5 fields changed
      • addedInput schema / properties / also
        Added value: +{
        +  "default": "",
        +  "title": "Also",
        +  "type": "string"
        +}
      • addedInput schema / properties / review_after
        Added value: +{
        +  "default": "",
        +  "title": "Review After",
        +  "type": "string"
        +}
      • addedInput schema / properties / source_ref
        Added value: +{
        +  "default": "",
        +  "title": "Source Ref",
        +  "type": "string"
        +}
      • addedInput schema / properties / title
        Added value: +{
        +  "title": "Title",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "content"
        -]New value: +[
        +  "title",
        +  "content"
        +]
    • Changedreasoning12 fields changed
      • addedInput schema / properties / also
        Added value: +{
        +  "default": "",
        +  "title": "Also",
        +  "type": "string"
        +}
      • removedInput schema / properties / content
        Removed value: -{
        -  "title": "Content",
        -  "type": "string"
        -}
      • addedInput schema / properties / hypothesis
        Added value: +{
        +  "title": "Hypothesis",
        +  "type": "string"
        +}
      • addedInput schema / properties / next_time
        Added value: +{
        +  "title": "Next Time",
        +  "type": "string"
        +}
      • addedInput schema / properties / reasoning
        Added value: +{
        +  "title": "Reasoning",
        +  "type": "string"
        +}
      • addedInput schema / properties / result
        Added value: +{
        +  "title": "Result",
        +  "type": "string"
        +}
      • addedInput schema / properties / review_after
        Added value: +{
        +  "default": "",
        +  "title": "Review After",
        +  "type": "string"
        +}
      • addedInput schema / properties / revised_belief
        Added value: +{
        +  "title": "Revised Belief",
        +  "type": "string"
        +}
      • addedInput schema / properties / source_ref
        Added value: +{
        +  "default": "",
        +  "title": "Source Ref",
        +  "type": "string"
        +}
      • addedInput schema / properties / tags
        Added value: +{
        +  "default": "",
        +  "title": "Tags",
        +  "type": "string"
        +}
      • addedInput schema / properties / title
        Added value: +{
        +  "title": "Title",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "content"
        -]New value: +[
        +  "title",
        +  "hypothesis",
        +  "reasoning",
        +  "result",
        +  "revised_belief",
        +  "next_time"
        +]
    • Changedrecall2 fields changed
      • changedInput schema / properties / limit / default
        Previous value: -20New value: +10
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "items": {
        -        "additionalProperties": true,
        -        "type": "object"
        -      },
        -      "title": "Result",
        -      "type": "array"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "recallOutput",
        -  "type": "object"
        -}New value: +null
    • Changedsearch2 fields changed
      • changedInput schema / properties / limit / default
        Previous value: -30New value: +10
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "items": {
        -        "additionalProperties": true,
        -        "type": "object"
        -      },
        -      "title": "Result",
        -      "type": "array"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "searchOutput",
        -  "type": "object"
        -}New value: +null
    • Addedset_domain_case
    • Addedtimeline
    • Addedunfile_domain
  2. 24 tool updatesv0.1.0
    • First observedanti_pattern
    • First observedcheckpoint
    • First observeddedup_scan
    • First observededit_memory
    • First observedforget
    • First observedget_memory
    • First observedget_relations
    • First observedhandoff
    • First observedhelp
    • First observedlink_memories
    • First observedlist_by_domain
    • First observedlist_domains
    • First observedlist_recent
    • First observednote
    • First observedoptimize_runs
    • First observedoptimize_scan
    • First observedoptimize_stage
    • First observedoptimize_status
    • First observedpulse
    • First observedpurge_memory
    • First observedreasoning
    • First observedrecall
    • First observedsearch
    • First observedset_confidence

TDQS

A3.8/5.0

Scored across 38 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count2/5

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.

Completeness5/5

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

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    An 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.
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    A local memory server for AI agents that stores and retrieves information via MCP, keeping all data in SQLite on your machine.
    225 PyPI
    1
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    MCP server for persistent, cross-session, local-first memory for AI agents, storing memories as Markdown files with SQLite indexing for hybrid search.
    24
    Apache 2.0