Skip to main content
Glama

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 tomorrow

The 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

project_brief

read

Stack, commands, files to read first, git, TODOs, decisions, gotchas, recent work — one call

context_pack

read

Given a concrete question, returns only the relevant code windows (path:line) plus matching memories, under a token budget

recall

read

Keyword + CJK-aware search over saved memories, ranked by field, importance, and recency

remember

write

Persist a decision, gotcha, fact, command, todo, or note; identical entries are deduplicated

todo

write

Durable add / list / done / reopen across sessions

forget

write

Archive a memory; restore=true brings it back

log_work

write

Timestamped work log: summary, files, commands, outcome, next steps

status

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 forget is 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-mcp

Running 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 --doctor

Connect 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  connected

Tools 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 test

That 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

project_brief (cache hit)

~10 ms

0.5–1.2k tokens

context_pack (17 files scanned)

~8–10 ms

~1.0k tokens, 2–4 cited windows

Reading src/store.ts directly

—

~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 log

Every 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 git with 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

CTXKEEPER_ROOT

auto-detected

Force the project root (absolute path)

CTXKEEPER_DIR

<root>/.ctxkeeper

Project memory directory

CTXKEEPER_GLOBAL_DIR

~/.ctxkeeper/global

Global memory directory

CTXKEEPER_MAX_FILE_KB

300

Max size of a file read into context

CTXKEEPER_DISABLE_CODE_SEARCH

unset

Set to 1 to expose memory tools only

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 recall misses.

  • 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 tools
context_packPack relevant contextA
Read-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.

NameRequiredDescriptionDefault
queryYesConcrete question or identifiers, e.g. "where is the OAuth token refreshed".
max_filesNo
budget_tokensNo
include_memoriesNo

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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

There is no output schema, and 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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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 memoryA
DestructiveIdempotent

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.

NameRequiredDescriptionDefault
idYesMemory ID, e.g. m_lx2abc.
scopeNoall
restoreNoUn-archive instead of archiving.

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

NameRequiredDescriptionDefault
filesNo
outcomeNosuccess
summaryYesWhat was done and why, in 1-4 sentences.
commandsNo
next_stepsNo
duration_minNo

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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)A
Read-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.

NameRequiredDescriptionDefault
refreshNoForce a fresh filesystem/git scan instead of using the 30s cache.
budget_tokensNoToken budget for the brief (rough estimate, default 1200).

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 memoryA
Read-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.

NameRequiredDescriptionDefault
tagsNo
limitNo
queryNoKeywords; empty returns recent/high-importance entries.
scopeNoall
typesNo
include_doneNo
include_archivedNo

TDQS

A3.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 factA
Idempotent

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.

NameRequiredDescriptionDefault
tagsNo
typeYesdecision | gotcha | fact | command | todo | note
filesNoRelated paths, relative to the project root.
scopeNoproject = this repo only; global = every project on this machine.project
titleYesShort, searchable title.
sourceNoOptional author/agent label.
contentYesThe fact itself. Include why, constraints, and file paths when useful.
replacesNoID of an older memory this supersedes (it will be archived).
importanceNo

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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 statusA
Read-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.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

NameRequiredDescriptionDefault
idNoRequired for done/reopen.
tagsNo
limitNo
titleNoRequired for add.
actionYes
contentNo
importanceNo
include_doneNo

TDQS

B3.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

  1. 8 tool updatesv0.1.0
    • First observedcontext_pack
    • First observedforget
    • First observedlog_work
    • First observedproject_brief
    • First observedrecall
    • First observedremember
    • First observedstatus
    • First observedtodo

TDQS

A3.7/5.0

Scored across 8 tools

Disambiguation4/5

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.

Naming Consistency3/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    A
    maintenance
    Provides 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.
    -
  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables 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.
    -