ctxkeeper
A local-first MCP server for durable project memory and token-budgeted context retrieval.
Get a session-start
project_briefwith stack, commands, files to read first, git state, TODOs, decisions, gotchas, and recent work.Save durable memories as decisions, gotchas, facts, commands, todos, or notes, with tags, related files, importance, and project/global scope.
Search saved memories with keyword/CJK-aware
recall, filtered by type, tag, scope, done/archived status.Archive or restore memories with
forget.Manage a durable project todo list: add, list, mark done, or reopen items.
Log completed work with summary, files, commands, outcome, next steps, and duration.
Generate a token-budgeted
context_packof relevant code excerpts withpath:linecitations plus matching memories.Inspect server/project status, detected root, store paths, counts, git state, and limits.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ctxkeeperpull the project brief and open TODOs so I can get up to speed"
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.
ctxkeeper is a local-first MCP server that gives AI coding agents durable project memory and token-budgeted context packs.
No API keys. No vector database. No telemetry. One node process, one append-only file.
Agent → project_brief
← stack · run/test commands · files to read first · git state
open TODOs · decisions · gotchas · recent work ~1.2k tokens
Agent → context_pack("where is the OAuth token refreshed?")
← src/auth/refresh.ts:42-78 + the decision that explains it ~1.5k tokens
Agent → remember(type="gotcha", ...) # survives the session
Agent → log_work(summary=..., next_steps=...) # hands off to tomorrowThe problem
Every new agent session starts cold:
You re-explain the architecture, the constraints, and the command that actually runs the tests.
The agent greps the repo, reads whole files, and burns thousands of tokens to find 30 lines.
Decisions and gotchas live in yesterday's chat, not in the project.
Switch from Claude Code to Cursor to OpenCode and all context is gone again.
Most MCP servers add more tools. ctxkeeper makes the tools you already have need less context.
Related MCP server: Turbovec MCP Server
What you get
Tool | R/W | What it does |
| read | Stack, commands, files to read first, git, TODOs, decisions, gotchas, recent work — one call |
| read | Given a concrete question, returns only the relevant code windows ( |
| read | Keyword + CJK-aware search over saved memories, ranked by field, importance, and recency |
| write | Persist a decision, gotcha, fact, command, todo, or note; identical entries are deduplicated |
| write | Durable add / list / done / reopen across sessions |
| write | Archive a memory; |
| write | Timestamped work log: summary, files, commands, outcome, next steps |
| read | Detected root, store paths, counts, git state, limits |
Also exposed: resource ctxkeeper://brief, prompt onboard, and server instructions that describe the workflow at handshake time.
Why another MCP server?
The ecosystem has plenty of connectors. The 2026 survey data shows ~47k active servers in the official registry, but the scarce layer is context:
Layer | Examples | Supply |
L1 Connect | filesystem, GitHub, browser, databases, SaaS | saturated |
L2 Operate | deploy, open PRs, update tickets | crowded |
L3 Domain workflow | finance, legal, recruiting | scarce, data-gated |
L4 Context | remember the project, pick the right lines, budget tokens, hand off | underserved |
ctxkeeper is deliberately L4. It does not replace your GitHub or Playwright server; it reduces how often the agent needs them.
Design choices that follow from that:
Append-only JSONL, not a database. No native build, crash-tolerant, multi-client friendly, auditable, and
forgetis reversible.Memory bridges language. A Chinese question can retrieve English code: memories contribute file paths and identifiers (e.g.
refreshToken) as bridge terms for window selection.Code blocks are never cut in half. Each file gets a budget; if it does not fit, use the single best window or skip it and say so.
Read-only by construction. No arbitrary shell. The only subprocess is fixed-argument, read-only
git.Sensitive files never enter context.
.env*, keys, credentials, and common token shapes are skipped or redacted.
Quick start
Requires Node.js >= 20.11.
git clone https://github.com/Coisini-cyber/ctxkeeper-mcp.git
cd ctxkeeper-mcp
npm install # also builds via the prepare script
npm test # 11 end-to-end tests over real stdio
npm run demo -- . "how does the store work"demo prints status, project_brief, and one context_pack, so you can judge the output quality before wiring it into a client.
No clone? Point your MCP client at the repository directly (it builds on first run):
npx -y github:Coisini-cyber/ctxkeeper-mcpRunning that in a terminal will look like it hangs — it is a stdio server waiting for a client.
The same binary is also a small CLI, useful for checking output without an MCP client:
node dist/index.js --brief
node dist/index.js --pack "where is the token refreshed?"
node dist/index.js --doctorConnect to OpenCode
Add this to your global config, ~/.config/opencode/opencode.json (on Windows: C:\Users\<you>\.config\opencode\opencode.json):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"ctxkeeper": {
"type": "local",
"command": ["node", "/absolute/path/to/ctxkeeper-mcp/dist/index.js"],
"enabled": true,
"timeout": 20000
}
}
}Do not set cwd: the server detects the project root from the workspace, so one entry works in every repository.
If you prefer not to clone, use "command": ["npx", "-y", "github:Coisini-cyber/ctxkeeper-mcp"]. It builds on first run and is slower to start; the local path is recommended for daily use.
Verify:
opencode mcp list
# ✓ ctxkeeper connectedTools appear as ctxkeeper_project_brief, ctxkeeper_context_pack, and so on.
For project-only setup, put the same mcp block in the repository's opencode.json.
Any other MCP client
{
"mcpServers": {
"ctxkeeper": {
"command": "node",
"args": ["/absolute/path/to/ctxkeeper-mcp/dist/index.js"]
}
}
}Step-by-step configs for Claude Code, Claude Desktop, Cursor, VS Code, and Windsurf: docs/clients.md.
Make the agent actually use it
Different clients weight server instructions differently. Add a hard rule to your AGENTS.md / CLAUDE.md:
## Project memory (ctxkeeper)
- At the start of every session, call `ctxkeeper_project_brief` before reading files or grepping.
- To locate code, call `ctxkeeper_context_pack` with a concrete question, then read only the cited `path:line` ranges.
- Save confirmed decisions and gotchas with `ctxkeeper_remember`; track multi-step work with `ctxkeeper_todo`.
- Before finishing, call `ctxkeeper_log_work` with what changed, files touched, and next steps.
- Never store secrets, tokens, or full source files in memories.A real project_brief
Abridged output from this repository after a day of work:
# Project brief: ctxkeeper-mcp
D:\mcp\ctxkeeper · no git · 2026-11-02 13:44
stack: TypeScript 88% · JavaScript 12% · 17 files · ~2.9k LOC
read first: `src/index.ts`, `README.md`
## Commands
- build: `npm run build`
- test: `npm run test`
- demo: `npm run demo`
## Open TODOs (2)
- [m_mvzb4ptlyn1kf] **Add an incremental file index** — avoid a full scan on every pack
- [m_mvzb4pug8vf7k] **Compact the event log** — snapshot + tail after tens of thousands of events
## Decisions (4)
- [m_mvzb7yweonhbc] **Bridge Chinese questions to English code** — memories contribute file paths and identifiers
- [m_mvzb4psxlo7qq] **Read-only code access, skip sensitive files** — no arbitrary shell; redact high-confidence secrets
- [m_mvzb4ps1k9vm8] **Never truncate a code block mid-line** — fall back to the best window or skip
## Gotchas (1)
- [m_mvzb4prdcpo9j] **The user's home directory is a git repo** — never adopt home/temp as the project root
## Recent work
- 2026-11-02 [success] Shipped ctxkeeper: event-sourced memory, brief, context pack, 11 e2e tests
· next: incremental index; event-log compaction; one-week field testThat is the entire onboarding for a new session.
Measured on this repo
Small repo, Windows 11, Node 22.23 — a pipeline check, not a benchmark:
Operation | Latency | Output |
| ~10 ms | 0.5–1.2k tokens |
| ~8–10 ms | ~1.0k tokens, 2–4 cited windows |
Reading | — | ~3.5–4k tokens |
The gap grows with file size: context_pack returns the 30 lines around the answer, not the 430-line file.
How memory is stored
project/
├─ src/
├─ package.json
└─ .ctxkeeper/ # created automatically
├─ .gitignore # contains "*" — memories are not committed
└─ events.jsonl # append-only event logEvery write is an event: memory.add, memory.archive, memory.unarchive, todo.set, worklog.add. Reads replay the log. This avoids native dependencies, survives crashes, lets multiple clients append safely, and makes archiving and completion reversible.
Global memories (cross-project preferences) live in ~/.ctxkeeper/global/.
Security and privacy
No network calls. No accounts, keys, telemetry, or cloud storage.
Read boundary: only text files inside the detected project root; skip
node_modules,.git,dist,build,target, virtualenvs, and similar.Sensitive files:
.env*,*.pem,*.key,id_rsa*,credentials,secrets.*are excluded from code search.Redaction: private key blocks,
sk-…,ghp_…,AKIA…,xox…are redacted from output.No arbitrary execution. The only subprocess is read-only
gitwith fixed arguments.Caveat: the store is plain text. Do not save secrets. Treat repository content as untrusted data, not instructions.
See SECURITY.md for reporting.
Configuration
Environment variable | Default | Purpose |
| auto-detected | Force the project root (absolute path) |
|
| Project memory directory |
|
| Global memory directory |
|
| Max size of a file read into context |
| unset | Set to |
Root detection order: CTXKEEPER_ROOT → nearest .ctxkeeper or project manifest (package.json, pyproject.toml, Cargo.toml, go.mod, …) → nearest .git (home and temp directories are never adopted) → cwd.
Limitations
Retrieval is lexical (identifiers + CJK bigrams), not embeddings. Try different keywords if
recallmisses.Large repositories are capped at 6,000 files / 24 MB per scan.
The event log does not compact itself yet.
No team sync, encryption, or per-user permissions. Built for individuals and small teams.
Memory quality depends on write quality: short titles, concrete content, file paths.
Roadmap: incremental index → event-log compaction → optional local embeddings with lexical fallback → “recently changed files → related memories” in the brief.
See docs/alternatives.md for an honest comparison with AGENTS.md, the official Memory server, mem0/Letta, Graphify/Serena, and Context7. See docs/research.md for the full 2026 MCP landscape and why this layer is underserved. docs/architecture.md explains the event log, retrieval pipeline, and extension points.
FAQ
Does it work with Claude Code / Cursor / Windsurf? Any client that supports local stdio MCP servers can run it. The examples use OpenCode, but the server itself has no client-specific code.
Does it replace AGENTS.md / CLAUDE.md?
No. Those are static instructions you maintain by hand. ctxkeeper adds dynamic project state (decisions, gotchas, TODOs, recent work) and retrieves only the relevant parts.
Does my code leave the machine? No. There are no network calls, no accounts, and no telemetry. Code excerpts are read locally and returned to the client you already use.
Why not embeddings? v0.1 deliberately trades semantic recall for zero install friction and offline operation. Lexical retrieval plus identifier/CJK tokenization covers concrete questions; an optional local embedding backend is on the roadmap.
Is the memory committed to git?
No. .ctxkeeper/.gitignore contains *, so the store stays local by default. Delete that file if you want to commit curated memories.
How large a repo can it handle? Scans are capped at 6,000 files / 24 MB per call. Small and medium repositories are fine; very large monorepos need the incremental index on the roadmap.
Contributing
Issues and PRs are welcome. Start with CONTRIBUTING.md. The invariants are: local-first, no native deps, read-only code access, token-aware output, reversible writes.
If ctxkeeper saves you a few thousand tokens today, star the repo — it helps other developers find it.
License
MIT © 2026 Sixian Deng
Available Tools
8 toolscontext_packPack relevant contextARead-onlyIdempotent
Given a concrete question, return a token-budgeted pack of the most relevant code excerpts (with path:line citations) plus matching project memories. Use this BEFORE broad greps or reading whole files; it cuts token use and round trips.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Concrete question or identifiers, e.g. "where is the OAuth token refreshed". | |
| max_files | No | ||
| budget_tokens | No | ||
| include_memories | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description adds real behavioral context: the output is budgeted, includes path:line citations, and may include memories. It does not mention what happens when the budget is exhausted or how results are ranked/truncated, so it stops short of full disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with what the tool returns and followed by the when-to-use cue. Every clause carries information; nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description does its part by characterizing the return value (excerpts with citations and memories). However, for a 4-parameter tool with three undocumented parameters, an agent still lacks the knobs' semantics, so the definition is not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 25% — only `query` is documented. The description never explains `max_files`, `budget_tokens`, or `include_memories`; "token-budgeted" hints at budget_tokens but gives no defaults, bounds, or effect. It fails to compensate for the low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource: returns a token-budgeted pack of relevant code excerpts with path:line citations plus matching project memories. That is far more specific than any sibling, but it never names a sibling (e.g. project_brief or recall) to contrast against, so the differentiation is implied rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear positive guidance: "Use this BEFORE broad greps or reading whole files." It explains the tradeoff (token use and round trips). It does not say when not to use it or how it relates to recall/project_brief, which is the remaining gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forgetArchive or restore a memoryADestructiveIdempotent
Archive a memory by ID so it stops appearing in briefs and recall. Archive is reversible: pass restore=true with the same ID. Use when a decision is superseded or a note is wrong.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Memory ID, e.g. m_lx2abc. | |
| scope | No | all | |
| restore | No | Un-archive instead of archiving. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is carried structurally; the description earns credit for adding the crucial behavioral fact that the operation is reversible via restore=true with the same ID, and that archived items drop out of briefs and recall. It does not address behavior when the ID is unknown or invalid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each doing distinct work: effect, reversibility, and trigger. The most important information (what it does and its effect) is front-loaded with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter mutation tool with no output schema, the description covers the main path and the undo path, but never explains what scope controls or what happens if the ID doesn't resolve. An agent could call it correctly on the happy path but would guess on scope.
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 67%: id and restore are documented in the schema, and the description usefully reinforces the restore semantics. However, the scope parameter (all/project/global) is undocumented in both schema and description, leaving a required piece of invocation semantics unaddressed.
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 gives a specific verb and resource ("Archive a memory by ID") plus the observable effect ("stops appearing in briefs and recall"), which distinguishes it from sibling tools like recall and remember. It is clear about what the tool does, though it doesn't explicitly name sibling alternatives to route away from.
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?
"Use when a decision is superseded or a note is wrong" gives a concrete trigger condition, and the restore sentence explains the reverse path. There is no explicit statement of when *not* to use it (e.g. when to prefer remember or recall), so it falls short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
log_workLog completed workA
Append a short, timestamped work-log entry (what changed, which files, commands, outcome, next steps). Call this before ending a session so the next agent can resume without re-reading everything.
| Name | Required | Description | Default |
|---|---|---|---|
| files | No | ||
| outcome | No | success | |
| summary | Yes | What was done and why, in 1-4 sentences. | |
| commands | No | ||
| next_steps | No | ||
| duration_min | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false, destructiveHint=false, and the description's 'append' wording is consistent with a non-idempotent, non-destructive write. It adds useful context (timestamped, short, session-handoff purpose) but says nothing about where entries land, whether they are retrievable via recall, or whether repeated calls duplicate entries.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero padding, with the action and its content shape front-loaded before the trigger condition. Every clause 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?
For a 6-parameter write tool with no output schema and sparse schema descriptions, the definition covers purpose, trigger, and most content fields adequately. Gaps remain around `duration_min`, entry persistence/retrieval, and what the call returns, but nothing critical to invoking it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 17%, with just `summary` documented, so the description carries real weight here: it names files, commands, outcome, and next steps, mapping meaning onto four otherwise undocumented parameters. Only `duration_min` goes unmentioned, and no format or limit details (maxItems, enum values) are supplied.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('append') and resource ('work-log entry') and enumerates the entry contents (what changed, files, commands, outcome, next steps). It is clearly a write-to-log operation, though it never contrasts itself with the memory siblings (remember/recall/forget) that an agent might confuse it with.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit timing guidance: 'Call this before ending a session so the next agent can resume without re-reading everything,' which tells the agent exactly when to reach for it and why. It does not name an alternative tool or state when not to use it, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_briefProject brief (call first)ARead-onlyIdempotent
Start here. Returns a token-budgeted brief for this project: detected stack, run/test commands, files to read first, git state, open TODOs, decisions, gotchas, and recent work logs. Replaces exploratory file reads at session start.
| Name | Required | Description | Default |
|---|---|---|---|
| refresh | No | Force a fresh filesystem/git scan instead of using the 30s cache. | |
| budget_tokens | No | Token budget for the brief (rough estimate, default 1200). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint and idempotentHint, so safety is covered; the description adds that the output is token-budgeted and substitutes for exploratory reads, which is real behavioral context. It omits the 30s caching behavior and scan cost, though the schema's refresh param hints at it.
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, imperative opener first, then a packed content list. Every clause earns its place and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing return content, and the enumerated section list does that well. It could say more about output shape (structured vs prose) or how budget_tokens truncates sections, but an agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both refresh (30s cache override) and budget_tokens (400–8000, default 1200) are already documented in the schema. The description adds no parameter meaning beyond noting the brief is "token-budgeted"; 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?
"Start here" plus a concrete enumerated payload (detected stack, run/test commands, files to read first, git state, TODOs, decisions, gotchas, logs) states the verb and resource precisely. It distinguishes itself from siblings like recall/context_pack by framing the output as a synthesized session-start brief rather than a lookup.
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?
"Start here" and "at session start" give a clear triggering condition, and "replaces exploratory file reads" tells the agent what to skip. It does not name when NOT to use it or which sibling to prefer for follow-ups (recall, context_pack), so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallRecall project memoryARead-onlyIdempotent
Search saved memories with keyword/CJK-aware ranking (title, tags, files, content; importance and recency weighted). Filter by type, tag, or scope. Use before asking the user to repeat context.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | ||
| limit | No | ||
| query | No | Keywords; empty returns recent/high-importance entries. | |
| scope | No | all | |
| types | No | ||
| include_done | No | ||
| include_archived | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is covered. The description adds real behavioral context beyond that: the ranking is a blend of keyword match across specific fields plus importance and recency weighting, which tells the agent why result order may not be pure keyword relevance. It omits nothing critical for a read tool, though it says nothing about result volume/pagination 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?
Three compact sentences, front-loaded with the core action and ranking model. The middle 'Filter by type, tag, or scope' sentence largely restates the schema's enum fields, but it is short enough not to be wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter tool with near-zero schema description coverage and no output schema, the description covers the search model and filters but leaves limit, include_done, and include_archived unexplained — notably the default exclusion of done/archived entries. Adequate to call correctly, but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 14% across 7 params, so the description has to compensate. It does explain the query semantics (keywords, CJK-aware) and the type/tag/scope filters, but says nothing about limit, include_done, or include_archived — the last two being defaults that silently hide todo and archived memories, a behavior an agent should know about.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search saved memories') plus the ranking model (keyword/CJK-aware, title/tags/files/content, importance and recency weighted), which an agent can distinguish from the write-oriented 'remember' sibling. It stops short of explicitly contrasting with siblings like project_brief or context_pack, but the action is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use before asking the user to repeat context' gives one concrete triggering situation, which is genuinely useful. However, there is no guidance on when not to use it or which sibling (project_brief, context_pack, status) to prefer for related retrieval needs, leaving alternatives to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rememberRemember a durable factAIdempotent
Persist a decision, gotcha, fact, command, todo, or note to the local project store (or global store). Use this whenever the user states a preference, you make a non-obvious choice, or you discover something future sessions should know. Identical entries are deduplicated.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | ||
| type | Yes | decision | gotcha | fact | command | todo | note | |
| files | No | Related paths, relative to the project root. | |
| scope | No | project = this repo only; global = every project on this machine. | project |
| title | Yes | Short, searchable title. | |
| source | No | Optional author/agent label. | |
| content | Yes | The fact itself. Include why, constraints, and file paths when useful. | |
| replaces | No | ID of an older memory this supersedes (it will be archived). | |
| importance | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare write (readOnlyHint=false), idempotent, non-destructive, and the description usefully adds the mechanism behind idempotency: "Identical entries are deduplicated." It also discloses that entries land in a local project store unless scope is global. It does not say what a caller gets back or how deduplication resolves (silent skip vs. error), which keeps it off a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both load-bearing: the first establishes what is written and where, the second establishes when to write. The dedup note is a single trailing clause rather than its own paragraph. Nothing is repeated or padded.
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 9-parameter write tool with no output schema, the description covers purpose, storage scope, triggers, and dedup behavior, which is most of what a caller needs. It omits how a caller obtains the ID required by `replaces`, and it leaves the relationship to `recall`/`forget` implicit, which is a genuine gap for a memory system with sibling tools.
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 78%, so the schema already documents most of the 9 parameters, and the description's enumeration of types and the project/global distinction largely restates the enum values. It adds no extra semantics for tags, files, importance, source, or replaces beyond what the schema descriptions provide. Baseline 3 is the right ceiling here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete verb (persist) and an enumerated resource set (decision, gotcha, fact, command, todo, note) plus the store it lands in, so an agent immediately knows what the tool does. It falls short of a 5 because it does not distinguish itself from the `todo` sibling even though it accepts a "todo" type, leaving a real ambiguity unaddressed.
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?
"Use this whenever the user states a preference, you make a non-obvious choice, or you discover something future sessions should know" gives three explicit, checkable triggers. It stops short of the top score because it never names alternatives or exclusions — nothing says to use `recall` to look things up, `forget` to remove, or `todo` for tracked tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statusServer and store statusARead-onlyIdempotent
Show the detected project root, store paths, memory/todo/worklog counts, git state, and limits. Use when setting up the server or debugging why nothing is recalled.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds that this is a diagnostic/passive inspection tool rather than a data operation, but says nothing about output format, cost, or whether it touches the filesystem or git subprocess in ways that could be slow.
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 front-loads the reported contents, the second the usage triggers. No filler, no restatement of the name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates what the response contains, which is the key information an agent needs to decide to call it. Minor gap: it doesn't signal the response shape (structured JSON vs. human-readable text) for parsing purposes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so there is nothing to document; the schema is trivially complete. Baseline 4 applies, and the description correctly implies a no-argument call.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ("Show") and then enumerates exactly what is reported: project root, store paths, memory/todo/worklog counts, git state, and limits. This is clearly distinguishable from every sibling (remember/recall/forget/todo/log_work), which all operate on memory data rather than reporting server state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives two concrete triggering conditions: server setup and debugging why nothing is recalled. It doesn't name alternatives or state when not to use it, but for a zero-parameter diagnostic tool the selection guidance is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
todoProject todosB
Manage the durable project todo list. action=add needs title; action=list shows open items (set include_done=true for all); action=done/reopen needs id. Todos survive sessions and appear in project_brief.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Required for done/reopen. | |
| tags | No | ||
| limit | No | ||
| title | No | Required for add. | |
| action | Yes | ||
| content | No | ||
| importance | No | ||
| include_done | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds genuine context beyond the annotations: todos persist across sessions and surface in project_brief, which is the key behavioral property of this store. However, it is silent on the mechanics an agent would want for a mutable 8-param tool — how list is bounded (limit defaults to 30, max 100), whether duplicate titles are rejected, and what done actually does to the record.
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?
One compact sentence-per-action block, front-loaded with the resource and then the action contract. Every clause carries either a required-parameter rule or an alternative, with no padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-action, 8-parameter mutation tool with no output schema and thin annotations, the description leaves too much open: list's return shape and pagination, the meaning of tags/content/importance, and whether reopening restores prior state. An agent could call the wrong action with the wrong parameters and only discover it from errors.
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 only 25%, and the description covers just the two that already have schema text (title, id) plus include_done. Four parameters — tags, limit, content, importance — are undocumented in both schema and description, including the limit that governs list output size and the importance score that presumably affects ordering.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Manage the durable project todo list") and enumerates the four supported actions with their semantics. It is distinguishable from the memory siblings (remember/recall/forget) by the 'project todo' framing, though it never names them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives per-action conditions (title for add, id for done/reopen, include_done for list), which is real routing guidance within the tool. It stops short of saying when to use this versus remember/forget/context_pack, so an agent must infer the boundary between durable todos and memory entries.
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.
8 tool updates
v0.1.0- First observed
context_pack - First observed
forget - First observed
log_work - First observed
project_brief - First observed
recall - First observed
remember - First observed
status - First observed
todo
TDQS
Scored across 8 tools
Most tools have distinct roles: remember/recall/forget form a clear memory lifecycle, todo manages a separate list, and log_work and status are unambiguous. project_brief and context_pack both return token-budgeted context, but their scopes (session-start overview vs question-specific excerpts) are described well enough to distinguish them.
The set mixes simple verbs (remember, recall, forget), noun-like names (todo, status), and compound names (project_brief, log_work, context_pack). No single predictable convention is followed, though all names are readable and mostly snake_case.
Eight tools is well-scoped for a project-context memory server, with each tool covering a distinct operation. There is no obvious bloat or missing essential capability at this count.
The surface covers memory creation, search, archival with restore, todos, work logs, briefs, status, and context packing, providing solid lifecycle coverage. Minor gaps exist, such as no direct memory-edit operation or bulk cleanup beyond archiving by ID.
Maintenance
Related MCP Connectors
Shared memory for coding agents. Stop re-explaining your codebase every session.
Shared project memory that keeps teammates and AI agents aligned across sessions.
Persistent engineering memory designed to follow developers across coding agents.
Project memory, documentation and controlled secret access for AI coding agents.
Related MCP Servers
- AlicenseAqualityDmaintenanceLong-term memory for AI coding assistants. Remembers context once and recalls it across sessions.724MIT
- AlicenseNot gradedqualityBmaintenanceProvides persistent long-term memory (semantic RAG) for AI coding assistants, enabling them to store and semantically search code and documentation across chat sessions without token limits.5MIT
- FlicenseNot gradedqualityAmaintenanceProvides AI coding agents with a local-first persistent memory layer they can read and write during sessions, storing decisions, preferences, error patterns, and research per project or globally. Enables semantic and keyword search, formatted context recall, and cross-project guideline surfacing without API keys or cloud storage.-
- FlicenseNot gradedqualityAmaintenanceEnables AI coding agents to read and write persistent project-scoped and cross-project memory during sessions, using local semantic search to surface relevant decisions, preferences, error patterns, and guidelines across sessions. It also optionally exposes an autonomous task queue that draws on that same stored context.-