Skip to main content
Glama

Mnemolith: memory that stays true to your code

Mnemolith

Shared memory for AI coding tools that stays true to your code.

Mnemolith demo: a memory goes stale when docker-compose.yml changes, and the user records what is true now

Mnemolith (NEE-mo-lith): "memory stone." What your AI learns, carved where every tool can read it. (Why the name)

Formerly Aether Cache. If you installed aether-cache, see Moving from Aether Cache: your memories come with you.

Website · PyPI

Claude Code, Cursor, and other AI tools each forget your project between sessions, and when they do remember things, nothing checks whether those memories are still correct. Mnemolith gives every tool one shared, local memory, and keeps it honest:

  • Memories go stale when the code changes. Each memory is linked to the files it's about, with a snapshot of their git content hash. When docker-compose.yml changes, the memory about it is retired automatically instead of being fed to your AI forever.

  • Contradictions get replaced, not hoarded. "We migrated to MySQL" retires "we use Postgres" instead of sitting next to it and confusing the model. Near-identical repeats are merged.

  • Every memory can explain itself. Which tool and session saved it, which file versions it was based on, and every change since: created, seen again, went stale, confirmed, replaced.

  • It works with the files you already use. Current memories sync into a managed section of AGENTS.md and CLAUDE.md, so they're committed, reviewed in PRs, and visible to teammates who don't run Mnemolith.

It runs entirely on your machine, on top of a database engine I wrote from scratch.

Not a Redis clone

Mnemolith started as a from-scratch rebuild of Redis in Java, then kept going. Every layer here is written from scratch, and each one does something the layer beneath it can't:

Layer

What it adds

MCP server

Claude Code, Cursor, and any MCP tool share one memory

Git awareness

Memories retire themselves when the code they describe changes

Memory layer

Status, provenance, full history, duplicate merging, and conflict review, inside the engine

HNSW vector index

Semantic search: 99.4% recall at 0.84 ms on 100K vectors, 22× faster than exact search

Redis-compatible engine

RESP protocol, 50+ commands, replication, transactions, and crash-safe persistence (0 acknowledged writes lost across 1,039,890 writes and 8 kill -9 crashes), at 88–93% of real Redis's throughput

The bottom layer alone is a working Redis: redis-cli, redis-benchmark, and redis-py talk to it unchanged. The memory layer, git awareness, and MCP server are things Redis doesn't do at all.

Claude Code ─┐                       ┌─────────────────────────────────────────────┐
Cursor ──────┼─ MCP ─► mnemolith ─┼─ RESP ─► Java engine (Main.java)            │
other tools ─┘   (Python: embeddings,│          memories, HNSW vector index,       │
                  git hashing, sync) │          history, append-only file on disk  │
                                     └─────────────────────────────────────────────┘

Related MCP server: coding-memory-mcp

Does it help?

We tested it. Claude Code did 7 tasks in a sample codebase, 3 times each, in three setups. Every task needs something only a teammate would know: a past decision, who owns which code, a promise to a partner, a business rule. Two need a fact mentioned in an earlier session. An automatic check grades every run.

Setup

Tasks done right

Across sessions

Avg cost per task

No memory

43% (9 of 21)

3 of 6

$0.12

CLAUDE.md notes, same facts

90% (19 of 21)

4 of 6

$0.12

Mnemolith, same facts

100% (21 of 21)

6 of 6

$0.14

Without memory, Claude edited another team's code, changed a frozen partner API and skipped refund approval, every time. A CLAUDE.md file held the same facts but missed a database address mentioned in an earlier session 2 times out of 3; Mnemolith saved it on its own and used it next session. The cost is about 15% more per task than a notes file, at API prices, because recalling and keeping memories up to date takes a few extra turns. 63 runs on Claude Opus 5.5, November 2026. In an earlier round where every fact could also be found in the code, all three setups tied.

Run it yourself (uses your own Claude Code plan; see eval/ for what each task checks):

cd eval && python3 run.py --repeat 3 && python3 report.py

What it looks like

The dashboard (mnemolith ui): memories whose files changed wait for a decision, with the file versions side by side.

And from your AI tool's side, a memory linked to a file, the file changes, and the next lookup catches it:

> remember("The database runs Postgres via docker compose", files=["docker-compose.yml"])
Saved as m1.

        ... someone edits docker-compose.yml ...

> recall("database setup")
These memories were just retired because files they depend on changed. If one is still true,
call confirm_memory; if it's wrong, save the corrected fact with remember:
[m1] "The database runs Postgres via docker compose" is now marked outdated: docker-compose.yml changed.

> confirm_memory("m1")        # still true, so re-link it to the new version of the file
Confirmed m1; it's active again and linked to the current file versions.

> explain_memory("m1")
m1: "The database runs Postgres via docker compose"
status: active, project: demo
saved by: claude-code (session eea54b5c)
linked files: docker-compose.yml@02ea346...
history:
  19:16  created: by claude-code (session eea54b5c), linked to docker-compose.yml@87da641...
  19:16  active -> stale: docker-compose.yml changed since this was saved
  19:16  re-linked: to docker-compose.yml@02ea346... (confirmed still true)
  19:16  stale -> active: confirmed still true

