Leteo
Leteo is a persistent, local memory server for AI coding agents. It uses SQLite to store, search, recall, and manage observations (memories) across projects, sessions, and prompts. You can save memories (mem_save) with titles, content, types (e.g., bugfix, decision, architecture), scopes (project, personal, global), and session links; retrieve them by ID (mem_get_observation) or full-text search (mem_search) with filters; update (mem_update) or delete (soft/hard via mem_delete). The server provides contextual initialization blocks (mem_context) with pinned and recent memories, sessions, and prompts. Sessions are managed with start (mem_session_start), end (mem_session_end), summaries (mem_session_summary), and prompt recording (mem_save_prompt). Passive capture (mem_capture_passive) automatically extracts key learnings from subagent output. Conflict handling includes comparing memories (mem_compare), judging conflicts (mem_judge), and reviewing due items (mem_review). Organization tools allow pinning/unpinning (mem_pin/mem_unpin), merging project variants (mem_merge_projects), and suggesting stable topic keys (mem_suggest_topic_key) for evolving observations. Diagnostics are available via mem_doctor, stats via mem_stats, and timeline via mem_timeline. You can detect the current project (mem_current_project), and export/import data (JSON, Markdown, from Engram). Optional cloud replication sends selected project memories to a self-hosted server using client-only connections. Configuration allows setting agent voice, memory languages, and context depth.
Exports memories from Leteo into an Obsidian vault as Markdown, allowing users to browse and manage their memories in Obsidian.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Leteowhat do we have on the auth implementation?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Leteo — persistent memory for AI coding agents
Your coding agent forgets everything when the session ends, and most of it when the context is compacted. Leteo is the memory it keeps: decisions, bug fixes, conventions and the discoveries that were expensive to make, stored in a local SQLite database and handed back when they are relevant.
One binary, no server, no API key. Nothing leaves your machine unless you turn on cloud replication for a project you name.
Measured against itself — the same agent, the same questions, once with it and once without:
Four right answers out of four, where the agent without it got none out of three. That is the finding that survives the variance, and the tokens are the noisier half of it. Every run is here — both baselines, the fixed cost of about 15,400 tokens a session that both arms pay, and the pairing from these same seven runs that says Leteo costs 3.7x as much.
Works with: Claude Code · ZCode · Codex · Cursor · Gemini CLI · OpenCode · Windsurf · VS Code Copilot · Kilo Code · Qwen · Kiro · Antigravity · Pi · DeepSeek Harness
What it feels like
You never prompt it to remember. That is the whole idea. Your agent opens each session already holding what the project knows, and saves as it goes while you work — a bug fixed, a convention agreed, something non-obvious learned. Those notes are written for its future self rather than for you, so they stay out of the conversation.

The rest is a SQLite file you own. leteo tui opens it, leteo export takes it
with you, and leteo delete means it.

Related MCP server: basic-memory
Does it pay for itself?
Measured rather than asserted, over thirteen runs: four right answers out of four on the questions the code cannot answer, where an agent without it got none out of three — or three out of three against that same none out of three, on the strict protocol. That is the finding that survives the variance.
The tokens are noisier. On those same questions the median saving is 27% and the best case 70% — or 17% and 44% if you drop the one run whose prompt differed by a field, which the article does for you. On questions the code does answer the difference is inside the noise, and the same thirteen runs support "costs 3.7x as much" if you pick the opposite pair.
does memory save tokens? shows every run, both baselines, the fixed per-session cost of about 15,400 tokens, and where the number is weak. The honest summary is that it does not reliably save you tokens — it stops your agent confidently answering something else.
Install
# Linux and macOS
curl -fsSL https://raw.githubusercontent.com/asanabrial/leteo/main/scripts/install.sh | sh# Windows
irm https://raw.githubusercontent.com/asanabrial/leteo/main/scripts/install.ps1 | iexOr through a package manager, if you already keep your tools in one. Homebrew covers macOS and Linux, on both architectures:
brew tap asanabrial/leteo && brew install leteo# Windows
scoop bucket add leteo https://github.com/asanabrial/scoop-leteo
scoop install leteo# Anywhere with Node, if that is what you already have
npm install -g @asanabrial/leteoThat last one puts leteo on your PATH for the command line, and is the one
route that cannot configure an agent: leteo setup refuses from a binary npm
is holding, because the path it would write down is one npm deletes. Configure
the agent with the npx line instead, or
install by any of the routes above.
Then open Leteo and set your agent up from the Setup screen:
leteo tuiThat is all of it. Nothing else to install first — not Rust, not SQLite, not a
runtime: the archives are prebuilt binaries with SQLite compiled in, and each
script checks its download against the published SHA256SUMS before installing
anything. From the scripts the binary lands in ~/.local/bin, or
%LOCALAPPDATA%\leteo\bin on Windows — Homebrew and Scoop put it where they
put everything else. LETEO_INSTALL_DIR moves that, LETEO_VERSION takes a
tag other than the latest release, and LETEO_BASE_URL downloads from
somewhere other than GitHub releases. Those three belong to the scripts rather
than to the binary, which is why they are not in the
Environment table.
Releases carry five builds — x86-64 Linux, Windows and macOS, and arm64 Linux and macOS. The two Linux ones ask for nothing newer than glibc 2.34, so they run on Debian 12, Ubuntu 22.04, RHEL 9 and anything later. That floor is pinned in the release workflow rather than inherited from whichever image GitHub calls latest: v0.1.0 inherited it, and wanted a glibc newer than Debian stable's. On anything else, build from source, which is the one route that needs Rust:
cargo install leteoThat builds the released version from crates.io.
cargo binstall leteo fetches the same release binary instead of compiling it,
which is the faster half of that sentence. To build whatever is on main
instead, including work that has not been released yet, ask for the repository:
cargo install --git https://github.com/asanabrial/leteo.
Without installing anything
Most MCP documentation assumes npx, so there is a wrapper on npm that fetches
the release binary for your platform, checks it against the same published
SHA256SUMS, and hands it every argument:
{
"mcpServers": {
"leteo": {
"command": "npx",
"args": ["-y", "@asanabrial/leteo", "mcp"]
}
}
}bunx @asanabrial/leteo mcp works the same way — it is the same package from
the same registry, and the wrapper depends on nothing but what both runtimes
already have. npm install -g above is that same package installed once
instead of fetched per run.
The npm version is the release tag, so pinning one in npm pins the binary it
fetches — a guard holds the two numbers together, because published one behind
it would quietly serve the previous release to everybody arriving this way. It
is a way in rather than the way to run it: a binary on your PATH starts
without a download and is what leteo setup writes into your agent.
As a plugin
Claude Code takes Leteo as a plugin, which registers the same MCP entry and the
same five lifecycle hooks leteo setup writes, through Claude Code's own plugin
machinery:
/plugin marketplace add asanabrial/leteo
/plugin install leteo@leteoThe plugin carries configuration, not the binary. Install leteo by one of the
routes above first: the MCP entry and every hook the plugin registers run
leteo from PATH, so without it they are five commands that are not there.
What the plugin replaces is the setup step, and removing it takes those entries
away again.
Pick one of the two, not both. Registered twice, every lifecycle event runs
twice — which stored each prompt twice, 23 identical pairs on the machine where
it was found, before anybody noticed anything was wrong. leteo setup --hooks
now looks for an installed bundle and refuses rather than adding a second
registration, naming the file it found.
Codex has the same bundle under plugin/codex, and there it is
the only route to the hooks — leteo setup codex registers the MCP server and
no hooks at all, which leaves Codex holding the tools with nothing telling it
when to reach for them.
ZCode has one under plugin/zcode, from the same marketplace.
Adding a marketplace is a desktop action, not a command: Settings → Plugins →
Create → Add marketplace, pointing at asanabrial/leteo. Then install
leteo-zcode from the list.
Its CLI does not add marketplaces — zcode plugins lists and enables what is
already installed, and nothing more. Checked against zcode 0.16.5:
$ zcode plugins --help
plugins List and enable installed plugins (`plugins list`)It registers three hooks rather than five, because that client fires neither
SubagentStop nor SessionEnd. It is also the route that does not depend on
somebody else's switch: ZCode runs configuration-file hooks only while
hooks.enabled is true in ~/.zcode/cli/config.json, which starts off, and
enabling the plugin is what enables the plugin's hooks.
Uninstall
leteo uninstall
leteo uninstall --yesThe first reports what would go and changes nothing. The second carries it out: Leteo leaves every agent it configured, and then the machine. On Windows it also registers itself in Installed apps, so it can be removed from there instead.
To leave one agent and stay in the rest:
leteo setup claude-code --uninstallThat takes out the MCP entry, the lifecycle hooks and the protocol block, and nothing else — other servers, other tools' hooks and your own notes stay where they are.
MCP
A 22-tool MCP server over standard input/output, run directly or written into a
client by leteo setup:
leteo mcpRun like that it offers all of them. Three of the twenty-two change or count
the whole store, and leteo setup leaves those out: what it writes into an
agent is --tools=agent, the nineteen an agent reaches for while it works.
--tools picks a profile or a single tool, and --project fixes the project
for the process.
Alongside it there is a JSON command line, an interactive terminal UI, and setup support for fourteen MCP clients — the list at the top of this page.
Its name in the MCP Registry is
mcp-name: io.github.asanabrial/leteo, which is what server.json
publishes. The line is written out rather than hidden in a comment because that
is what the registry reads to believe this repository owns the crate, and
crates.io strips HTML comments when it renders this file.
What you type
Rarely anything: the saving and the recalling happen without you. This is the
store from the outside, for the times you want to look yourself. Every command
that answers prints JSON — tui is the exception, being a screen rather than an
answer — and the default database is ~/.leteo/leteo.db.
Reading it. search is the one you will actually use, and --all-projects
widens it past the project you are standing in. recent is the last few in time
order; context is the block an agent is handed when a session opens, so it
shows what yours are starting with; timeline reads what was saved either side
of one memory; stats counts what is there. tui is all of it on one screen.
leteo search "connection pool" --project leteo
leteo search "connection pool" --all-projects
leteo recent --project leteo --limit 20
leteo context leteo --scope project
leteo timeline 42 --before 5 --after 5
leteo stats
leteo tuiWriting by hand. Seldom needed, since the agent saves as it works — but a memory you want in your own words, and the session boundaries an agent would otherwise draw for you:
leteo save "SQLite architecture" "One writer, many readers" --project leteo --type architecture
leteo session-start session-1 --project leteo
leteo session-end session-1Setting an agent up. On its own it walks through it; naming an agent does
that one. --hooks adds the lifecycle hooks that make memory automatic, and
--dry-run reports every file it would touch without writing one:
leteo setup
leteo setup claude-code --hooks
leteo setup opencode --dry-runKeeping it well. doctor runs every check and says which one failed and
why; --repair carries out the three that are safe to make on their own —
restoring missing full-text triggers, rebuilding the indexes, and recomputing
stale hashes.
export and import move a store between machines, and obsidian-export
writes it into a vault as Markdown:
leteo doctor
leteo doctor --repair
leteo export --project leteo --output leteo-export.json
leteo import leteo-export.json
leteo obsidian-export --vault C:\Vaults\Notes --project leteoProjects. A project is worked out from the directory, so the same work can
end up filed under two names. consolidate folds a group of them into one name,
prune drops the ones holding no memories at all:
leteo projects list
leteo projects consolidate --project leteo --apply
leteo projects prune --applyConflicts. When a new memory looks like it contradicts an older one the two
are paired and the agent settles the pair. These read the same pairs from
outside: list and show for what is there, scan to look for pairs nobody
has recorded yet, stats to count them by verdict:
leteo conflicts list --project leteo --status pending
leteo conflicts show 7
leteo conflicts scan --project leteo --apply
leteo conflicts stats --project leteoDeleting. Without --hard a memory is marked deleted and stops coming back
in answers; with it, the row is gone and its relations are cut. A project takes
the same flag. A session takes none, and while it still holds memories deleting
it is refused outright and says how many — a session goes when it is empty, not
by taking its memories with it:
leteo delete observation 42 --hard
leteo delete session session-1
leteo delete project leteo --hardprojects consolidate, projects prune and conflicts scan change nothing
until --apply: without it each one reports exactly what it would do.
Languages
Three settings, because they answer three different questions.
interface is Leteo's own screens: the panels, the menus, the help. Twelve
languages — English, español, português, français, Deutsch, italiano, català,
galego, euskara, Nederlands, polski, svenska — deliberately the same twelve
offered for memories, from the same table. Left unset it follows the machine's
locale, so a Spanish computer gets a Spanish dashboard without being asked.
voice_language is what Sardi speaks, and it is separate because those
lines are written into your agent's conversation rather than onto Leteo's
screens. Working in English on a Spanish machine is an ordinary thing to do.
Left unset it follows interface. It is the same twelve languages.
language is what memories are written in. It is handed to a model rather
than parsed, so it is free text and not limited to the twelve above: español,
Spanish, português do Brasil and 日本語 all work. Left unset, each memory
is written in the language of the conversation that produced it.
Settings
Those three and two more are kept in settings.json, in the data directory —
~/.leteo/settings.json unless you moved it. The Setup screen writes the file,
and it is also meant to be opened by hand: a value it cannot read costs that one
setting rather than the whole file. Nothing says so at the time, though, because
a hook must not fail while you are mid-edit — leteo doctor is what names a
setting being read past.
Key | Values | Unset means |
| one of the twelve above | follow the machine's locale |
| one of the twelve above | follow |
| free text | the language of each conversation |
|
|
|
|
|
|
The two languages are written as the language's own name — español, not es —
and read back forgivingly, because this is a file people type into: the English
name, the ISO code and the spelling without the accent all work.
voice is how much of its own work Sardi says out loud — everything, the save
reminder alone, or nothing. context_size is how many memories a session opens
with: twenty, fifty or eighty, for a small context window or for a store that
matters more than the budget.
Two of the five are flags as well, because changing them should not mean reconfiguring an agent. Either one on its own is a whole command:
leteo setup --language "español"
leteo setup --context slimCloud
Optional, off by default, and per project. Your machine is the client; the cloud never connects back.
Turning it on takes two answers: where the server is, and which projects go
to it. config set writes the first into the data directory — into a file with
restricted permissions, because it holds a token — and enroll names a project.
Nothing replicates until both are done, and the commands below say so rather
than starting quietly:
leteo cloud config set --server https://memory.example.com --token YOUR-TOKEN
leteo cloud enroll --project leteo
leteo cloud config showconfig show reads the configuration back with the token replaced by a presence
flag, so it is safe to paste.
Once it is on, health asks the server whether it is there and answering.
status contacts nothing at all: it reports this machine's own view — what is
enrolled, how many changes are waiting and since when, and whether the last
attempt failed and with what. sync runs one cycle now, and leteo serve keeps
running them in the background until interrupted:
leteo cloud health
leteo cloud status
leteo cloud sync
leteo serveNot to be confused with leteo cloud serve, which is the other end — the server
itself, which you only run if you are hosting one. That side, with its Compose
stack, managed tokens and project grants, is in
openspec/specs/replication.md.
Coming From Engram
Leteo is an independent Rust product derived from the workflow and MIT-licensed implementation of Gentleman Programming's Engram. It is not affiliated with or endorsed by that project, and promises no drop-in CLI compatibility.
It reads an Engram database directly, so moving across is a copy. The first reports what it would adopt and writes nothing; the second carries it out, and refuses a second time rather than importing everything twice:
leteo import --from-engram --dry-run
leteo import --from-engramIt defaults to ~/.engram/engram.db; pass --source for another path. The copy
folds in the write-ahead log, so a running Engram's most recent memories come
across and its own file is never written to.
Build
Leteo requires Rust 1.97 or newer.
cargo fmt --all
cargo test
cargo clippy --all-targets -- -D warnings
cargo build --releaseCI runs the tests. The formatting and the lints are on you before you commit,
which is why they are listed here and in AGENTS.md rather than
only in a workflow.
The cloud tests need a real PostgreSQL and are skipped without one. Point
TEST_DATABASE_URL at a throwaway database and run cargo test -- --ignored;
they create and drop their own schema, and are not written to share one.
Contributors — human or agent — should read AGENTS.md first.
Documentation
This file is the user-facing guide. What the system guarantees, and why, is in
openspec/ — one document per capability, cross-linked:
Document | Covers |
what Leteo is, the crate layout, the system-wide invariants | |
what a memory is, its types, review windows, normalisation | |
matching, ranking, the three stages, the narrowings | |
the database, migrations, | |
the MCP surface and the shape of its replies | |
the five lifecycle events and their time budgets | |
the command line and what its answers explain | |
the optional PostgreSQL peer |
Longer write-ups of individual measurements live in docs/. The first
is there was nothing worth tuning: the third
search stage answers questions belonging to another project 90.2% of the time,
which is more often than it answers its own, and four rules swept across their
whole range say that is not a threshold anybody can fix.
The second is does memory save tokens?, which asks the question this project was launched with and answers it against itself: on questions the repository already answers the saving is inside the noise, on questions it cannot answer the agent without memory spends more and still gets it wrong three times out of three, and six of eleven sampled memories from the opening block turn out to be recoverable from the repository anyway — code, specs, tests and the git history together.
Environment
None of these has to be set. This is an inventory of every variable the
binary reads — a test fails the build when the binary honours one this table
leaves out — and not a list of things to configure. leteo setup writes what an
installation needs into each agent's own configuration file, and the choices you
make in the interface are kept in settings.json. Neither of them
sets a variable in your environment.
All but the last are a command-line flag as well, and the flag wins: the variable is read only when the command line does not answer the same question.
Variable | Flag | Purpose |
|
| Local data directory; defaults to |
|
| Explicit local SQLite path |
|
|
|
|
| Project the MCP server trusts for the whole process; without it, the working directory decides |
|
| Agent CLI that judges conflict candidates: |
| — | Language this machine works in, when |
Two are worth a sentence more, because they are where the flag winning bites:
LETEO_TOOLSis already answered for every agent Leteo sets up: the MCP entry it writes runsleteo mcp --tools=agent. Exporting the variable afterwards changes nothing for that agent — edit the profile in its configuration file, or run the setup again.LETEO_DATA_DIRis the one with a real reason to be exported. The MCP server is started by the agent rather than by you, so a database somewhere other than~/.leteohas to reach it either through that agent's environment or as a--data-dirin the command its configuration runs.
Cloud, on your machine
leteo cloud config set persists the server and the token in the data directory
and is how this is configured. These two are read only where that file leaves
the field empty, so a setup that predates it keeps working unchanged.
Variable | Purpose |
| Cloud base URL for |
| Sync bearer token, at least 32 bytes |
leteo cloud serve reads LETEO_CLOUD_TOKEN too, as its own legacy static
token — on a machine that is both client and server, one name means two things.
Cloud, on the server
These belong to whoever runs leteo cloud serve, and they are set where that
service is defined — see
docker/docker-compose.yml. There is no wizard for
them on purpose: they are deployment secrets rather than preferences, and none
of this applies to a normal installation.
Variable | Purpose |
| PostgreSQL URL for cloud serve |
| Dashboard signing secret, at least 32 bytes |
| Managed-token HMAC pepper, at least 32 bytes |
| Optional legacy admin bearer token, at least 32 bytes |
| Required allowlist for legacy cloud tokens |
| Cloud bind host; defaults to |
| Cloud port; defaults to |
| PostgreSQL connection-pool limit |
| Maximum cloud push body size |
License And Attribution
Leteo is distributed under the MIT License. See LICENSE and
NOTICE for upstream attribution and the exact reference revision.
Tagged binary archives also include a generated THIRD_PARTY_LICENSES.html
covering their Rust dependencies.
Available Tools
22 toolsmem_capture_passiveA
Extract and save the Key Learnings items a subagent ended with, in any of the twelve languages Leteo writes memories in. Each becomes a memory of its own, filed under the tool that produced it.
| Name | Required | Description | Default |
|---|---|---|---|
| source | No | Source identifier. | mcp-passive |
| content | Yes | Text ending in a Key Learnings section, in any of the twelve languages Leteo writes memories in. | |
| session_id | No | Session identifier. Defaults to manual-save-{project}. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | Why nothing came out, when nothing did. |
| saved | No | |
| dropped | No | Learnings past the ceiling, which this capture did not keep. |
| project | No | |
| extracted | No | |
| duplicates | No | |
| project_path | No | Where the project lives, when the answer came from a directory. |
| project_source | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds useful postcondition information beyond the sparse annotations: each Key Learnings item becomes its own memory and is filed under the producing tool. While it does not detail side effects or error cases, it provides meaningful behavioral context that is not derivable from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no fluff. Every clause contributes meaning: action, source, language scope, and storage behavior. The structure is front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple write tool with high schema coverage and an output schema present, the description covers purpose and behavior sufficiently. It lacks explicit alternative guidance or caveats, but these are not critical given the tool's straightforward nature.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter is already explained. The description does not add extra parameter-level semantics beyond noting the content requirement and language scope, which is partially schema-covered. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly specifies a concrete action ('Extract and save') and resource ('Key Learnings items a subagent ended with'), and distinguishes itself from sibling tools by noting the items are 'filed under the tool that produced it' and supported in 'twelve languages'. This goes beyond a generic save tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for subagent outputs with a Key Learnings section, but it does not explicitly state when to use this tool instead of alternatives like mem_save or mem_save_prompt, nor does it mention exclusions or conditions. It is not misleading, just minimally guiding.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_compareAIdempotent
Persist a semantic verdict between two observation IDs. Semantic not_conflict is a successful no-op.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | Optional model identifier stored as provenance. | |
| relation | Yes | Verdict: related, compatible, scoped, conflicts_with, supersedes, or not_conflict. | |
| reasoning | No | Optional short explanation for the verdict. | |
| confidence | No | Optional confidence score in the inclusive range 0.0..1.0. | |
| memory_id_a | Yes | Integer ID of the first observation. | |
| memory_id_b | Yes | Integer ID of the second observation. |
Output Schema
| Name | Required | Description |
|---|---|---|
| sync_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds the key behavioral nuance that 'Semantic not_conflict is a successful no-op,' which is not captured by the annotations. It also confirms the write nature of the operation, aligning with readOnlyHint=false. This adds value beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, compact sentence that conveys the core purpose and an important edge-case behavior. Every word earns its place, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich schema (100% param coverage), output schema presence, and annotations (idempotentHint, destructiveHint), the description is sufficient. It captures the essential purpose and the no-op nuance, and additional details are not necessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are already well-documented. The description's mention of 'two observation IDs' simply echoes memory_id_a and memory_id_b, adding no new semantic meaning beyond the schema. The relation values are listed in the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description provides a specific verb+resource+scope: 'Persist a semantic verdict between two observation IDs.' This clearly distinguishes the tool from siblings like mem_save or mem_review, and the note about not_conflict being a no-op adds crucial specificity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when a semantic verdict is to be recorded between two observations, but it does not explicitly state when to use this tool versus alternatives (e.g., mem_judge, mem_review). No exclusions or alternate tool references are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_contextARead-onlyIdempotent
Get pinned and recent observations plus the recent sessions and user prompts of a project. Answers about the current project unless you pass a project or all_projects. Long bodies come back as a 400-character preview marked content_truncated; read one in full with mem_get_observation.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of recent observations. Eighty at most, which is the deepest context Leteo itself is ever configured to open with. | |
| scope | No | Restrict observations to this scope: project, personal, or global. | |
| project | No | Restrict recent observations to this project. | |
| all_projects | No | List every project and ignore the detected one. | |
| prompt_limit | No | Maximum number of recent user prompts. Twenty at most, the ceiling every list on this surface has. | |
| session_limit | No | Maximum number of recent sessions. Twenty at most, the ceiling every list on this surface has. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | Carried when this project answered with nothing and the store did not. |
| count | No | How many memories this answer carries, across both lists. |
| project | No | |
| prompts | No | |
| sessions | No | |
| observations | No | |
| project_path | No | Where the project lives, when the answer came from a directory. |
| pinned_omitted | No | How many pinned memories did not fit, when the shelf outgrew the block. |
| project_source | No | |
| also_remembered | No | Everything behind the newest few, as an index rather than a recital. |
| memory_language | No | What language to write and search memories in. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds transparency about the 400-character preview with `content_truncated` and the default project scoping, which are not captured in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each with a distinct purpose: what it returns, how scoping works, and warning about truncation with a pointer to another tool. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and 6 parameters fully documented, the description covers the essential behavior: return types, default scope, and truncation. It could mention ordering or that pinned observations may span scopes, but this is sufficient for a tool invocation decision.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds semantic meaning for `project` and `all_projects` by explaining the default behavior ('Answers about the current project unless you pass a project or all_projects'), going beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Get pinned and recent observations plus the recent sessions and user prompts of a project.' This specifies a concrete action and resource, and it distinguishes itself from the sibling tool mem_get_observation by noting that tool is for reading full observations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains the default scope ('Answers about the current project unless you pass a project or all_projects') and points to an alternative for full reads ('read one in full with mem_get_observation'). It lacks explicit 'when not to use' guidance for other siblings, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_current_projectARead-onlyIdempotent
Detect the current project without failing on ambiguous or invalid project context.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| cwd | No | |
| project | No | |
| warning | No | |
| error_hint | No | |
| project_path | No | |
| project_source | No | |
| available_projects | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool as read-only, idempotent, and non-destructive. The description adds a valuable behavioral guarantee—'without failing on ambiguous or invalid project context'—which is not present in the annotations and helps the agent understand edge-case behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. Every element adds meaning, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that this is a zero-parameter, read-only tool with an output schema and comprehensive annotations, the description is sufficiently complete. It captures the core purpose and a key behavioral nuance, with return details covered by the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema coverage is 100%, so the description has no additional burden. The baseline of 4 applies because there are no parameter semantics to clarify.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Detect' with a clear resource 'current project' and adds a distinguishing qualifier about handling ambiguous/invalid context. This clearly separates it from broader sibling tools like mem_context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Detect the current project' implies when to use it, but there is no explicit guidance about alternatives or when not to use it. The usage context is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_deleteADestructive
Delete an observation by ID. Soft-delete by default; hard_delete permanently removes it.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Numeric observation identifier. Also accepted as `observation_id`. | |
| hard_delete | No | Permanently remove the row instead of soft-deleting it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| status | No | |
| hard_delete | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive behavior. The description adds the crucial distinction between soft-delete (default) and hard-delete (permanent), which is valuable context beyond the structured metadata. However, it does not detail what happens to associated data or potential side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the action and includes the key default behavior. No unnecessary words; every element contributes value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with annotations and an output schema, the description adequately covers the essential behavior (soft vs. hard delete) and the acceptance of `observation_id`. No further context is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers all parameters with descriptions and defaults. The description only echoes 'by ID' and 'hard_delete' without adding new semantic meaning. With 100% schema coverage, the baseline is 3, and the description does not elevate it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: deleting an observation by ID, with a specific verb and resource. It also distinguishes between soft-delete and hard-delete modes, which sets it apart from other memory tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context is clear: to delete an observation, use this tool. It does not explicitly mention alternatives or when not to use it, but the delete operation is unambiguous and distinct from sibling tools like mem_update or mem_get_observation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_doctorARead-onlyIdempotent
Run read-only SQLite, FTS, foreign-key, and mutation-journal diagnostics.
| Name | Required | Description | Default |
|---|---|---|---|
| check | No | Optional upstream diagnostic check code; the local report includes all checks. | |
| project | No | Project context to report; diagnostics remain store-wide. |
Output Schema
| Name | Required | Description |
|---|---|---|
| check | No | |
| checks | No | |
| issues | No | |
| healthy | No | |
| project | No | |
| prompts | No | |
| journal_mode | No | |
| observations | No | |
| project_stats | No | Present only when a project was explicitly requested and matched. |
| prompt_fts_ok | No | |
| schema_version | No | What the store is stamped at, and what this build reads. Carried so an agent can say which of the two is behind when a binary refuses a store. |
| busy_timeout_ms | No | |
| integrity_check | No | |
| prompt_fts_rows | No | |
| schema_supported | No | |
| pending_mutations | No | |
| observation_fts_ok | No | |
| observation_fts_rows | No | |
| foreign_key_violations | No | The violations, as examples rather than as an inventory. |
| foreign_key_violations_omitted | No | How many violations there were beyond the ones listed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/non-destructive, so the description's mention of 'read-only' adds no new behavior. It does add specific diagnostic domains, but no deeper behavioral traits like performance impact or required session state are disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with zero waste. It clearly states action and scope without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema, annotations, and full parameter schema coverage, the description covers the essential diagnostic scope. It lacks usage context and report expectations, but those are likely handled by the output schema and sibling tool composition.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters are fully described in the schema (100% coverage), and the tool description adds no additional parameter information. Baseline of 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Run' and clearly identifies diagnostic scope (SQLite, FTS, foreign-key, mutation-journal). This distinguishes it from the many sibling memory-management tools, making the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance on when to use this tool versus alternatives. It implies diagnostic use but does not state conditions for invocation, prerequisites, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_get_observationARead-onlyIdempotent
Get one complete observation by its numeric identifier, with its full body — unlike mem_search and mem_context, which preview it. Reads state: a memory that has been deleted is still returned here and says so.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Numeric observation identifier. Also accepted as `observation_id`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| observation | No | The memory, carrying whatever the graph says against it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and non-destructive hints. The description adds a meaningful behavioral trait: the tool reads state and returns deleted memories with an indication, which is beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no fluff. The first sentence states purpose and differentiators; the second discloses a key edge case. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-parameter tool with an output schema, the description covers purpose, sibling comparison, and a specific behavioral edge case. It is fully sufficient for an agent to select and call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 100% coverage, already describing the id parameter and its alias. The description does not add any extra parameter-specific meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool gets one complete observation by numeric identifier, with full body. It explicitly distinguishes from mem_search and mem_context, which preview it, making the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly contrasts with sibling tools (mem_search, mem_context) and indicates this tool returns the full body rather than a preview. The note about deleted memories being returned also informs when 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.
mem_judgeAIdempotent
Record a manual verdict on a pending relation surfaced by mem_save. Manual not_conflict verdicts are persisted. Reason and evidence each come back as a 400-character preview marked reason_truncated or evidence_truncated.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | Optional explanation for the verdict. | |
| evidence | No | Optional JSON or text evidence. | |
| relation | Yes | Verdict: related, compatible, scoped, conflicts_with, supersedes, or not_conflict. | |
| confidence | No | Optional confidence score in the inclusive range 0.0..1.0. | |
| session_id | No | Optional session in which the verdict was made. | |
| judgment_id | Yes | Relation sync ID returned as candidates[].judgment_id by mem_save. |
Output Schema
| Name | Required | Description |
|---|---|---|
| relation | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint=false, idempotentHint=true), the description adds useful behavioral details: 'Manual not_conflict verdicts are persisted' and reason/evidence return as 400-character previews with truncation flags. This informs the agent about response behavior without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences that front-load the core purpose and then add relevant detail about persistence and truncation. Every sentence earns its place; no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity and presence of an output schema, the description covers the essential behavior: source of judgment_id, persistence semantics, and response preview behavior. It could elaborate on the effect of other verdict types, but that is not critical for selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains all parameters. The description references the truncation of reason/evidence, but that is more about output behavior than parameter meaning. It adds no significant parameter semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Record a manual verdict on a pending relation surfaced by mem_save.' It uses a specific verb ('record') and resource ('verdict on a pending relation'), and distinguishes itself from siblings by referencing the mem_save workflow and manual verdicts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: when a pending relation is surfaced by mem_save and a manual verdict is needed. However, it does not explicitly mention alternatives or exclusions, such as when to prefer automatic review or comparison tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_merge_projectsADestructive
Merge comma-separated project name variants into one canonical project.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Canonical project name to merge into. | |
| from | Yes | Comma-separated project names to merge from. |
Output Schema
| Name | Required | Description |
|---|---|---|
| canonical | No | |
| sources_merged | No | |
| enrolment_moved | No | Said when the canonical project had to take over a source's enrolment. |
| prompts_updated | No | |
| sessions_updated | No | |
| canonical_created | No | Said when everything moved into a name the store did not hold. |
| observations_updated | No | |
| topic_key_collisions | No | How many topic keys now name two live memories in the merged project. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=true, so the agent knows it's destructive. The description adds the context of canonicalization and comma-separated variants, but does not elaborate on consequences (e.g., whether 'from' entries are deleted or just aliased). This is minimal but non-contradictory, consistent with a '3' for adding some value beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the action verb and specifies the resource and outcome. There is zero waste or redundant phrasing, making it highly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with two fully documented parameters, an output schema, and annotations covering destructive behavior. The description is nearly complete for the tool's purpose, though it could benefit from stating whether the 'from' projects are deleted or merely reassigned. However, the existence of output schema and annotations reduces the burden, so a 4 is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both 'from' and 'to' have descriptive schema text. The description adds no new parameter semantics beyond what the schema already provides; it merely restates the relationship. Therefore the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Merge' with a clear resource ('comma-separated project name variants') and outcome ('into one canonical project'). It immediately distinguishes this tool from siblings like mem_update or mem_save by focusing on consolidation of variants, making the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use the tool: when there are multiple project name variants that should be consolidated. It provides a clear context without explicit exclusions or named alternatives, which aligns with the '4=clear context, no exclusions' level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_pinAIdempotent
Pin a local observation so it appears before recent observations in memory context.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Numeric observation identifier. Also accepted as `observation_id`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| pinned | No | |
| sync_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context by explaining the effect on memory ordering, which goes beyond the annotations. However, it does not disclose additional traits such as reversibility via mem_unpin or any side effects on existing pins. Annotations (idempotentHint=true, destructiveHint=false) cover some behaviors, so the description provides partial added value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that front-loads the action and purpose without any fluff. Every word contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (one parameter, output schema present, annotations provided), the description is complete enough. It states the action and its effect, and the structured fields cover the remaining details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully describes the single parameter 'id', including the alias 'observation_id'. The description does not add any parameter-specific information beyond what the schema provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Pin') and resource ('local observation'), and clearly states the effect (appears before recent observations in memory context). This distinguishes it from siblings like mem_unpin and mem_get_observation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: to prioritize an observation in memory context. It does not explicitly mention alternatives or exclusions, but the purpose is unambiguous and the sibling mem_unpin implies the reverse operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_reviewA
List observations due for review or mark one reviewed. Actions: list, mark_reviewed. Bodies come back as a 400-character preview marked content_truncated; read one in full with mem_get_observation.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Backward-compatible alias for observation_id. | |
| limit | No | Maximum list results. | |
| action | Yes | Action: list or mark_reviewed. | |
| project | No | Optional project filter for list. | |
| observation_id | No | Observation identifier for mark_reviewed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | How many memories this answer carries — the length of `observations`. |
| action | No | |
| due_omitted | No | How many memories are due that this page does not carry. |
| observation | No | |
| observations | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already indicate non-read-only and non-destructive, but the description adds important behavioral details: list returns only 400-character previews marked with `content_truncated`, and full reads require a separate tool. This goes beyond the annotations and is valuable for the agent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise: three sentences that front-load the core purpose, list the actions, and mention the preview behavior plus an alternative. Every sentence contributes value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (5 params, two actions) and the presence of an output schema, the description covers the essential context: what the tool does, the preview limitation, and a pointer to mem_get_observation for full content. It could mention which params apply to each action, but that is inferable from the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all parameters already have descriptions. The description only reinforces that `action` can be 'list' or 'mark_reviewed', which is already in the schema. It does not add new semantic meaning for `id`, `limit`, or `project`. The baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a review manager: it lists actions ('list, mark_reviewed') and specifies the resource ('observations due for review'). It also differentiates from mem_get_observation by noting the preview limitation, so the purpose is distinct and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly provides an alternative for a specific need: 'read one in full with mem_get_observation'. This indicates when to use another tool. However, it does not explicitly state when not to use this tool or contrast it with other sibling tools like mem_search, so guidance is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_saveBDestructive
Save an observation to persistent memory. Without session_id, uses a stable manual-save session for the detected project.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | One of: bugfix, decision, policy, architecture, discovery, pattern, config, preference. The category is a search filter, so a word outside this list is a memory that filtering never returns — a real store collected `implementation`, `feature` and `manual` that way. Close synonyms are folded on the way in; anything else is kept verbatim. | manual |
| scope | No | Memory scope: project, personal, or global. A label for filtering later — a personal memory still belongs to this project and reads narrowed to another one will not return it. | project |
| title | Yes | Short searchable title. | |
| content | No | Full observation content. | |
| project | No | Project owning this observation. Accepted only when it matches the detected project, the process override, or a project the store knows. | |
| tool_name | No | Name of the tool that produced the observation. | |
| topic_key | No | Stable key used to revise an evolving observation instead of inserting another. | |
| session_id | No | Session identifier. Defaults to manual-save-{project}. | |
| observation | No | Backward-compatible alias for content. | |
| capture_prompt | No | Link this memory to the question it answers: the prompt this process last recorded, else the session's last one, else — only when no session_id is given — the project's last from the past 30 minutes. Defaults to true. Pass false for automated saves that answer no user request. | |
| recovery_token | No | Short-lived token returned by an ambiguous_project error. Required with project_choice_reason. | |
| project_choice_reason | No | Must be user_selected_after_ambiguous_project, and only after the user picked one of available_projects from an ambiguous_project error. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | Said when a summary was saved without a name anybody could find it by. |
| status | No | |
| project | No | |
| candidates | No | |
| judgment_id | No | |
| observation | No | |
| project_path | No | Where the project lives, when the answer came from a directory. |
| project_source | No | |
| judgment_status | No | |
| judgment_required | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=true and readOnlyHint=false, so the write nature is known. The description adds the 'stable manual-save session' default when session_id is omitted, which is valuable context. It does not elaborate on irreversibility or side effects, but the annotation covers the destructive nature. No contradictions detected.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the primary action and a key default behavior. There is no filler or redundancy; every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the high parameter count (12) and rich schema descriptions, the one-sentence description is lean. It covers the primary purpose and a key default, but it omits usage guidance and does not mention important behaviors like topic_key revision, project ambiguity handling, or capture_prompt linking. The rich schema and annotations compensate partially, but the description itself leaves contextual gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The tool description does not add anything beyond the schema's own detailed parameter descriptions (e.g., session_id default is already documented in the schema). Therefore, the description contributes no additional parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb+resource: 'Save an observation to persistent memory.' It distinguishes from sibling tools like mem_save_prompt by focusing on 'observation' rather than 'prompt', though it does not explicitly name alternatives. The core purpose is immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use mem_save vs alternatives such as mem_save_prompt or mem_capture_passive. It mentions the session_id default behavior, which is a useful context, but it does not state explicit usage conditions, exclusions, or scenarios where another tool would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_save_promptA
Save a user prompt in an existing session. The prompt comes back as a 400-character preview marked content_truncated; keep the sync_id to link a later save to it.
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | Original user prompt text. | |
| project | No | Project associated with the prompt. Accepted only when backed by known context or an ambiguous-project recovery. | |
| session_id | No | Session identifier. Defaults to manual-save-{project}. | |
| recovery_token | No | Short-lived token returned by an ambiguous_project error. Required with project_choice_reason. | |
| project_choice_reason | No | Must be user_selected_after_ambiguous_project, and only after the user picked one of available_projects from an ambiguous_project error. |
Output Schema
| Name | Required | Description |
|---|---|---|
| prompt | No | |
| project | No | |
| project_path | No | Where the project lives, when the answer came from a directory. |
| project_source | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important behavioral details beyond the annotations: the 400-character preview with the `content_truncated` flag and the need to retain the sync_id. This adds meaningful context about return behavior and follow-up actions, going beyond what annotations alone indicate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler, front-loading the core action and immediately providing the most critical behavioral caveat (truncation and sync_id). Every word serves a purpose, making it highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the essential behavior (save, preview, sync_id) and benefits from a detailed schema and output schema. It does not explain the ambiguous-project recovery flow or the project_choice_reason/recovery_token interaction, but those are thoroughly documented in the schema, so the overall context is sufficient for an agent to operate effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides complete descriptions for all 5 parameters (100% coverage), so the description does not need to compensate. The mention of sync_id refers to an output field rather than a parameter, adding no extra clarity to parameter usage beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Save') and resource ('a user prompt') with a clear scope ('in an existing session'). It distinguishes itself from sibling tools like mem_save by referencing the existing-session requirement and the sync_id linking behavior, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies the context of use: saving a prompt into an existing session, and emphasizes keeping the sync_id for linking later saves. However, it does not explicitly mention when not to use this tool or name alternatives, so it falls short of the highest bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_searchARead-onlyIdempotent
Search persistent observations by full-text query and optional filters. Answers about the current project unless you pass a project or all_projects. Long bodies come back as a 400-character preview marked content_truncated; read one in full with mem_get_observation.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Restrict results to this observation category. One of: bugfix, decision, policy, architecture, discovery, pattern, config, preference. Close synonyms are folded, so `bug` finds a `bugfix`. | |
| limit | No | Maximum number of results. The store clamps this to its configured maximum. | |
| query | Yes | Full-text query or an exact topic key containing a slash. | |
| scope | No | Restrict results to this memory scope: project, personal, or global. | |
| project | No | Restrict results to this project. | |
| match_mode | No | Require all query terms or allow any query term. | |
| all_projects | No | Search every project and ignore the project filter. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | Carried when nothing matched, or when only some of the words did. |
| count | No | How many memories are in `results` — the length of that list, not how many matched. When more matched than were returned, the hint says so. |
| project | No | |
| results | No | |
| project_path | No | Where the project lives, when the answer came from a directory. |
| project_source | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, but the description goes beyond by disclosing that long bodies are truncated to a 400-character preview with a content_truncated flag. This is critical behavioral context not present in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: the action, the scope default/override, and the truncation behavior with a pointer to the alternative tool. It is concise and well-structured with key information front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 7-parameter schema and presence of an output schema, the description covers the essential caveats (default project scope, preview truncation, and how to get full content). It gives the agent enough to select and invoke the tool correctly without requiring extra external knowledge.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% parameter coverage, providing detailed descriptions for all 7 parameters. The tool description adds no new parameter-specific semantics beyond summarizing that filters are optional, so it appropriately relies on the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: searching persistent observations via full-text query with optional filters. It specifies the scope behavior (current project unless overridden) and explicitly distinguishes itself from mem_get_observation, which is used to read full bodies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit guidance on default behavior (current project) and how to alter it (project or all_projects). It also names an alternative tool (mem_get_observation) for the specific case of retrieving a full observation, fulfilling the when/when-not/alternatives criterion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_session_endAIdempotent
End an existing memory session and optionally attach a summary. The session comes back with its summary as a 400-character preview marked summary_truncated.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Identifier of the session to end. Also accepted as `session_id`. | |
| summary | No | Optional concise session summary. |
Output Schema
| Name | Required | Description |
|---|---|---|
| session | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint=true and destructiveHint=false, which cover the safety profile. The description goes beyond annotations by explaining the return behavior: the session comes back with a 400-character preview marked 'summary_truncated'. This adds useful contextual detail about the output without contradicting any annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the action, and every phrase provides value. There is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (2 params, no nested objects) and the presence of an output schema, the description covers the essential functional context and the notable return behavior (truncated preview). No critical information seems missing for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully documents both parameters: 'id' (with an alias) and 'summary'. The description merely reinforces 'optionally attach a summary', which is already stated in the schema. With 100% schema coverage, the description adds no new parameter-level semantics beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb ('End') and resource ('existing memory session'), and distinguishes it from siblings like mem_session_start and mem_session_summary. The optional summary attachment is also mentioned, leaving no ambiguity about the tool's purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly indicates when to use this tool (to end an existing memory session) and mentions an optional action (attach a summary). It does not explicitly exclude alternatives, but the context is clear enough that an agent can differentiate it from related session tools like mem_session_start.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_session_startAIdempotent
Create a memory session, or return it unchanged if its identifier exists.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Unique session identifier. Also accepted as `session_id`, which is what every tool that writes to a session calls it. | |
| project | No | Optional explicit project; otherwise it is detected from directory or cwd. | |
| directory | No | Working directory for this session. |
Output Schema
| Name | Required | Description |
|---|---|---|
| session | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint=true, and the description essentially restates that with 'return it unchanged if its identifier exists.' It adds minor specificity but no deeper behavioral context such as side effects or prerequisites. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence that conveys the core action and idempotent behavior with zero wasted words. Excellent structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, idempotent create tool with full schema descriptions, annotations, and an output schema, the description is sufficient. It could have mentioned typical usage context (e.g., as a setup step before using memory tools), but that is not essential.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter has a description. The tool description adds no additional meaning to the parameters, just uses the word 'identifier' which maps to the required 'id'. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb ('Create') and resource ('memory session'), and it distinguishes behavior via the idempotent clause 'or return it unchanged if its identifier exists.' This sets it apart from siblings like mem_session_end and mem_session_summary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. It does not mention mem_session_end for closing sessions or any other sibling, and there are no stated prerequisites or contextual triggers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_session_summaryB
Save a structured end-of-session summary as persistent memory.
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | Structured session summary content. | |
| project | No | Optional explicit project. Accepted only when backed by known context or an ambiguous-project recovery. | |
| session_id | No | Session identifier. Defaults to manual-save-{project}. | |
| recovery_token | No | Short-lived token returned by an ambiguous_project error. Required with project_choice_reason. | |
| project_choice_reason | No | Must be user_selected_after_ambiguous_project, and only after the user picked one of available_projects from an ambiguous_project error. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | Said when a summary was saved without a name anybody could find it by. |
| status | No | |
| project | No | |
| candidates | No | |
| judgment_id | No | |
| observation | No | |
| project_path | No | Where the project lives, when the answer came from a directory. |
| project_source | No | |
| judgment_status | No | |
| judgment_required | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false and destructiveHint=false, covering the basic safety profile. The description adds that the summary is 'persistent memory', which is some behavioral context, but does not disclose details about overwriting, session relationships, or the recovery-token workflow hinted by the schema parameters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, direct sentence that front-loads the tool's purpose. It contains no fluff or redundancy, making it efficient and appropriately sized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the schema and annotations are rich, the description lacks important context such as the ambiguous-project recovery workflow (recovery_token, project_choice_reason) and how this tool differs from mem_save. Given the tool's complexity, more contextual guidance would be needed for complete understanding, though the schema partially compensates.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are thoroughly documented in the JSON schema. The description adds no parameter-specific meaning beyond what the schema already provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool saves a structured end-of-session summary as persistent memory, specifying the resource (summary) and action (save). However, it does not explicitly differentiate from sibling tools like mem_save, which also saves to memory, though the 'end-of-session' qualifier provides some distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. There are no references to mem_save, mem_session_end, or exclusion criteria. The description only states what the tool does, leaving the agent to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_statsARead-onlyIdempotent
Get aggregate memory store statistics. Takes no arguments and counts the whole store; for one project's counts call mem_doctor with that project.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| projects | No | Projects that hold at least one memory, the most recently written first. Not every project the store knows: one with only a session or a prompt is absent, which on a real store is two of nineteen. |
| total_prompts | No | |
| total_sessions | No | |
| total_observations | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, so the safety profile is clear. The description adds the useful scope detail that it 'counts the whole store,' but it does not disclose other behavioral traits such as return format or pagination. With annotations covering the core safety aspects, this is adequate but not richer than expected.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long, with the primary purpose front-loaded. The first sentence states what the tool does, and the second sentence adds an alternative. Every word earns its place with no fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple tool with no parameters and an output schema (not shown but present). The description provides the essential context: aggregate scope, no arguments, and a clear alternative for project-specific counts. Given the low complexity and strong annotations, this is complete enough for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema fully covers parameter semantics (100% coverage). The description redundantly says 'Takes no arguments,' aligning with the schema. Per the rubric, 0 params earns a baseline of 4, and no additional parameter explanation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource construction: 'Get aggregate memory store statistics.' It clearly distinguishes from siblings by explicitly noting that 'for one project's counts call mem_doctor with that project,' which prevents confusion with similar memory tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit contextual guidance: it states the tool counts the whole store (when to use) and directs users to mem_doctor for project-specific counts (when not to use, with an alternative named). This is a clear and useful usage guideline.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_suggest_topic_keyARead-onlyIdempotent
Suggest a stable topic_key for observation upserts.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Observation category. One of: bugfix, decision, policy, architecture, discovery, pattern, config, preference. | manual |
| title | No | Preferred source for the topic segment. | |
| content | No | Fallback source when title is empty. |
Output Schema
| Name | Required | Description |
|---|---|---|
| topic_key | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds the useful behavioral trait 'stable', indicating deterministic output across calls. However, it does not explain how the key is generated or how edge cases (e.g., empty title and content) are handled.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no redundancy. It immediately communicates the tool's purpose and key distinguishing trait ('stable'), making it highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity, comprehensive parameter descriptions in the schema, and presence of an output schema, the short description is largely sufficient. It lacks only an explicit tie-in to the upsert workflow (e.g., suggesting use before mem_save/mem_update), but this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 100% of the three parameters, including the type enum and title/content fallback behavior. The description itself adds no additional parameter-specific semantics beyond what the schema already provides, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb 'suggest' and resource 'stable topic_key' with the context 'for observation upserts'. This clearly distinguishes it from sibling tools like mem_save or mem_get_observation, which perform different actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for observation upserts' implies when this tool should be used, but there is no explicit guidance on when not to use it or how it compares to alternatives. The usage context is clear but not elaborated with exclusions or preferred workflow placement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_timelineARead-onlyIdempotent
Show chronological context around a specific observation. Bodies come back as a 400-character preview marked content_truncated; read one in full with mem_get_observation.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Number of observations after the focus. | |
| before | No | Number of observations before the focus. | |
| project | No | Accepted for upstream schema compatibility; timeline is session-scoped. | |
| observation_id | Yes | Observation identifier at the center of the timeline. Also accepted as `id`, which is what the tools that fetch, pin or update one call it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| after | No | |
| focus | No | |
| before | No | |
| after_total | No | |
| before_total | No | How many of the session come before the focus, and how many after. `before` and `after` are capped by the window you asked for, so these say whether there is more on either side. |
| session_info | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses key behavioral detail that bodies are returned as 400-character previews marked with `content_truncated`, and directs to mem_get_observation for full content. This adds value beyond the annotations which already declare read-only/idempotent hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: the first states the purpose concisely, the second discloses critical behavior and an alternative. No redundancy or extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a rich schema, annotations, and existing output schema, the description fully covers the tool's purpose, unique behavior, and usage boundaries. No significant gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed descriptions for each parameter (after, before, project, observation_id). The tool description adds no additional parameter-specific meaning, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Show') and resource ('chronological context around a specific observation'), clearly distinguishing it from sibling tools like mem_get_observation (full read) and mem_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when not to use this tool by directing users to mem_get_observation for full observation bodies, and implies the appropriate use case of viewing chronological context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_unpinAIdempotent
Unpin a local observation so it returns to normal recency order.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Numeric observation identifier. Also accepted as `observation_id`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| pinned | No | |
| sync_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=false, destructiveHint=false, idempotentHint=true). The description adds meaningful behavioral context by explaining the effect on recency ordering, which goes beyond the annotations. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that is front-loaded with the core action and effect. It contains zero filler and every word contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, output schema exists, annotations present), the description is sufficient to convey the core purpose and effect. The term 'local observation' is a minor domain ambiguity, but overall the description is complete for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%; the id parameter is already well-documented in the schema (numeric identifier, also accepted as observation_id). The description adds no additional parameter semantics, so baseline score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('unpin') and resource ('local observation') plus a clear effect ('returns to normal recency order'). It clearly distinguishes the tool from sibling mem_pin, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (you unpin something that was pinned), but it does not explicitly state when to use this tool versus alternatives like mem_pin, nor does it describe any prerequisites or exclusions. The context is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mem_updateADestructive
Revise a stored memory. Fields left out keep their current value. The memory comes back as a 400-character preview marked content_truncated; read one in full with mem_get_observation.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Numeric observation identifier. Also accepted as `observation_id`. | |
| type | No | New observation category. One of: bugfix, decision, policy, architecture, discovery, pattern, config, preference. | |
| scope | No | New scope: project, personal, or global. | |
| title | No | New title. | |
| content | No | New content. | |
| project | No | New project. | |
| topic_key | No | New topic key. |
Output Schema
| Name | Required | Description |
|---|---|---|
| observation | No | The memory, carrying whatever the graph says against it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=true and readOnlyHint=false. The description adds meaningful behavioral context: partial-update semantics (omitted fields preserved) and the 400-character preview with content_truncated marker, along with a path to retrieve the full memory. This goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise—two sentences—and front-loaded with the core purpose. The second sentence packs two critical behavioral details (partial update and preview truncation) without extra words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a medium-complexity update tool with a fully described schema and an output schema, the description adequately covers purpose, update semantics, response format, and a follow-up action. A minor gap is not explaining how to clear a field (e.g., via null), but this is not critical given the schema allows null values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage for all parameters. The description supplements this by clarifying that omitted fields retain their current values, which is essential for understanding how to use the optional parameters. This adds value beyond the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Revise a stored memory') and the resource (memory). It also differentiates from siblings by specifying partial-update behavior ('Fields left out keep their current value'), making it distinct from tools like mem_save or mem_delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for revising existing memories, especially partial updates, but does not explicitly contrast with alternative memory tools or state when not to use it. The pointer to mem_get_observation for full reads is contextually useful but not an alternative for updating.
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. Dates show when Glama detected each change.
22 tool updates
v0.1.0- First observed
mem_capture_passive - First observed
mem_compare - First observed
mem_context - First observed
mem_current_project - First observed
mem_delete - First observed
mem_doctor - First observed
mem_get_observation - First observed
mem_judge - First observed
mem_merge_projects - First observed
mem_pin - First observed
mem_review - First observed
mem_save - First observed
mem_save_prompt - First observed
mem_search - First observed
mem_session_end - First observed
mem_session_start - First observed
mem_session_summary - First observed
mem_stats - First observed
mem_suggest_topic_key - First observed
mem_timeline - First observed
mem_unpin - First observed
mem_update
TDQS
Each tool targets a distinct operation: saving, retrieving, updating, deleting, session management, project handling, pinning, review, relations, and diagnostics. Even similar retrieval tools (search, context, timeline, get_observation) are clearly differentiated by their specific purpose and return format.
All tools share the 'mem_' prefix, which provides cohesion, but the action part mixes imperative verbs (save, search, delete), nouns (context, stats, timeline), and noun-verb constructs (session_start, session_end). This inconsistent pattern makes it less predictable than a uniform verb_noun convention.
With 22 tools, the set is on the heavy side but each tool covers a distinct aspect of memory management—sessions, projects, observations, reviews, and diagnostics. The breadth justifies the count, and it remains navigable due to the consistent prefix and clear individual purposes.
The toolset provides comprehensive coverage of the memory domain: full lifecycle for observations (create, read, update, delete), session management (start, end, prompts, summaries), project handling (detect, merge), plus pinning, review, relation verdicts, statistics, and diagnostics. No obvious gaps prevent core workflows.
Maintenance
Related MCP Connectors
Persistent memory for AI agents across Claude, ChatGPT and any MCP client.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Portable memory for AI agents: capture once, recall across Claude, Cursor, and any MCP client.
- mcpOAuthai.butlerbrain
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Related MCP Servers
- AlicenseCqualityFmaintenanceThis project is based on the Knowledge Graph Memory Server from the MCP servers repository and retains its core functionality.44353MIT
- AlicenseBqualityAmaintenanceBasic Memory is a knowledge management system that allows you to build a persistent semantic graph from conversations with AI assistants. All knowledge is stored in standard Markdown files on your computer, giving you full control and ownership of your data. Integrates directly with Obsidan.md173,864AGPL 3.0
- FlicenseNot gradedqualityBmaintenanceLocal-first cross-agent memory for AI coding agents. Persistent, shared memory over MCP — what you tell one agent can be recalled by another — with all data stored in a single local SQLite file, no cloud and no API keys.-
- AlicenseNot gradedqualityBmaintenancePersistent memory for AI coding agents that stores and recalls preferences, decisions, and conventions via semantic similarity, with zero cloud dependencies and plug-and-play MCP integration for Claude Code.Apache 2.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/asanabrial/leteo'
If you have feedback or need assistance with the MCP directory API, please join our Discord server