A newer fact replacing an older one:

> remember("The API timeout was raised to 60 seconds")
Saved as m3.
Related existing memories:
[m1] (similarity 0.58) The API timeout is 30 seconds
If m3 makes any of these no longer true, call replace_memory(old_id, "m3"). Otherwise do nothing.

> replace_memory("m1", "m3")
m1 retired; m3 replaces it.

Quick start

One line installs everything and runs setup. On macOS or Linux:

curl -fsSL https://mnemolith.dev/install.sh | sh

On Windows (PowerShell):

powershell -ExecutionPolicy ByPass -c "irm https://mnemolith.dev/install.ps1 | iex"

The installer (install.sh, install.ps1) gets uv if you don't have it (uv brings Python), installs Mnemolith, and runs mnemolith setup. Prefer your own tools? Any of these works, followed by mnemolith setup:

uv tool install mnemolith
pipx install mnemolith
pip install mnemolith        # Python 3.10+

setup starts the engine in the background, downloads the embedding model once (about 90 MB), and connects every supported AI tool it finds on your machine: Claude Code, Claude Desktop, Cursor, and Codex. That's it. Open your AI tool in any git repo and try:

Remember that our tests need DOCKER_HOST set. It depends on docker-compose.yml.

Then start a new session and ask how to run the tests.

Only use Claude Code? You can install Mnemolith as a plugin instead, with no setup step (needs uv):

/plugin marketplace add anishchugh05/mnemolith
/plugin install mnemolith@mnemolith

The plugin (plugin/) runs the same server and adds a /mnemolith:dashboard command. Use the plugin or setup, not both, or Claude sees the tools twice.

The engine runs on Java 11+. If you have it, it's used. If you don't, Mnemolith downloads a private copy (about 50 MB) into ~/.mnemolith/java, checks it against its published checksum, and uses it only for Mnemolith; nothing is installed system-wide, and mnemolith uninstall removes it.

Already keep notes for your AI in CLAUDE.md, AGENTS.md, or Cursor rules? Run mnemolith import in the repo (or use Import notes in the dashboard) to turn them into memories, linked to the files they mention.

Memories are kept per project (the git repo's folder name), so projects never mix. Everything stays on your machine: the engine only accepts connections from it, and your memories live in ~/.mnemolith.

Command

What it does

mnemolith setup

One-time setup: engine, model, and AI tools

mnemolith add

Adds the repo you're in (or a path) so the dashboard can check its files; the dashboard can also find and add repos for you

mnemolith ui

Opens the dashboard: see what your AI remembers, and confirm, fix or retire memories whose files changed

mnemolith import

Turns the notes in CLAUDE.md, AGENTS.md, and Cursor rules into memories; shows them first and asks

mnemolith remove

Removes a project (default: the one you're in), like Remove project in the dashboard: its memories are retired, not deleted

mnemolith export

Saves memories, with their linked files and history, to a JSON file (-p for one project)

mnemolith status

Is it running, and what's in this project's memory

mnemolith doctor

Checks everything and tells you how to fix what's wrong

mnemolith list / recall "query" / explain m1

Look at memories from the terminal

mnemolith sync

Writes current memories into AGENTS.md / CLAUDE.md

mnemolith mender on / off

Turns Mender on or off; mnemolith mend drafts fixes for this repo now

mnemolith connect cursor

Connects one tool: claude-code, claude-desktop, cursor or codex (--print shows config for any other MCP tool)

mnemolith start / stop

Runs or stops the engine (it also starts on its own when a tool needs it)

mnemolith uninstall

Disconnects your AI tools, stops the engine, and asks before deleting memories

If mnemolith isn't found after installing, run uv tool update-shell and open a new terminal. Port 7380 taken? Set MNEMOLITH_PORT and run setup again. To uninstall: mnemolith uninstall, then uv tool uninstall mnemolith.

Mender: drafted fixes for stale memories

Flagging a stale memory is half the job: someone still has to work out what's true now and type it in. Mender, an optional part of Mnemolith, drafts that for you. mnemolith setup asks whether to turn it on; mnemolith mender on (or Settings in the dashboard) changes it later. It needs no API key and installs nothing extra.

  • Simple changes are drafted by plain rules, on your machine. Mender compares the version of each file the memory was saved against (from git) with the file now. image: postgres:16 became image: mysql:8, so "The database is Postgres (postgres:16 image)" becomes "The database is MySQL (mysql:8 image)". It handles version bumps, moved files (the path is updated, not treated as a deletion), and changes that don't touch the memory at all (only a comment, or lines it doesn't mention), which it suggests confirming as still true.

  • Everything else is drafted by the AI tool you already use. With Mender on, Claude Code, Cursor, and Codex get two more tools: list_stale shows each stale memory with what changed in its files, and propose_fix submits a draft. Drafts are checked against the code: quotes in the reason and new numbers or versions must actually be in the files, or the draft is marked Unverified.

  • You approve every change in the dashboard, where each draft sits under the diff it came from, with what it's based on. Approve it, edit it, or dismiss it. Approving is refused if the files changed again after the draft was made (it would be based on old code), and if the memory was already settled some other way.

Changed your mind? Approving shows an Undo, and any fix can be reverted later from the memory's details in the dashboard (Revert this fix) or with mnemolith mender revert m7: the old memory comes back for you to decide, and Mender won't suggest the same fix again unless the files change. mnemolith status and your AI tool tell you when fixes are waiting.

mnemolith mend drafts fixes for the repo you're in and lists them.

Moving from Aether Cache

Mnemolith used to be called Aether Cache. If you installed aether-cache, run the installer above. It installs Mnemolith, removes aether-cache, moves your memories from ~/.aether-cache to ~/.mnemolith, and reconnects your AI tools. Nothing is lost, and memories synced into CLAUDE.md / AGENTS.md are picked up where they are.

Installed some other way? Install mnemolith the same way, run mnemolith setup, then remove aether-cache (uv tool uninstall aether-cache, pipx uninstall aether-cache, or pip uninstall aether-cache).

Tools the AI can call

Tool

What it does

remember(fact, files?, replaces?)

Saves a durable fact, optionally linked to files. Merges near-identical repeats and shows related memories so the AI can decide whether the new fact replaces one; replaces="m42" saves it and retires m42 in one call.

recall(query, limit?)

Searches the project's memories by meaning. Checks linked files first, so it never returns a memory whose code changed underneath it.

explain_memory(id)

Where a memory came from and its full history.

replace_memory(old, new)

Retires an older memory that a newer one makes untrue.

mark_outdated(id, reason)

Retires a memory that turned out to be wrong.

confirm_memory(id)

Brings back a memory that's still true after its files changed, re-linked to the current versions.

check_stale()

Runs the file check on demand.

list_conflicts() / resolve_conflict(...)

Reviews pairs of very similar memories that may contradict each other.

sync_to_files()

Writes current memories into AGENTS.md / CLAUDE.md (also: mnemolith sync).

list_stale()

With Mender on: the stale memories, what changed in their files, and which already have a draft.

propose_fix(id, new_text?, reason?, still_true?, files?)

With Mender on: drafts a fix for the user to approve in the dashboard. Checked against the code before it's shown.

Design decisions, and what the measurements said

Similarity can't detect contradictions, so the AI judges

The first version flagged a new memory as a possible contradiction when it was similar to an existing one. Calibrating with real all-MiniLM-L6-v2 embeddings showed that can't work:

Pair

Kind

Similarity

"we use Postgres" / "the database is Postgres"

duplicate

0.73

"tests need DOCKER_HOST set" / "you have to set DOCKER_HOST before running tests"

duplicate

0.92

"we use Postgres" / "we migrated to MySQL"

contradiction

0.30

"API timeout is 30 seconds" / "API timeout is 60 seconds"

contradiction

0.94

"tests need DOCKER_HOST set" / "integration tests need a running Redis"

related, both true

0.34

Duplicates scored 0.73 to 0.92 and contradictions 0.30 to 0.94, so no threshold separates them. A threshold low enough to merge real duplicates would silently merge "timeout is 30s" with "timeout is 60s", the worst bug this product could have. So the engine only auto-merges near-identical text (similarity ≥ 0.97). For everything else, embeddings find the related memories and the AI, which already understands the sentences, decides whether one replaces another.

Staleness compares file contents, not commits

Each linked file is stored as path@<git blob hash>, computed with git hash-object. Comparing contents rather than commit ids catches uncommitted edits, ignores commits that didn't touch the file, and needs no git hooks: recall re-hashes the handful of linked files before every search.

Memories never mutate silently

Every change is a logged event with a timestamp and a reason. The engine logs each memory with the id and timestamp it assigned, so replaying the log after a restart rebuilds the exact same memories and histories, down to the millisecond, instead of minting new ones.

The engine underneath

A Redis-compatible server written from scratch in Java. It speaks RESP, so redis-cli, redis-benchmark, and redis-py work with it unchanged. The core was built by completing every stage and extension of the CodeCrafters "Build Your Own Redis" challenge; the vector index, persistence hardening, and the memory layer are my own additions.

progress-banner

Throughput vs. official Redis

redis-benchmark -t set,get, 100K requests, 50 parallel clients, 3-byte values, same machine:

Mnemolith

Redis 8.10.2

Mnemolith as % of Redis

SET

205.8K ops/sec

233.6K ops/sec

88%

GET

225.7K ops/sec

242.7K ops/sec

93%

p50 latency

0.119 ms

0.111 ms

p99 latency (SET / GET)

0.375 / 0.231 ms

0.359 / 0.159 ms

max latency (SET)

19.7 ms

1.3 ms

JVM GC / JIT pauses

Typical latency is on par with Redis. The gap is in worst-case latency, from JVM garbage collection and JIT warm-up, which Redis (written in C) doesn't have.

100,000 AG News headlines embedded with all-MiniLM-L6-v2 (384 dimensions, cosine similarity), 500 held-out queries, k = 10. Recall is measured against exact brute-force search on the same data.

Mode

Recall@10

p50 latency

p99 latency

Exact (brute force)

1.000

18.58 ms

20.52 ms

HNSW, ef=10

0.905

0.49 ms

1.38 ms

HNSW, ef=20

0.951

0.52 ms

0.73 ms

HNSW, ef=50

0.985

0.66 ms

0.89 ms

HNSW, ef=100

0.994

0.84 ms

1.41 ms

HNSW, ef=200

0.998

1.24 ms

2.19 ms

At ef=100, HNSW returns 99.4% of the true top-10 about 22× faster than exact search. Building the index for 100K vectors took 136 seconds (M=16, M0=32, efConstruction=200). Latencies are measured from the Python client, so they include network and client overhead. Full setup and raw numbers: results.json.

How it works: each vector links to its nearest neighbors in a layered graph. A search starts on a sparse top layer of long-range links, hops greedily toward the query, drops down a layer at a time, and finishes with a best-first search on the bottom layer that keeps the ef best candidates. Neighbor selection uses the diversity heuristic from the HNSW paper (prefer neighbors in different directions over near-duplicates), which is what keeps recall high.

Filtered search: HNSW doesn't know about memory status, so searches over-fetch candidates, drop the ones that don't match (stale or superseded), widen the search if too few survive, and fall back to an exact scan if needed. In a test with 2,000 memories where only 2% were active, filtered searches returned exactly the correct top 10 on 30/30 queries. The catch: at that selectivity, the exact fallback runs most of the time, which is the known weak spot of post-filtering on graph indexes.

Crash safety

Every write goes to an append-only file (AOF) that is replayed on startup.

kill -9 crash test (crash_test.py): a client writes as fast as it can, the server is killed at a random moment, restarted, and every write the server acknowledged is checked.

fsync policy

Crashes

Acknowledged writes

Lost

everysec

5

757,295

0

always

3

282,595

0

Recovery took 0.6 seconds per restart, replaying up to ~185K writes.

Torn writes: a machine crash can cut the last write off halfway. The first version refused to start on such a file; now replay stops at the last complete command, trims the partial one, and starts normally with all earlier data intact.

Cost of each fsync policy (SET throughput, 50 clients):

Policy

Throughput

p50 latency

always (sync every write)

42.9K/sec

1.159 ms

everysec (sync once a second)

113.9K/sec

0.103 ms

no (let the OS decide)

118.8K/sec

0.103 ms

everysec is 2.7× faster than always and within 4% of no, which is why it's the sensible default. On macOS, fsync doesn't force the SSD's own cache to flush, so always looks cheaper here than it would on a Linux server.

Full command list

  • Memory:

    • MEM.ADD, MEM.GET, MEM.SEARCH (with STATUS filter), MEM.STATUS, MEM.WHY, MEM.LIST

    • MEM.FILES, MEM.SEEN, MEM.CONFLICTS, MEM.RESOLVE

  • Vectors: VADD, VSEARCH (HNSW, tunable EF, EXACT mode)

  • Strings: GET, SET (EX / PX), INCR, STRLEN, TYPE, KEYS *

  • Lists: RPUSH, LPUSH, LRANGE, LLEN, LPOP, blocking BLPOP

  • Streams: XADD (explicit, partial, and auto IDs), XRANGE, XREAD (with BLOCK and $)

  • Sorted sets: ZADD, ZRANK, ZRANGE, ZCARD, ZSCORE, ZREM

  • Bitmaps: SETBIT, GETBIT, BITCOUNT, BITOP AND / OR (binary-safe strings)

  • Geospatial: GEOADD, GEOPOS, GEODIST, GEOSEARCH ... FROMLONLAT ... BYRADIUS

  • Transactions: MULTI, EXEC, DISCARD, WATCH, UNWATCH (optimistic locking via per-key write versions)

  • Pub/Sub: SUBSCRIBE, UNSUBSCRIBE, PUBLISH

  • Replication:

    • Master–replica handshake (PING, REPLCONF, PSYNC) and command propagation

    • REPLCONF GETACK offset tracking and WAIT

  • Persistence: RDB loading; AOF with a manifest, appendfsync always / everysec / no, and torn-write recovery

  • Auth: AUTH, ACL WHOAMI / GETUSER / SETUSER (SHA-256 password hashes)

Running the engine on its own

java src/main/java/Main.java                                   # port 6379
java src/main/java/Main.java --bind 127.0.0.1                  # accept connections from this machine only
java src/main/java/Main.java --port 6380 --replicaof "localhost 6379"
java src/main/java/Main.java --dir /tmp/data --appendonly yes --appendfsync everysec

Reproducing the benchmarks

Each benchmark runs against the engine you've started:

redis-benchmark -p 6379 -t set,get                 # throughput; also run against redis-server to compare
python vector_bench.py                             # HNSW recall and latency (start the engine with -Xmx4g)
python crash_test.py everysec 5                    # kill -9 crash test
python memory_mcp/calibrate.py                     # embedding similarity calibration

Mnemolith is an early, open-source project. These are the production systems in the same space:

Roadmap

What's coming next, roughly in order. Ideas and pushback are welcome in GitHub issues.

Next: team memory (December to February)

  • Shared memory for a repo. Each person keeps their own memories, and each repo gets one shared team memory that every teammate's AI reads. You promote a memory to the team explicitly, so nothing gets shared by accident.

  • Reviewed like code. Team memories live in the repo as plain files. Mnemolith writes the file; you commit it and open the pull request yourself, so teammates review a change to team knowledge the same way they review code. Git history is the audit trail, and access follows repo permissions. Mnemolith never commits on its own.

  • Stale memories flagged in pull requests. A GitHub Action comments when a pull request changes files that team memories depend on, so outdated knowledge gets caught in review.

Then: memory for any folder (early 2027)

  • Memories for folders that aren't code, tied to PDFs, Word files and spreadsheets, and flagged when those change, so people who aren't developers can use it too.

  • Later, a desktop app that installs like any other app, with no terminal needed.

Always: the local version stays free and open source.

Status and limitations

Mnemolith is v1 and early. It works end to end in automated tests and is now being tried in real Claude Code sessions.

Not done yet:

  • An evaluation on real-world repos. The evaluation above uses a small sample codebase built for it; real projects are bigger and messier.

  • Lower overhead: recalling and keeping memories up to date costs about 15% more per task than a notes file.

  • AOF compaction: the log only grows, and every status change adds a line.

Engine limitations:

  • Threading: one OS thread per connection, not an event loop. That's fine for a local tool, but it won't scale to thousands of clients like Redis.

  • Transactions: EXEC isn't isolated, so other clients' commands can interleave with a transaction's commands.

  • Vector index: re-adding a vector updates it without rewiring its graph links, and there's no delete. Retired memories are filtered out, not removed.

  • Replication: full resync only, and a new replica assumes the master's dataset is empty.

  • Smaller gaps:

    • KEYS * lists only string keys.

    • GEOSEARCH scans every member.

    • ACL supports only the default user.

    • HELLO (RESP3) isn't supported, so clients must use RESP2.

Project layout

src/main/java/Main.java      the engine (single file, from the CodeCrafters setup)
mnemolith/                   the Python package behind the `mnemolith` command
  server.py                  MCP server: embeddings, git staleness, AGENTS.md/CLAUDE.md sync
  engine.py                  finds Java, starts and stops the engine in the background
  javart.py                  downloads a private copy of Java when the computer has none
  connect.py                 registers Mnemolith with Claude Code, Claude Desktop, Cursor, and Codex
  cli.py                     the `mnemolith` command
  ui.py, ui/index.html       the dashboard (`mnemolith ui`): a local server, its API, and the page
  mender.py                  Mender: rule-drafted fixes, drafts from AI tools, and the guarded approve
  portability.py             import from notes files, export to JSON
  engine/mnemolith-engine.jar the prebuilt engine (rebuild with `python scripts/build_engine.py`)
tests/test_mender.py         Mender's rules (`python -m pytest tests`)
eval/                        with-vs-without memory evaluation on a sample codebase (`python3 eval/run.py`)
plugin/                      the Claude Code plugin (listed through .claude-plugin/marketplace.json)
memory_mcp/calibrate.py      similarity calibration for duplicate/contradiction thresholds
vector_bench.py              HNSW benchmark (writes results.json)
crash_test.py                kill -9 crash-safety test

Releasing

Bump the version in pyproject.toml, mnemolith/__init__.py, and server.json, commit, then:

git tag v0.3.4 && git push --tags

Once the release is on PyPI, point the Claude Code plugin at it: bump the version in plugin/.claude-plugin/plugin.json and plugin/pyproject.toml, run uv lock in plugin/, then commit and push. The plugin can't move first, because its lockfile needs the new release to exist.

The release workflow checks the versions match, builds and smoke-tests the package, publishes it to PyPI and the MCP Registry, and creates the GitHub Release.

License

MIT. See LICENSE.

Available Tools

10 tools
check_staleA

Check whether any memory's linked files have changed since it was saved, and retire those memories. recall already does this automatically; call it directly after big changes.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It does disclose a destructive effect ("retire those memories") and that recall duplicates this behavior implicitly, which is valuable. But it never defines what retirement means (deletion vs. flagging vs. mark_outdated), nor whether the check is report-only, leaving real ambiguity about consequences.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, with the action and its scope front-loaded before the sibling cross-reference. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description covers purpose, triggering condition, and the sibling overlap. The only shortfall is the undefined semantics of "retire," which matters for a mutating, no-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter meaning to convey; the description correctly explains the implicit scope (all memories with linked files) instead of inventing arguments. Baseline 4 applies for a parameterless tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: check whether a memory's linked files changed since save, then retire those memories. It also names the sibling that performs the same work (recall), so an agent can separate it from the 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit condition for calling it ("directly after big changes") and names the alternative (recall does this automatically). The phrasing is slightly ambiguous about why to call it at all if recall is automatic, but the when-to-use signal is present and concrete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

confirm_memoryA

Mark a memory as still true (e.g. after it was retired because a linked file changed, but the fact itself didn't). Re-links it to the current version of its files.

NameRequiredDescriptionDefault
memory_idYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses a side effect beyond the name — it re-links the memory to the current version of its files — but says nothing about required permissions, reversibility, or what happens to conflicting/stale links.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action and followed by the qualifying scenario and the side effect. No filler, though the parenthetical adds a level of nesting that slightly slows reading.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists, so return values need not be described, and the tool is a simple single-parameter mutation. However, with zero annotations the description should cover more of the mutation's behavior — permissions, reversibility, or how re-linking interacts with check_stale/sync_to_files — to be fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

One required parameter with 0% schema description coverage, and the description never mentions it. The parameter is a single self-evident identifier ('memory_id') for the memory being confirmed, so the gap is small, but no format or sourcing guidance is added.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Mark a memory as still true') and clarifies the state transition being reversed (retired when a linked file changed). This implicitly contrasts with mark_outdated and replace_memory, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical supplies a concrete trigger condition — use it after a memory was retired because a linked file changed but the fact itself didn't. It does not state the inverse case (when the fact is no longer true, use mark_outdated) or name alternatives, so it stops short of a full when/when-not routing guide.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explain_memoryA

Show where a memory came from (which tool and session saved it, which files it's linked to) and everything that has happened to it since. Use it when a memory looks wrong or surprising.

NameRequiredDescriptionDefault
memory_idYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. The naming ('explain', 'show') strongly implies a read-only inspection, and the description discloses the two categories of information returned (origin and subsequent history), but it never states read-only semantics, whether any state changes, or permission needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core purpose and closing with the usage cue. No filler or restated name/title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return structure need not be explained, and the description already says what is surfaced. For a one-parameter read tool this is nearly complete; only the read-only guarantee and memory_id format are missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single memory_id parameter, so the description should compensate and does not — it says 'a memory' with no hint about ID format or how to obtain one. The parameter is self-describing enough ('memory_id', title 'Memory Id') that the gap is mild rather than fatal.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'show where a memory came from' plus 'everything that has happened to it since'. This clearly separates it from siblings like recall (retrieval) or check_stale (staleness), though it never names an alternative explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete triggering condition: 'Use it when a memory looks wrong or surprising.' That is real when-to-use guidance, but there is no when-not guidance and no named alternative for related diagnostic tasks such as list_conflicts or check_stale.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_conflictsA

List pairs of memories in this project that may contradict each other and need a decision.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. 'List' implies a read-only operation, which is a reasonable signal, but the description does not confirm non-mutation, disclose whether results are ranked or filtered, or say anything about the decision workflow the pairs feed into.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the verb, and every clause adds scope or intent. No filler or restated title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return structure need not be explained. The description covers scope and intent adequately for a zero-param lister, though it could have named resolve_conflict to complete the workflow picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description correctly signals that scoping is implicit (current project) rather than parameterized.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (pairs of memories that may contradict each other), with the scope confined to 'this project'. It implicitly distinguishes itself from resolve_conflict by framing the output as items that 'need a decision', though it does not name that sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'need a decision' hints that this is a discovery step preceding resolve_conflict, but the description never states when to call this versus resolve_conflict or check_stale. Usage is implied rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mark_outdatedA

Mark a memory as no longer true, with a short reason. It stops counting as current but keeps its history. If you know what's true now, save that with remember(..., replaces=) instead, so the next session knows the new fact, not just that the old one is wrong.

NameRequiredDescriptionDefault
reasonYes
memory_idYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden and does disclose the key trait: the memory stops counting as current but retains history, i.e. a soft deprecation rather than a delete. It also implies a reason is mandatory. It stops short of saying whether the action is reversible, whether the record still appears in recall, or what permissions are needed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and its effect before the alternative. The closing rationale ("so the next session knows the new fact, not just that the old one is wrong") is slightly expansive but justifies the routing advice rather than padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description covers effect plus the main alternative for a two-parameter mutation. Gaps remain around reversibility and how an outdated memory behaves in later recall or conflict resolution, which matters given the absence of annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for both parameters. It adds meaning for reason ("a short reason") and clarifies memory_id indirectly via the "replaces=<this id>" reference, but never says where the id comes from or what form it takes.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Mark a memory as no longer true") plus the scope of the effect ("stops counting as current but keeps its history"). That effect statement cleanly separates it from destructive siblings like replace_memory and from the forward-looking remember.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit routing rule: if you know what's true now, use remember(..., replaces=<this id>) instead. It names the alternative tool, the parameter to use, and the condition that selects it, so the agent does not have to infer when this tool is the wrong choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recallA

Search this project's shared memory by meaning. Call it at the start of every task, and whenever project-specific knowledge (setup, conventions, past decisions) might matter. Current (active) memories come first. Related memories that were retired, replaced, or may be outdated are listed after them, labeled, so you know what changed: never rely on those.

NameRequiredDescriptionDefault
limitNo
queryYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does real work: it discloses result ordering (active memories first, then retired/replaced/outdated ones, labeled) and warns "never rely on those." That's meaningful behavioral context an agent cannot get from the schema; it stops short of stating it is a read-only operation or how the limit affects results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, then trigger conditions, then result-ordering behavior. Sentences are dense but each carries information; the ordering/caveat sentence is slightly long but earns its length by preventing misuse of stale results.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return format needn't be restated, and the description covers scope (this project), usage timing, and result semantics including stale entries. The only gap an agent still faces is the meaning/effect of the limit parameter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must explain both parameters. "By meaning" usefully tells the agent the query is natural-language/semantic rather than keyword syntax, but the limit parameter (default 5) is never mentioned in either place.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Search this project's shared memory by meaning" gives a specific verb (search) plus resource (project shared memory) and modality (semantic, not keyword). It doesn't explicitly name a contrasting sibling such as remember or list_conflicts, so the read-vs-write distinction is inferable rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete triggers: "at the start of every task" and "whenever project-specific knowledge (setup, conventions, past decisions) might matter." It does not state when to prefer a sibling (e.g., explain_memory or list_conflicts) instead, so routing guidance is one-sided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rememberA

Save a durable fact about this project so future sessions, in any AI tool, know it. Use this, not a built-in memory or notes file, whenever the user asks you to remember something about the project.

Good facts: conventions ("we use pnpm, not npm"), setup gotchas ("tests need DOCKER_HOST set"),
decisions and their reasons. Not: temporary task details or anything in the code already.
files: repo-relative paths this fact depends on (e.g. ["docker-compose.yml"]), so the memory
can be flagged when those files change.
replaces: the id of a memory this fact makes untrue (e.g. "m42"), to save and retire it in one call.
NameRequiredDescriptionDefault
factYes
filesNo
replacesNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description bears the full burden of behavioral disclosure. It explains the operational implications of the `files` parameter (flagging when changed) and the `replaces` parameter (retiring old memories).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The information is well-structured, moving from the high-level purpose to usage guidelines and then drilling down into specific parameter semantics. No sentence is wasted, and the scope definition is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is complex due to its metadata requirements (`files`, `replaces`). The description covers all necessary context for an agent to choose this tool over siblings and invoke it with correct semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Since schema description coverage is 0%, the description must compensate. It perfectly explains the semantic meaning of all three parameters, detailing what 'files' means (repo-relative paths) and what 'replaces' refers to (memory ID).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the goal: to save a 'durable fact' for future sessions and distinguishes this function from built-in memory or notes files.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit guidelines on when to use the tool (conventions, setup gotchas, decisions) and, critically, when *not* to use it (temporary task details or code content).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

replace_memoryA

Retire an older memory because a newer one replaces it (e.g. "we use Postgres" replaced by "we migrated to MySQL"). The old memory stops showing up in recall but keeps its history.

NameRequiredDescriptionDefault
new_idYes
old_idYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses that the old memory disappears from recall but retains its history, which is the key non-destructive/retirement behavior an agent needs. It still omits whether the operation is reversible, what happens if new_id doesn't exist, and permission requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the core action, and the parenthetical example earns its place by disambiguating the semantics. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and the behavioral effect is covered. However, for a mutation-style tool with zero annotations and two undocumented required ID parameters, the description leaves an agent guessing about ID provenance and irreversibility.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and both required parameters are undocumented titles ('Old Id', 'New Id'). The description implies the old/new relationship but never states that these are memory identifiers, nor any format or validity constraints, so it only partially compensates for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Retire an older memory') plus the causal condition that defines it ('because a newer one replaces it'), with a concrete example. This distinguishes it from siblings like mark_outdated, which retires a memory without a superseding replacement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The selection condition is clear and concrete: use this when a newer memory supersedes an older one, and the Postgres/MySQL example makes the scenario unambiguous. It does not explicitly name mark_outdated as the alternative for retiring without a replacement, nor state exclusions, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_conflictA

Settle a possible conflict. replaces_old=True: the new memory replaces the old one (the old one is retired). replaces_old=False: both are true, keep both. Ask the user if you're not sure.

NameRequiredDescriptionDefault
new_idYes
old_idYes
replaces_oldYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses the destructive outcome of replaces_old=True ('the old one is retired') and the non-destructive alternative, but says nothing about reversibility, permissions, error behavior, or whether other memories referencing the retired one are affected.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tight and front-loaded: the core action comes first, then the two flag branches, then the escalation rule. No filler sentences, though the value-branch phrasing is slightly terse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the acceptance/rejection semantics of the boolean are covered. The main omission is any prerequisite about how a conflict is identified before calling this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It fully explains the pivotal boolean replaces_old with both branches, which is the hardest parameter; however, new_id and old_id are left entirely undocumented and their roles are only inferable from their names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('settle') and resource ('a possible conflict'), and the flag semantics make the outcome unambiguous. It does not explicitly differentiate itself from siblings like list_conflicts or replace_memory, so the agent must infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Ask the user if you're not sure' gives a useful uncertainty rule, and the tool is implied to be used when a conflict is detected. However, it never names which sibling to use instead (e.g. list_conflicts to find conflicts, replace_memory for a straight replacement), leaving the routing decision to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sync_to_filesA

Write this project's current memories into the managed section of AGENTS.md / CLAUDE.md, so they're committed with the code: teammates and tools without Mnemolith see them, and changes show up in reviews. Call it when the user asks, or after a batch of new memories.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden, and it does disclose meaningful behavior beyond the name: it writes into a 'managed section' (implying it won't clobber unrelated file content), the result is committed with code, visible to teammates and tools lacking Mnemolith, and surfaces in reviews. It omits auth/permission requirements and whether it overwrites prior content, keeping it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the action and destination before the effect and the when-to-call clause. Every clause contributes; it is marginally verbose but not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With zero parameters and an output schema present, the description needn't explain return values, and it adequately covers what it does, where it writes, the blast radius, and when to invoke it. Only permission/overwrite semantics are left unspecified, a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. No parameter-level gaps exist to compensate for.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (write/sync) plus the resource (this project's current memories) and the exact destination artifact (the managed section of AGENTS.md / CLAUDE.md). An agent can distinguish this file-writing sync from sibling memory operations like remember, recall, and replace_memory without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to call it: 'when the user asks, or after a batch of new memories.' This is clear triggering context, though it names no exclusions or alternative sibling (e.g., when to prefer remember or replace_memory instead).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.3.4
    • Changedremember1 field changed
      • addedInput schema / properties / replaces
        Added value: +{
        +  "default": "",
        +  "title": "Replaces",
        +  "type": "string"
        +}
  2. 10 tool updates
    • First observedcheck_stale
    • First observedconfirm_memory
    • First observedexplain_memory
    • First observedlist_conflicts
    • First observedmark_outdated
    • First observedrecall
    • First observedremember
    • First observedreplace_memory
    • First observedresolve_conflict
    • First observedsync_to_files

TDQS

A3.9/5.0

Scored across 10 tools

Disambiguation3/5

Several tools retire or supersede memories: mark_outdated, replace_memory, and resolve_conflict (with replaces_old=True) all end a memory's active life, and remember(replaces=...) overlaps with replace_memory. The descriptions do cross-reference each other to steer the agent, but the boundaries between 'mark outdated', 'replace', and 'resolve conflict' require careful reading rather than being self-evident.

Naming Consistency4/5

Almost all tools follow a clean snake_case verb_noun pattern (list_conflicts, resolve_conflict, mark_outdated, check_stale, confirm_memory, explain_memory, replace_memory, sync_to_files). The two bare verbs (remember, recall) are canonical memory terms and remain readable, so this is only a minor deviation.

Tool Count5/5

Ten tools is well within the ideal range and each covers a distinct lifecycle stage of the memory domain: capture, recall, provenance, staleness, confirmation, conflict handling, and file sync. Nothing feels padded or missing at the count level.

Completeness4/5

The surface covers the full memory lifecycle — write (remember), read (recall, explain_memory), update (confirm_memory, replace_memory), retire (mark_outdated), maintain (check_stale, list_conflicts, resolve_conflict), and export (sync_to_files). The main gap is that recall is meaning-based only, with no plain list/get-by-id tool, which could make targeted inspection of a known memory awkward.

Maintenance

ActivityNo data
ResponsivenessOutdated data

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides a local long-term memory layer for AI coding tools like Cursor and Claude Code, enabling cross-session, cross-tool sharing of project facts, user preferences, decisions, and workflows.
    21 npm
    2
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Portable AI memory that roams with you across models and harnesses — one shared memory for Claude Code, Codex, Cursor, Gemini CLI and more, stored as plain markdown files you own. Per-project spaces plus a shared layer, vault-wide search; runs locally over stdio/HTTP or hosted with OAuth 2.1 backed by your own GitHub repo.
    33 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    One local memory every coding agent on your machine shares — Claude Code, Cursor, Claude Desktop, OpenCode. Answers from past sessions, commits, CLAUDE.md/AGENTS.md and ADRs with the exact source, and withholds work another agent has claimed so two agents don't rewrite the same thing.
    3
    4,617 PyPI
    1
    MIT