Projectmem
This MCP server gives AI coding agents a local-first memory layer for coding projects: read distilled project knowledge, check failure history before edits, and log what happens as you work.
Session-start reads: load mandatory instructions, project summary, project map, and plan.md intent file.
Pre-edit judgment: call
precheck_filebefore touching a file to see past failed approaches, unresolved issues, and high-churn warnings.Targeted memory access: fetch a single issue by ID, search events by keyword, or get a token-budgeted context block focused on an area.
ROI/score: get an A+→F prevention score with hours saved, tokens prevented, and dollars protected.
Cross-project lessons: query global gotchas learned from past projects, optionally filtered by library.
Write-side logging: open issues, record attempt outcomes (
worked/failed/partial), confirm fixes and close issues, add architectural decisions (with optionalsupersedes), and add durable notes/gotchas.Multi-project routing: list reachable projects and check which project a call would resolve to before writing.
🚀 Start here — five minutes, once
*Five minutes if you follow along here. Want to be shown instead — every command, the exact output it prints back, and the dashboards at the end? Take the complete setup guide.*
New to projectmem, or upgrading from 0.1.x / 0.2.x? Since 0.3.0 one MCP server serves every project, so this is the last time you configure anything.
1. Install or update
pip install -U projectmem2. Find the projects you already have
pjm doctorIt looks where code lives —
~/Developer,~/code,~/projects, your cloud folders, and every drive on Windows — and lists projects with memory that aren't registered yet. Anything it missed, add by hand:pjm project register "/Users/you/Developer/repos/ossdrop"3. Register them
pjm doctor --fix4. Point your AI at all of them with one config
"mcpServers": { "projectmem": { "command": "/absolute/path/to/python", "args": ["-m", "projectmem.mcp_server"] } }No
--root, nocwd— that's what makes it serve everything. Per-client instructions (Claude Desktop, Claude Code, Cursor, Antigravity, Codex) are in MCP Integration;pjm initprints this block with your own Python path filled in. Then fully restart the client — MCP servers only load on a cold start.5. Check your work
pjm doctorAdd
--onlineif you also want it to tell you when a newer projectmem is out — projectmem makes no network calls otherwise, and--autoturns that into a once-a-day check if you prefer.Run it again after editing the config. It flags any client still pinned to a single repo — the most common reason a new project is invisible to your agent.
All green? You're done. From here on it is one command per repo:
pjm initYour agent reads what the project already learned instead of rediscovering it, and writes down what it finds. Fewer tokens, no repeated dead ends, memory that outlives the session.
Related MCP server: Memstate AI - Agent Memory System
What is coding agent memory?
Coding agent memory is a persistent record of what happened while building a project — the issues hit, the approaches attempted, the fixes that worked and the decisions made — stored so an AI coding agent can read it at the start of a new session. Without it every session begins from zero.
projectmem is an open-source agent memory layer built for that job. It is
local-first: memory lives in a plain .projectmem/ directory inside your
repository, with no cloud, no account and no telemetry — the only network call
it can make is an update check you turn on yourself. A native MCP server
exposes 17 tools to Claude Code, Claude Desktop, Cursor, Antigravity and Codex,
so your agent reads memory and logs its work on its own.
Unlike chat-history memory tools, projectmem stores typed events — issues, attempts, fixes, decisions, notes — which is what makes the one thing no other tool does possible: a pre-commit warning that fires before you repeat an approach that already failed.
pip install projectmem
cd your-project && pjm init🎬 Watch the demo
📚 Docs
Doc | What's in it |
The full walkthrough on the web — install, MCP setup per client, | |
15-minute step-by-step walkthrough — set up projectmem on your own project, watch the lifecycle, see the pre-commit warning fire. | |
Release history. Latest: v0.3.3 — | |
PROJECTMEM: A Local-First, Event-Sourced Memory and Judgment Layer for AI Coding Agents — the peer-readable version: design, Memory-as-Governance framing, capability comparison, and the 207-event dogfooding study. | |
MIT |
The Problem
Every new AI session starts from zero. Claude, Cursor, Aider — they all forget yesterday's decisions, repeat failed debugging attempts, and burn millions of tokens reconstructing context from raw source files.
The model isn't the problem. The architecture is. Stateless models need a memory cortex.
The Solution
projectmem is the local-first memory + judgment layer that sits above your AI tools. It captures every failed attempt, decision, and gotcha — then injects that experience back into future AI sessions. Git tracks what changed. projectmem tracks why it changed, what was tried, and what failed.
Install
First time here? → The complete setup guide walks the whole path end to end: install, connecting Claude Desktop, Claude Code, Cursor, Codex or Antigravity, checking it with
pjm doctor, and reading your memory back through the dashboards — with the real terminal output at every step.
Three commands to a project that remembers:
pip install projectmem
cd your-project
pjm initThat's it. pjm init installs three git hooks (pre-commit warnings, post-commit classification, post-merge tracking), auto-starts a real-time file watcher, inherits cross-project memory if available, and creates .projectmem/. Capture is active from minute one.
The canonical command is
projectmem. Apjmalias is installed for speed.
✨ New in 0.3.3 — precheck stops getting slower, and Windows works end to end
pjm precheck runs before every edit — the instructions tell agents to call it
first — so its cost is paid constantly. It was taking 26 seconds on a
1,200-event project, and getting worse every week, because it ran one
git log per event to answer a question about a single file. It now makes one
call per distinct file, bounded by the oldest event citing it.
events | before | after |
100 | 2,210 ms | 48 ms |
400 | 8,905 ms | 51 ms |
1,500 | ~33 s, 1,501 git processes | 82 ms, 2 processes |
Latency is now flat rather than linear in project age. Results are unchanged — verified against a reimplementation of the old algorithm, including across merge commits.
A retired decision no longer resurfaces. supersedes has existed since
0.1.4, but the two surfaces an agent actually reads during work — get_context
and precheck_file — were not filtering it. You could retire a decision and
still be told about it. Both filter now, and AI_INSTRUCTIONS.md finally
documents how to retire one, which is why models never called it.
Your project is named in the bridge file, and AGENTS.md is written too.
One server serves every project, so a call naming none is refused rather than
guessed at — but nothing told the agent the name, so it learned it from the
error and retried, every session. The name is in the bridge now. It goes into
AGENTS.md as well as CLAUDE.md, because Antigravity and Codex never read
the latter.
Six Windows reports are closed. Git hooks shipped a bash shebang that
Git for Windows often cannot resolve — and an unresolvable shebang does not
skip the hook, it aborts your commit. The baked binary path lost its
backslashes to shell escaping. The venv fallback looked in bin/, which
cannot exist there. pjm watch --daemon could not be seen or stopped. And a
box-drawing character in the output killed pjm init outright on a cp1252
console — after it had already created everything, so the command both did its
work and reported failure.
Every one was fixed by running projectmem on the machines that reported it — Windows 11, and the four MCP clients — not by reading the code. Reported by @medium-effort, who also contributed the 0.3.2 Windows daemon support.
✨ New in 0.3.2 — Windows, properly
pjm watch --daemon crashed on Windows with AttributeError: module 'os' has no attribute 'fork'. It now spawns a detached worker instead of forking, so
background watching works on every platform.
Fixing that uncovered a second bug hiding behind it. Liveness was checked with
os.kill(pid, 0) — a POSIX idiom that does not port, because on Windows
os.kill routes to TerminateProcess and signal 0 is not a check at all. The
watcher could not be seen or stopped there, and each pjm watch --daemon leaked
another process. Both are fixed.
Windows daemon support was contributed by @medium-effort (#13).
pjm doctor also got two things. It now tells you to quit your AI client
before editing its config — those files hold the app's own preferences too, so
a running client can rewrite the whole thing on exit and restore the --root
you just removed. And it remembers what it saw last time, so a config that was
clean and is pinned again gets named as a revert rather than looking like doctor
being flaky. Local files only; nothing leaves your machine.
✨ New in 0.3.1 — know when to upgrade
Both dashboards now show which version generated the page, with a check for
updates link beside it. The page makes no request until you click — PyPI's
public JSON is fetched straight from your browser and nothing about your machine
is sent. On the command line, pjm doctor --online checks once and
pjm doctor --auto remembers to check daily; both are off unless you ask.
✨ New in 0.3.0 — one server, many projects
Until now an MCP config was tied to one repository: eleven projects meant eleven
server entries and eleven restarts. 0.3.0 serves every registered project from
a single server. Paste the config once; every repo you pjm init afterwards is
reachable from it.
pjm project list # what this server can reach
pjm project use ossdrop # the default when a call names no projectlog_issue(summary="stars come back empty", project="ossdrop")
→ Logged issue #0019 → ossdrop: stars come back emptyEvery write names the project it landed in — in a shared server, the dangerous
failure is not "nothing works", it is a write that succeeds against the wrong
repo. Existing --root configs keep working untouched, and a pinned server now
refuses to write anywhere else even when asked.
Also in 0.3.0:
Fixed: the MCP server was broken on fresh installs. mcp 2.0 renamed
FastMCPand left the old import path raising — since 2026-07-28 every newpip install projectmemgot a server that died at import. Caught and fixed by @VIVAAN-DHAWAN.Security: stored XSS in
pjm visualize. Event summaries reached the DOM unescaped, and git commit messages become event summaries — so a crafted commit in a branch you pulled could run script in your dashboard. Every sink is escaped now.A rebuilt dashboard — a shareable Memory Card, case files with the full issue → attempt → fix chain, an effort treemap, per-file dossiers, and a global view that opens with where you left off.
Registry migration is automatic: the 0.2.x list of paths is converted on first
read, with a .bak kept beside it.
✨ New in 0.2.0 — the workspace release
0.1.6 made one project's memory something you could watch. 0.2.0 lifts that to your whole workspace — and closes the gap between what happened (memory) and what your code is (structure).
🌐 Global dashboard —
pjm dashboardis one page over every project you'vepjm init-ed: total issues captured, fixes confirmed, dead-ends prevented, tokens saved, a grade per project, and a "needs attention" list. Click any card to open that repo's own dashboard, generated fresh. It's a global view, not a global store — each repo's.projectmem/is aggregated at read time and never leaves its folder. Default is serverless (a static snapshot); add--servefor a tiny, ephemeral live server where the Refresh button re-reads your files — no background daemon, Ctrl+C stops it.🧬 Structure & relations —
pjm map --build(run automatically atpjm init) walks your codebase and, for Python, resolves imports into a real dependency graph. The Project Map's Graph and Flow views now render actual files and the import edges between them. The cache (structure.json) is derived from code, gitignored, and never committed — code is only ever read.🔥 Failure heat on structure (the combo) — the one view a pure code-grapher can't draw and a pure memory tool can't either: files with repeated failed attempts glow red, laid directly over the real import graph. Structure comes from the code, heat comes from your memory, and they meet only in the renderer.
🗂️
plan.md— a new editable intent file: ideas and plans, what you mean to do — deliberately not the event log.events.jsonl → summary.mdrecords what happened;plan.mdrecords what you intend. The AI reads it at session start and edits it directly; a plan never becomes an event.pjm plan/pjm plan "idea"/ MCPget_plan().
Everything stays 100% local — the global dashboard is a read-time aggregate, never a central honeypot of your code's history.
The visualization suite (shipped in 0.1.6)
Your project's memory is also something you can watch — and share.
🎬 Showoff — a dashboard tab with three animated story scenes, all rendered from your real event log: Story Replay (watch your project's history build itself, node by node), Orbit (files orbit the project, events orbit their file), and Universe (your project as a rotating galaxy — every bright star is a real issue, attempt, fix, or decision; click one for its full details).
⏺ Built-in recorder — hit REC (10–60 s) and Showoff downloads a
.webmclip of the animation, rendered 100% locally with a "made with projectmem" badge. Your debugging story, ready for a tweet or a standup.🗺️ Flow — the Project Map's default view: a layered flowchart reading
PROJECT → DIRECTORIES → FILES → WHAT HAPPENED → MEMORY. Files with repeated failures glow red along their path, every file shows its outcome chips, and everything flows into theevents.jsonlcylinder. Tree and Graph views are one click away.🧵 Time Spine — the Timeline's default view: a real-time axis you scroll, with problems branching left (issues, failed attempts) and knowledge branching right (fixes, decisions, notes). Hover any card and its whole issue thread lights up. The classic list remains as "Details".
Why You'll Love It
Pre-Commit Warnings —
pjm precheckwarns you before you commit if you're about to repeat a failed approach, modify a high-churn file, or touch an unresolved issue. No other AI tool does this — it requires the memory layer underneath. The warning now lists the dead ends themselves ("What already failed here: ✗ tried CSS contain:layout"), andpjm precheck --snooze 2hsilences it politely — the snooze is itself logged, so even the silence is audited.Stale-Memory Detection (new in 0.1.4) — other memory tools silently decay or delete old memories; projectmem never deletes. Every decision that cites a file is cross-checked against that file's git history — when the file has moved on, the memory is flagged ("predates 7 commits to auth.py — confirm or supersede") and a human decides. Retire it cleanly with
pjm decision "new way" --supersedes <id>: the old event stays in the log, tagged, forever.Session-Start Briefing (new in 0.1.4) —
pjm briefanswers "where was I?" in one screen: active warnings, possibly-stale memories, open issues, recent decisions, stack gotchas, and your prevention score with a week-over-week delta.Memory for agents without MCP (new in 0.1.4) —
pjm export --claude-mdcompiles live decisions, gotchas, and a "Do NOT retry — these already failed" list into a marked block in CLAUDE.md (or.cursorrules). Copilot, plain Claude, any agent that reads the file inherits your project's judgment.Smart Context Injection —
pjm wrap claude(or cursor/aider) injects a token-budgeted memory block into your AI before the session opens. Your AI starts experienced, not blank.Provable ROI Score —
pjm scoreoutputs a letter grade (A+ → F) backed by concrete numbers — debugging hours saved, tokens prevented, dollars protected. CI-friendly JSON output and shields.io badge for your README.Cross-Project Memory — Lessons learned in one repo follow you forever. Library gotchas, decisions, and patterns live in
~/.projectmem/global/and auto-inherit into every new project that matches your stack.Real-time File Watcher — Background daemon detects rapid edits to the same file (debugging sessions) between commits. Battery-aware, gitignore-aware, auto-started by
pjm init.Native MCP Server — Plugs into Claude Desktop, Cursor, Antigravity, Codex, and any MCP-compatible tool. 15 native tools force the AI to read context, check files for known failures, read your
plan.md, and log work automatically. Verified end-to-end against all four clients.Interactive Dashboard (expanded in 0.1.6) —
pjm visualizeopens a six-tab local dashboard: Overview, Story Map (failure heatmap with collapse/focus controls), ROI Dashboard, Project Map (Flow / Tree / Graph, now over your real code structure), Timeline (Time Spine / Details), and Showoff — animated story scenes with a built-in video recorder.One MCP server for every project (new in 0.3.0) — configure your client once instead of once per repository. Calls name their project (
project="ossdrop"), or fall back to the active one; every write reports which repo it landed in, and a pinned--rootserver refuses to write outside its own. Existing single-project setups are untouched.Global Dashboard (new in 0.2.0) —
pjm dashboardis one cross-project view over every repo you'vepjm init-ed: grades, issues, savings, and per-project drill-in. A global view, never a global store — each repo's memory is aggregated at read time and never leaves its folder. Serverless by default;--servefor an ephemeral live server (Ctrl+C to stop).Code Structure + Judgment (new in 0.2.0) —
pjm map --buildreads your codebase into a real import graph, and the Project Map overlays failure heat from your event log on top: the files that keep breaking, glowing red over the structure that actually connects them. The structure cache is derived from code and gitignored — never committed.Intent, separate from memory (new in 0.2.0) —
plan.mdholds ideas and plans (what you mean to do), kept deliberately apart from the append-only event log (what happened).pjm plan, or the MCPget_plan(); the AI edits it directly and a plan never becomes an event.100% Local — No cloud, no telemetry, no accounts. Your code, your memory, your machine.
How It Compares
Capability | projectmem | claude-mem | agentmemory | mem0 | Letta (MemGPT) |
Core focus | Memory + Judgment | Session capture | Memory engine | Chat memory | Agent framework |
Pre-commit failure warnings | ✅ unique | ❌ | ❌ | ❌ | ❌ |
Stale memory: flag, never delete | ✅ new in 0.1.4 | ❌ | ❌ silent decay | ❌ | ❌ |
Supersede without losing history | ✅ new in 0.1.4 | ❌ | ❌ | ❌ | ❌ |
Captures development history | ✅ typed events | 🟡 | 🟡 | 🟡 | 🟡 |
Records architectural decisions | ✅ | ❌ | 🟡 | ❌ | ❌ |
Memory for agents without MCP | ✅ CLAUDE.md export | ❌ | ❌ | ❌ | 🟡 |
Cross-project memory | ✅ library-scoped | 🟡 | 🟡 | 🟡 | 🟡 |
Provable ROI score | ✅ A+ → F + $ | ❌ | ❌ | ❌ | ❌ |
Plain-text, greppable store | ✅ events.jsonl | ❌ | ❌ | ❌ | 🟡 |
No persistent server or DB | ✅ stdio + files † | ❌ | ❌ | ❌ | ❌ server + DB |
No telemetry, no accounts | ✅ | ❌ default-on | ✅ | ❌ | 🟡 |
Native MCP server | ✅ 15 focused tools | ✅ | 🟡 53 tools | 🟡 | 🟡 |
Global dashboard (all repos) | ✅ read-time, local | ❌ | 🟡 central store | ❌ | ❌ |
Editable intent (plan ≠ memory) | ✅ | ❌ | ❌ | ❌ | 🟡 |
Price | ✅ Free · MIT | Free + paid tier | Free | Freemium | Free + cloud |
✅ yes · 🟡 partial · ❌ no — snapshot June 2026; design capabilities, not benchmark results. claude-mem runs a background worker (port 37777) and enables telemetry by default (v13.5+); agentmemory down-ranks and prunes old memories via decay, mem0 rewrites facts on update, Letta's memory blocks self-edit in place — projectmem never deletes: it flags staleness and lets you decide. Letta requires a running server (Postgres or cloud).
† There is no database and nothing you have to keep running: the MCP server is a stdio subprocess your AI client spawns, and everything else is plain files. The only server anywhere is the optional pjm dashboard --serve, an ephemeral local viewer you start and stop with Ctrl+C — never a background service.
🚧 Upcoming
Import your existing memory —
pjm import(planned for 0.4.0) will migrate history from mem0, agentmemory, Letta, and Claude session logs into projectmem. It maps only to the core event vocabulary — issues, attempts, fixes, decisions, notes — so signal comes in and another tool's clutter stays out. Your judgment history moves with you.
Want a source supported? Open an issue and tell us what you're migrating from.
How AI Reads Your Memory (Token Efficiency)
The architecture is built around one rule: AI reads small, distilled files. Tools generate them from the big raw log.
Access mode | Tokens / session | How it works |
No projectmem (baseline) | 5,000 – 20,000+ | AI re-reads source files every session |
Universal Mode (markdown) | ~2,500 | AI reads 3 small distilled files once |
MCP Mode (recommended) | ~800 – 1,500 | AI calls |
| 500 – 2,000 | Pre-generated, you set the budget |
AI never reads events.jsonl directly. That file is for tools (pjm score, pjm context, pjm wrap). Tools distill the raw log into compact AI-readable summaries.
One server, many projects
Since 0.3.0 a single MCP server serves every project you have registered. Paste
the config once and every repo you pjm init afterwards is reachable from it —
no second entry, no restart.
pjm project list # what this server can reach
pjm project use ossdrop # the default when a call names no project
pjm project alias ossdrop odYour agent picks the project per call:
log_issue(summary="stars come back empty", project="ossdrop")
→ Logged issue #0019 → ossdrop: stars come back emptyEvery write says where it landed. That echo is the point: in a one-project setup a misconfigured server simply fails, but a shared server can succeed against the wrong repository, which corrupts two audit trails at once. If the name in the reply is not the project you meant, stop.
How a call is routed, highest first:
Source | Notes | |
1 |
| A boundary, not a default. A pinned server refuses to write elsewhere, even when asked. |
2 |
| id, alias or path. An unknown name is an error. |
3 | The client's workspace root | Only when exactly one resolves. |
4 | The active project |
|
5 | The working directory | Walks up looking for |
6 | — | Refuses, and lists what is registered. It never guesses. |
Client roots outrank the active project on purpose: the root is where you are now, the active project is a mode you set days ago. When they disagree, the stale one is the wrong answer.
Single-repo setups are untouched — pjm init --mcp-config-single still prints
the pinned config, and an existing --root entry keeps working exactly as before.
MCP Integration (Recommended)
For: Claude Desktop, Cursor, Antigravity, Codex — and any tool with native MCP support. The MCP server forces the AI to read memory and log every action automatically.
Since 0.3.0 you configure this once, not once per repository. The block below has no --root: the server serves every project you have registered, and each call resolves its own. Paste it, and every repo you pjm init from then on is reachable — no second entry, no restart.
"mcpServers": {
"projectmem": {
"command": "/opt/anaconda3/bin/python",
"args": ["-m", "projectmem.mcp_server"]
}
}Upgrading with projects you already have? The registry only ever recorded
projects you ran pjm init on since it existed (0.2.0), so anything older is
missing — and global mode routes through the registry. One command sorts it out:
pjm doctor # what's unregistered, what's stale, what's still pinned
pjm doctor --fix # register what it foundIt looks in the places code actually lives — ~/Developer, ~/code, ~/src,
~/projects and friends, plus every fixed drive on Windows, where projects sit
on D:\ and E:\ as often as under your home folder. To point it somewhere
specific:
pjm doctor --path ~/work --path /Volumes/ssd --fix
pjm project scan D:\ E:\ --depth 3 # the same walk, without the other checksNothing is scanned until you run it, and nothing is written without --fix.
After an upgrade the CLI mentions pjm doctor once — a wheel install can't run
code, so the first command you type is the only place to say it.
With one project registered, that is the whole setup — there is only one place a call can go. With several, your AI passes project="<name>", or you set a default with pjm project use <name>. pjm init prints this block with your own Python path already filled in.
Upgrading from 0.2.x? Your existing --root entry keeps working exactly as before, and a pinned server now refuses to write outside its own repo even if asked. Replace it with the block above when you want one server for everything.
The 3-minute workflow (let your AI do the setup)
Install + init.
pip install projectmem, thencdinto your project and runpjm init— or simply ask your AI to run it.Ask your AI to set up the projectmem MCP server for you — it can edit the client's config file itself. (It needs permission to do that: use Auto / accept-edits mode, or approve the file edit when asked. The exact config per client is in the sections below if you'd rather paste it by hand.)
Restart the AI tool so the MCP server loads, then start your session with this prompt:
Hi — I use projectmem as this project's memory. Before anything else,
call get_instructions(), then get_summary(), then get_project_map() to
load what we already know. As we work, log issues, attempts
(failed/worked), fixes, decisions, and notes with the projectmem tools,
and call precheck_file(path) before you edit a file. Ideas and plans go
in plan.md via get_plan() — never as events.Strictly speaking this prompt is optional — with the MCP server installed correctly the AI discovers the memory on its own. But saying it makes capture noticeably more consistent, so we recommend it.
Repeat for every project:
pjm init+ the same kickoff prompt.Coming back after closing the window? Open with a one-line reminder — "Reminder: we use projectmem as memory here." — and the whole setup carries on where you left off.
Prefer to wire it up by hand? The exact, verified config for each client follows.
Claude Desktop
Easiest — open the config from the UI:
macOS: Claude menu →
Settings…→Developertab → Local MCP servers → Edit Config.Windows / Linux: same path expected (
Settings → Developer → Edit Config) — open an issue if your platform differs and we'll update this.
If you prefer the raw file path: ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows, ~/.config/Claude/claude_desktop_config.json on Linux (or $XDG_CONFIG_HOME/Claude/ if you have moved it). pjm init prints the right one for the machine you run it on.
Paste this block:
"mcpServers": {
"projectmem": {
"command": "/opt/anaconda3/bin/python",
"args": ["-m", "projectmem.mcp_server"]
}
}Two things to know about this block:
Use the absolute path to
python(e.g./opt/anaconda3/bin/python, or runwhich pythonto find yours). Claude Desktop subprocesses don't inherit your shellPATH, so bare"python"often fails.You no longer need the
cwdfield, and you never could rely on it. Claude Desktop's current build (with the Epitaxy / Cowork workspace system) silently ignorescwd— the server ends up running withcwd=/and can't find.projectmem/. That is why older releases needed--root. The registry replaces it: the server finds projects by name, not by where it happens to be running.
"mcpServers": {
"projectmem": {
"command": "/opt/anaconda3/bin/python",
"args": [
"-m", "projectmem.mcp_server",
"--root", "/absolute/path/to/your/project"
]
}
}A pinned server serves exactly that repository and refuses to write anywhere else, even when asked — the stricter choice if you want a hard boundary. pjm init --mcp-config-single prints this form.
Then fully quit Claude Desktop (Cmd+Q on Mac) and reopen — MCP servers only initialize on cold start.
Cursor
Two ways to register the MCP server — pick whichever fits your workflow:
Global (recommended): Cursor menu →
Settings…→ left sidebar Tools & MCPs → Installed MCP Servers → Add Custom MCP. Paste the JSON below.Per-project: drop the JSON into
<project-root>/.cursor/mcp.json— only active when that project is open.
{
"mcpServers": {
"projectmem": {
"command": "/opt/anaconda3/bin/python",
"args": ["-m", "projectmem.mcp_server"]
}
}
}Two things to know about this block (same gotchas as Claude Desktop):
Use the absolute path to
python(runwhich pythonto find yours). Cursor subprocesses don't reliably inherit your shellPATH.Don't bother with the
cwdfield. Cursor — like Claude Desktop — silently ignores it: the server ends up running withcwd=~. Since 0.3.0 that no longer matters, because projects are found by name in the registry rather than by where the server runs.
Registered globally, one entry covers every project. Per-project .cursor/mcp.json still works if you prefer the server to exist only when that repo is open — add "--root", "/absolute/path/to/your/project" to args there to pin it.
Then fully quit Cursor (Cmd+Q on Mac) and reopen. projectmem also auto-discovers .projectmem/ by walking up from CWD (like git does for .git/), and honors PROJECTMEM_ROOT and a --root <path> CLI argument.
Antigravity
Antigravity (Google's AI IDE) speaks standard MCP.
Easiest — open the config from the UI:
Open the Agent window (the chat panel on the right).
Click the ⋯ Additional Options button in the panel header.
Choose MCP Servers → Manage MCP Servers → Add new (or Edit Config).
The raw file is at ~/.gemini/antigravity/mcp_config.json if you prefer editing it directly.
Paste this block:
{
"mcpServers": {
"projectmem": {
"command": "python",
"args": ["-m", "projectmem.mcp_server"]
}
}
}Antigravity does honor the cwd field, so adding "cwd": "/absolute/path/to/your/project" works — but it ties the server to that one repo. Leave it out and the same entry serves every registered project.
Then fully quit Antigravity (Cmd+Q on Mac) and reopen — MCP servers only initialize on cold start. All 17 projectmem tools register identically to Claude Desktop / Cursor.
Codex
Codex stores MCP config as TOML (not JSON) in ~/.codex/config.toml. There's a UI form at Settings → MCP Servers → Add MCP Server, but during cross-client verification the form's Save button didn't reliably persist — the file-edit path is faster and more reliable.
Easiest — edit ~/.codex/config.toml directly:
Append this block (preserves any existing config):
[mcp_servers.projectmem]
command = "/opt/anaconda3/bin/python"
args = ["-m", "projectmem.mcp_server"]
cwd = "/absolute/path/to/your/project"Three things to know about this block:
Use the absolute path to
python(runwhich pythonto find yours). Codex subprocesses don't reliably inherit your shellPATH.You no longer need
--rootorcwd. Earlier releases passed--rootas defense in depth (thecwdfield does appear to work in Codex, unlike Claude Desktop and Cursor). Since 0.3.0 the registry makes both unnecessary — add"--root", "/absolute/path/to/your/project"toargsonly if you want this server locked to a single repo.Set your reasoning effort to
mediumor higher. On low-reasoning Codex skipsget_instructionsfrom the session-start trio, which can cause the AI to miss the Setup Mode workflow rules. Medium+ honors the full trio automatically.
Validate the TOML:
python -c "import tomllib; tomllib.load(open('/Users/<you>/.codex/config.toml','rb')); print('OK')"Should print OK. If not, the parser tells you the offending line.
Then fully quit Codex (Cmd+Q on Mac) and reopen. Same cold-start rule as every other MCP client. Codex MCP servers spawn lazily on the first tool call in a chat session — if you don't see the process in ps aux right after reopening, send any message to a Codex chat and check again.
Reasoning-effort note: Codex's mode selector is at the bottom of the chat input. Set it to medium (not low) for the full session-start trio behavior. Once set, it persists per-session.
First-run permission prompts
On first use in any MCP-capable client (Claude Desktop, Cursor, Antigravity, Codex), your AI will ask permission before each projectmem tool call. This is expected security behavior — MCP clients require explicit consent for every new tool. Approve each tool once and the prompt won't reappear for that session.
Other MCP Tools
Any MCP-compatible client works — point your tool at
python -m projectmem.mcp_server and either set cwd to your project
root or rely on the parent-walk auto-discovery.
MCP Tools Exposed
All 17 tools your AI can call. Every repo tool takes an optional
project argument — see One server, many projects:
Read-side (10 tools):
Tool | When to use |
| Start of every session — load workflow rules |
| Start and end — distilled project memory |
| Start — understand repo structure |
| Read |
| Before editing any file — surface failure history |
| Read one specific issue's full history by ID |
| Plain-text search across all logged events |
| Token-budgeted memory block with optional focus filter |
| A+→F prevention score + ROI numbers |
| Cross-project library lessons inherited from past repos |
Write-side (5 tools):
Tool | When to use |
| Immediately when encountering a bug |
| Immediately after each fix attempt (outcome: |
| After confirming a fix resolves the issue |
| When making architectural / design decisions; pass |
| When discovering gotchas, setup details, or constraints |
CLI Reference
Core memory
Command | Purpose |
| Initialize memory + auto-install hooks + inherit global memory |
| Start a new issue / debugging session |
| Record a fix attempt outcome |
| Record the confirmed fix and close the issue — |
| Record an architectural decision; optionally retire a prior one (old event stays in the log, tagged) |
| Record durable context or a gotcha |
| Print |
| Print the current summary |
| Plain-text search across all events; |
| One-screen session-start briefing: warnings, stale memories, open issues, decisions, score |
| Compile live memory into CLAUDE.md / .cursorrules for agents without MCP |
Intelligence layer
Command | Purpose |
| Real-time file churn watcher |
| Warn about repeating failed approaches before commit; snooze politely (audited) when needed |
| Inject token-budgeted memory into Claude/Cursor/Aider |
| Generate token-budgeted project context |
| Letter-grade prevention score |
| Manage cross-project memory |
Projects (global MCP)
Command | Purpose |
| Find unregistered projects, stale entries and pinned client configs. |
| Every project this server can reach, and which one is active (new in 0.3.0) |
| Walk for projects with memory and register them |
| Add a project that already has memory ( |
| Set the default project for calls that name none; omit the name to clear it |
| Give a project a shorter name |
| Tag a project |
| Forget a project — its repo and |
Visualization & utility
Command | Purpose |
| Open the six-tab local dashboard (Overview, Story Map, ROI, Project Map, Timeline, Showoff) |
| Cross-project global dashboard over every |
| Print the Project Map; |
| Token ROI summary in the terminal |
| Auto-populate memory from git history |
| Manage git hooks manually |
| Rebuild |
Use
--at "file.py:42"with any logging command to attach precise location metadata.
plan.md — intent, kept separate from memory
pjm init scaffolds a .projectmem/plan.md: your ideas and plans — what you mean to do, in plain Markdown (Ideas · Active plans · Next · Someday · Shipped). It's the one file that is deliberately not the event log:
events.jsonl → summary.mdrecords what happened (append-only, never rewritten).plan.mdrecords what you intend — and you (or the AI) edit it directly, likePROJECT_MAP.md.
Your AI reads it at session start via get_plan() and updates it in place: adding ideas, checking items off, moving finished work down to Shipped. A plan is never logged as an event, so intent stays cleanly out of your memory's audit trail. pjm plan prints it; pjm plan "auto-batch the exporter" appends an idea. It's committed (not gitignored) so intent is shared with your team.
Example: Pre-Commit Warnings in Action
$ git commit -m "switch auth to JWT"
projectmem: Pre-Commit Check
─────────────────────────────────────────────
src/auth/middleware.py
WARN What already failed here (2 attempts):
✗ tried switching to JWT middleware (2d ago)
✗ patched session timeout to 60min (5d ago)
WARN HIGH CHURN: 5 changes in last 30 days
WARN 1 possibly-stale memory cites this file
decision [evt_9db5a3f8…] "auth uses session
cookies, 30min timeout" — predates 7 commits
Confirm it still holds, or retire it:
pjm decision "..." --supersedes <id>
─────────────────────────────────────────────
3 warning(s). Review before committing.
~30 min re-debugging just saved.Need it quiet for a refactor sprint? pjm precheck --snooze 2h — warnings pause, the pause itself is logged, and every commit shows one dim line so silence is never mistaken for a clean check.
Privacy & Security
By default, projectmem commits the distilled files (summary.md, PROJECT_MAP.md, AI_INSTRUCTIONS.md, issues/) and gitignores the raw log + runtime files (events.jsonl, watch.pid, watch.log). This means your teammate's AI inherits your team's knowledge automatically — just git clone and the AI already knows what your team learned.
Want total privacy? Add a single line .projectmem/ to your .gitignore. Nothing leaves your machine.
Full security policy and threat model: SECURITY.md · Privacy & Security guide
Design Principles
Local-first — No network calls, no cloud, no telemetry. Your data never leaves your machine.
Project-scoped — Memory lives in the repo. When the code moves, the memory moves.
AI-tool-agnostic — Works natively via MCP, or universally via Markdown instructions. Any AI tool, any workflow.
Built With
projectmem stands on the shoulders of these excellent open-source projects:
Typer — the CLI framework that makes
pjmfeel ergonomicModel Context Protocol — Anthropic's open spec that lets AI agents talk to local tools
watchdog — cross-platform filesystem event monitoring (the heart of
pjm watch)D3.js — the interactive visualizations in
pjm visualize
Research & Citation
projectmem is described in a peer-readable research paper:
PROJECTMEM: A Local-First, Event-Sourced Memory and Judgment Layer for AI Coding Agents Ripon Chandra Malo, Tong Qiu — University of Utah arXiv:2606.12329 · cs.SE (cross-list cs.AI)
The paper introduces the Memory-as-Governance framing — memory that doesn't merely answer the agent but acts on its next action — and reports the design, the deterministic pre-commit judgment gate, a capability comparison against 12 contemporary memory systems, and a two-month, 207-event dogfooding study across 10 real projects.
If projectmem is useful in your research or writing, please cite:
@misc{malo2026projectmem,
title = {PROJECTMEM: A Local-First, Event-Sourced Memory and
Judgment Layer for AI Coding Agents},
author = {Malo, Ripon Chandra and Qiu, Tong},
year = {2026},
eprint = {2606.12329},
archivePrefix = {arXiv},
primaryClass = {cs.SE},
url = {https://arxiv.org/abs/2606.12329}
}License
MIT — free for personal, commercial, and enterprise use forever.
Help Us Reach More Developers
We don't need money. We need you.
projectmem is built by one developer for the open-source community. Every star, every share, and every contribution helps the project survive and grow.
Star the repo — takes one click, helps massively with discovery
Share on X / LinkedIn — tell other devs they don't have to keep paying AI to relearn their codebase
Open an issue — bug, feature request, or just feedback
Contribute code — PRs welcome, see contributing guide
Using
projectmemat work or in a commercial product? Reach out to support@projectmem.dev so we know who's shipping with us. It's free — we just love hearing about it.
Stars and shares matter more than money — but if you really want to: sponsor on GitHub →
Available Tools
17 toolsadd_decisionA
Record an architectural or product decision permanently.
Call when you make a choice that future sessions or contributors
should know about. Decisions show up in `summary.md` and in
`pjm wrap` context blocks.
Side effects: appends a `decision` event and updates summary.md.
Decisions are append-only — to revise, pass `supersedes` with the old
decision's event id instead of editing history.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. | |
| summary | Yes | One-line description of the architectural or product decision (e.g., 'use bcrypt rounds=12 for password hashing'). Becomes part of the project's permanent record — write it for a future contributor. | |
| location | No | Optional file path or scope where the decision applies (e.g., 'src/auth/' for a module-level choice). Helps precheck_file cite the decision when the file is later touched. | |
| supersedes | No | Optional event id (evt_...) of a prior decision this one retires. The old event stays in the log tagged (superseded); only the new decision appears in summary.md. Use when precheck_file flags a decision as possibly stale and you are revising it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the disclosure burden. It clearly states the side effects: appends a decision event and updates summary.md, and it explicitly calls out append-only semantics with supersedes as the revision mechanism. It does not discuss permissions or failure modes, but the core mutating behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and each sentence earns its place: what the tool does, when to call it, where the output surfaces, and side effects/revision behavior. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complete input schema, the presence of an output schema, and a description that covers selection trigger, side effects, and revision, nothing essential is missing. An agent can confidently decide when to invoke this tool and what behavior to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema itself provides rich meaning with examples, project disambiguation, and supersedes behavior. The prose description does not need to add parameter detail; it only reinforces the supersedes context. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-object pair ('Record ... decision permanently') and immediately establishes the resource and its durable nature. It also gives the trigger condition, which separates this from generic note/attempt tools by the permanent, summary-visible artifact.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Call when you make a choice...' sentence is an explicit trigger condition, and the supersedes guidance tells the agent how to handle revisions. It does not name sibling alternatives or provide explicit when-not-to-use guidance, so it falls 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.
add_noteA
Record a gotcha, setup detail, or other durable context.
Use when you discover something important that doesn't fit as an
issue or decision. Notes survive across sessions and appear in
wrap context blocks.
Side effects: appends a `note` event. Notes prefixed `gotcha:`,
`lesson:`, or `warning:` are eligible for auto-promotion to
~/.projectmem/global/ for cross-project recall (L-046).| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. | |
| summary | Yes | One-line description of the gotcha, setup detail, or context worth preserving. Prefix with 'gotcha:' or 'lesson:' to enable cross-project promotion — e.g., 'gotcha: bcrypt v4 silently truncates passwords longer than 72 bytes'. | |
| location | No | Optional file path or library this note applies to (e.g., 'bcrypt' for a library-specific gotcha). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It clearly states the side effect: 'appends a `note` event.' It also discloses cross-session persistence, appearance in wrap context blocks, and auto-promotion rules for prefixed notes. This is unusually transparent for a write-like tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, with the core purpose in the first sentence. Every subsequent sentence earns its place: one gives usage timing, one gives side effects, and one explains promotion behavior. There is no filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter tool with a 100%-covered schema and an output schema, the description is complete. It explains why the note is durable, where it appears, what event it appends, and when to use it instead of issue/decision tools. An agent has enough context to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value by framing the summary as durable context rather than transient commentary and by including 'warning:' as an auto-promotion prefix, which goes beyond the schema's mention of only 'gotcha:' and 'lesson:'. It does not add much about project or location, but those are already well documented in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Record a gotcha, setup detail, or other durable context.' It also explicitly distinguishes the tool from issue/decision tracking, which maps to the sibling tools log_issue and add_decision. This makes the tool's scope immediately clear and separates it from related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use when you discover something important that doesn't fit as an issue or decision' gives an explicit condition for use and an implicit exclusion: if it does fit as an issue or decision, use those instead. It also explains the persistence and visibility consequences ('survive across sessions and appear in wrap context blocks'), which helps the agent reason about when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
current_projectA
Show which project a call would resolve to, without writing anything.
Use this before a write when several projects are in play — it answers "where would this land?" cheaply. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It clearly discloses the read-only nature with 'without writing anything' and 'Read-only,' which is the key safety-relevant behavior for this tool. It also signals low cost ('cheaply'), giving agents confidence to call it during write planning.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, with the core action and the read-only guarantee front-loaded, and the usage context in the second sentence. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only tool with an output schema, the description supplies the necessary usage context (before writes, multi-project situations) and the safety profile. The schema documents the parameter, and the output schema handles return shape, so nothing needed to call the tool 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?
The input schema already documents the single 'project' parameter at 100% coverage, including how to omit it. The description adds no parameter-specific detail beyond affirming the tool is about where a call would land, so a baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and object: 'Show which project a call would resolve to,' which precisely identifies the tool's function as a resolution check rather than a listing or mutation. The phrase 'without writing anything' further clarifies scope and separates it from sibling tools like list_projects or log_issue.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use it: 'before a write when several projects are in play,' and frames it as a cheap way to answer where a call would land. It doesn't name alternatives or when-not conditions, but the primary trigger is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_contextA
Generate a token-budgeted memory context block.
Use when you don't want to read the full summary. ``focus`` (e.g.
'src/auth/') biases the context toward a specific area.
Read-only; assembles a freshly-budgeted context block from
events.jsonl.| Name | Required | Description | Default |
|---|---|---|---|
| focus | No | Optional path prefix or keyword to bias selection toward (e.g., 'src/auth/'). When omitted, the context is project-wide. | |
| tokens | No | Approximate target token budget for the returned markdown (default 2000). Output may be slightly over or under as events are included as whole units. Recommended range: 500-8000. | |
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and it delivers: 'Read-only' explicitly rules out side effects, and 'assembles a freshly-budgeted context block from events.jsonl' discloses the data source and non-cached, freshly assembled nature. This is exactly the kind of behavioral context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: purpose first, use-case second, behavior note last. Every sentence earns its place; there is no fluff or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description plus the fully-covered schema and existing output schema provide everything needed to decide when to call the tool, what parameters to pass, and what side effects to expect. The project parameter is handled by the schema, including a pointer to list_projects, so no critical guidance 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 100%, so the baseline is 3. The description's mention of focus only restates what the schema already documents ('Optional path prefix or keyword to bias selection toward'); it adds no meaning beyond the schema for tokens or project.
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 opens with a specific verb and resource: 'Generate a token-budgeted memory context block.' It clearly differentiates from get_summary by stating this is for when you don't want to read the full summary, so an agent can distinguish it from the most similar sibling without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit condition: 'Use when you don't want to read the full summary.' This implies get_summary as the alternative and covers the main routing concern, though it does not name the sibling tool explicitly or list when-not-to-use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_global_gotchasA
Query cross-project library gotchas from ~/.projectmem/global/.
Returns lessons learned in past projects that apply to the libraries
you're about to use. Call whenever working with an unfamiliar library
or starting a new feature.
Read-only. Reads from ~/.projectmem/global/ (cross-project memory,
not this repo's .projectmem/).| Name | Required | Description | Default |
|---|---|---|---|
| library | No | Optional library name to filter by (case-insensitive substring match — 'react' also matches 'react-router'). When omitted, returns all gotchas across every library — useful when starting a new feature to scan for any relevant past lessons. | |
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It clearly states the operation is read-only, names the exact source location, and clarifies that it reads cross-project memory rather than the repo's own .projectmem/. This is solid transparency for a read-only query tool.
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?
Four short sentences front-load the main action and source, followed by usage guidance and safety context. There is minor redundancy between 'Read-only' and the subsequent 'Reads from' clause, but no wasteful 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?
The description covers what the tool does, when to call it, the source path, and the read-only safety property. Since an output schema exists and the parameter schemas are rich, nothing critical is missing for an agent to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both parameters already have detailed descriptions in the schema (case-insensitive substring match for library, project resolution for project). The tool description does not add parameter-specific semantics, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Query') and a specific resource ('cross-project library gotchas' from ~/.projectmem/global/), and it explicitly contrasts with this repo's .projectmem/. The focus on library gotchas makes it clearly distinct from siblings like get_summary or get_project_map.
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?
Provides an explicit trigger: 'Call whenever working with an unfamiliar library or starting a new feature.' It does not, however, name sibling alternatives or provide when-not-to-use exclusions, so it falls slightly short of a perfect score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_instructionsA
Read the project's mandatory AI instructions.
MANDATORY: call this at session start. The instructions describe the
workflow rules you MUST follow while working in this project — they
are not advisory.
Read-only; does not modify memory.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It explicitly states 'Read-only; does not modify memory,' which covers the main safety-relevant behavior. It could add more context about what happens if no instructions exist or whether the returned content is cached, but the simple read-only trait is transparently disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the core purpose, followed by the mandatory usage instruction and a read-only safety note. The repetition of 'MANDATORY' and 'MUST' is somewhat redundant, but the text is still efficient and every sentence contributes useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, low-complexity tool with one optional parameter, a detailed schema, and an output schema, this description is complete. It tells the agent why this tool exists, when it must be called, and that it is side-effect-free. Nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage of the single optional parameter, including when to omit it and how to resolve a project identifier. The description adds no parameter-specific detail, so baseline 3 is appropriate since the schema already takes care of documenting the parameter fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the exact action ('Read') and resource ('the project's mandatory AI instructions'), and its emphasis that these are mandatory workflow rules distinguishes it from sibling information tools like get_summary or get_project_map. This is specific, actionable, and immediately tells an agent what the tool is for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly commands calling this tool at session start, states that the instructions are not advisory, and makes clear the agent MUST follow the returned rules. This is stronger and more explicit than a mere contextual hint; it tells the agent exactly when and how the tool should be used, leaving no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_issueA
Read one specific issue's full history by ID (token-efficient).
Use this when you only need one issue's context instead of the whole
summary. Example: get_issue('0042').
Read-only.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. | |
| issue_id | Yes | Zero-padded 4-digit issue ID returned by log_issue (e.g., '0042'). Numeric strings without padding (e.g., '42') are also accepted. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the safety burden. It explicitly states 'Read-only,' which is a meaningful behavioral disclosure for an agent deciding whether a call is safe. It also mentions 'token-efficient' and 'full history,' giving useful behavioral context beyond a bare schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core action, followed by a usage condition and a concrete example. Every sentence earns its place, and there is no redundant restatement of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple read tool with only two parameters, both fully documented in the schema, and an output schema is present. The description closes the remaining gaps by stating use case, example, and read-only behavior, so an agent has enough to select and invoke 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%, and the schema already explains both issue_id and project in detail. The description adds only a concrete call example with get_issue('0042'), which reinforces but does not materially extend the schema meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Read one specific issue's full history by ID'. It also functionally distinguishes itself from the sibling summary tool by saying it provides one issue's context 'instead of the whole summary', so an agent can tell it apart from get_summary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear usage condition: 'Use this when you only need one issue's context instead of the whole summary.' It implies the alternative is a summary-level tool, aligning with get_summary, though it does not explicitly name the sibling or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_planA
Read plan.md — the project's INTENT file (ideas + plans).
Call this at session start alongside get_summary(). plan.md records what
the team MEANS to do (ideas, active plans, next steps) — distinct from
the event log, which records what HAPPENED. When the user shares an idea
or a plan, edit plan.md directly (add a bullet, check items off, move
done work to Shipped); do NOT log plans as events.
Read-only. Returns 'No plan found.' if plan.md hasn't been initialized.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden and meets it: it states 'Read-only' and discloses the edge-case return value, "Returns 'No plan found.' if plan.md hasn't been initialized." This is the key behavioral information an agent needs for a simple file-read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose in the first sentence and every subsequent sentence adds distinct value: session-start usage, intent-vs-event distinction, editing guidance, read-only behavior, and missing-file result. There is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter read tool with an output schema, the description fully covers what the tool does, when to invoke it, how it relates to other data sources, and its behavior on uninitialized input. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the one optional project parameter is already fully documented in the schema with format, aliases, and omission rules. The description adds no parameter-specific meaning, which matches the baseline for complete schema 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?
Description opens with 'Read plan.md — the project's INTENT file', giving a specific verb and resource. It clarifies the semantic scope by distinguishing plan.md (what the team MEANS to do) from the event log (what HAPPENED), so it is not confused with event-log read tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to call it: 'Call this at session start alongside get_summary().' It also gives a when-not instruction: when the user shares an idea/plan, edit plan.md directly and 'do NOT log plans as events', preventing misuse of event-log tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_project_mapA
Read PROJECT_MAP.md to understand the repo structure.
Call this at session start when structure matters (file layout,
entry points, ownership). Cheaper than scanning the filesystem.
Read-only. Returns 'No project map found.' if PROJECT_MAP.md hasn't
been initialized — run `pjm init` first if so.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full burden and does well: it declares 'Read-only,' specifies the exact return message when PROJECT_MAP.md is missing, and notes the prerequisite to run `pjm init` first. It also adds a performance trait ('Cheaper than scanning the filesystem').
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 concise sentences, each with a distinct purpose: what it does, when to use it, and its read-only/missing-file behavior. 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 single-optional-parameter read tool with a full output schema, the description covers the important operational details: when to call it, read-only nature, missing-file behavior, and initialization prerequisite. The parameter semantics live in the schema, so nothing essential 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?
The input schema already documents the optional project parameter in depth (registered id, alias, path, omit conditions, and a pointer to list_projects), and coverage is 100%. The description adds no parameter-specific guidance, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Read PROJECT_MAP.md') and explains its purpose ('understand the repo structure'). It further distinguishes this tool from filesystem traversal by noting it is 'Cheaper than scanning the filesystem,' and its unique focus on file layout, entry points, and ownership separates it from sibling tools like get_summary or get_context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit timing ('Call this at session start') and conditions ('when structure matters'), and names an alternative approach (filesystem scanning) with a cost comparison. It does not explicitly list when-not-to-use cases, but the conditional 'when structure matters' implies the boundary, so clear context but no formal exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scoreA
Get the project's failure-prevention score.
Returns an A+→F grade with concrete ROI numbers: debugging hours
saved, tokens prevented, dollars protected. Use when the user asks
about progress or value.
Read-only; computes the score from events.jsonl on each call.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the behavioral burden. It explicitly says 'Read-only' and 'computes the score from events.jsonl on each call,' which tells the agent the tool is safe and reflects current data rather than cached results. It does not discuss failure modes or file-missing behavior, but for a simple read-only computation the disclosure is strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short, purposeful sentences: what it does, what it returns, when to use it, and how it behaves. The most important info is front-loaded, with no filler or repetition of schema details. It is concise without being under-specified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that the output schema exists, the description does not need to explain return shape in detail, yet it already summarizes the grade and ROI components. The optional parameter is fully documented in the schema, and the description covers usage timing and read-only behavior. Nothing essential is missing for an agent to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Parameter schema coverage is 100%, and the schema description already explains the optional 'project' parameter, its default, when to omit it, and how to discover valid values via list_projects. The tool description adds no new parameter semantics, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get the project's failure-prevention score.' It clarifies what the tool produces (an A+→F grade plus ROI numbers), making it easy to distinguish from siblings like get_summary or get_context. This is more than a tautology and directly supports correct selection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states clearly when to use it: 'Use when the user asks about progress or value.' It does not explicitly name alternative tools or provide when-not-to-use guidance, but the when-to-use condition is concrete and actionable. The read-only note also helps set expectations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_summaryA
Read the project memory summary.
MANDATORY: call this BEFORE answering ANY question about the project.
Do NOT answer from conversation history alone.
Do NOT re-scan source files (package.json, README, src/) to understand
the project — `summary.md` is the distilled authoritative source and
costs ~500 tokens versus ~5,000 to re-derive.
Your prior assumptions about this project may be stale. Call this
cheaply at session start (and again before ending) to verify your
work is recorded.
Read-only; does not modify memory or trigger event logging.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility for behavioral disclosure. It clearly states the tool is read-only, does not modify memory, and does not trigger event logging. It also reveals performance characteristics (~500 tokens vs ~5,000) and warns that prior assumptions may be stale, which is valuable context beyond any structured metadata.
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?
Every sentence earns its place: a clear first line, mandatory usage, explicit exclusions, a cost comparison, a staleness warning, and a safety declaration. The structure front-loads the core action and then layers guidance, with no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-optional-parameter schema and the presence of an output schema, the description is fully sufficient. It covers what the tool does, when to call it, how it behaves, and its safety profile. No important operational dimension 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?
The input schema already provides rich, 100% coverage of the optional 'project' parameter, including when to omit it, examples, and how to list valid names. The description itself adds no additional parameter-level semantics, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence 'Read the project memory summary' states a specific verb and resource, and the rest of the description clarifies it is the distilled authoritative source. However, it does not explicitly distinguish itself from sibling tools like get_instructions, get_context, or get_project_map, so it falls just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit, forceful usage guidance: it is MANDATORY before any question, should not be replaced by conversation history, and should not be substituted by re-scanning source files. It also specifies when to call it again (before ending) and notes the token cost tradeoff. This leaves no doubt about when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_projectsA
List the projects this server can reach, and which one is active.
Call this when a tool answers "No project selected", or when you need the
exact name to pass as `project`. Read-only; touches no project memory.| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full behavioral burden. It discloses 'Read-only; touches no project memory', which is a meaningful side-effect guarantee the agent could not infer from the schema. It also reveals the output's key trait (active project) beyond a mere listing.
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 in logical order: what it does, when to call it, and its safety guarantee. Every sentence earns its place; the trigger conditions are front-loaded and the read-only note closes it efficiently.
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 zero-parameter list tool with an output schema present, the description covers what is returned, the two scenarios that warrant calling it, and the safety profile. Nothing an agent needs to invoke 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?
Tool has 0 parameters, so the baseline is 4. The schema is an empty object and the description appropriately doesn't invent parameter details. Mentioning the `project` parameter of other tools is contextual routing guidance, not parameter documentation, and it aids correct invocation.
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 ('List'), a defined resource ('projects this server can reach'), and the distinguishing output ('which one is active'). This differentiates it from the sibling current_project, which presumably returns only the active project rather than the full set.
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?
Provides explicit trigger conditions: 'Call this when a tool answers "No project selected"' and 'when you need the exact name to pass as `project`'. It gives clear context for when to invoke, though it doesn't name sibling alternatives or spell out when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
log_issueA
Open a new issue. Returns the issue ID.
MANDATORY: call this IMMEDIATELY when you encounter a bug, regression,
or unexpected behavior — BEFORE writing fix code. Logging up-front
means the issue survives interruptions and session boundaries.
Side effects: appends an `issue` event to .projectmem/events.jsonl,
creates an issue file in .projectmem/issues/, updates summary.md,
and marks this issue as the active one for subsequent
record_attempt calls.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. | |
| summary | Yes | One-line description of the bug or unexpected behavior (~140 chars recommended). Becomes the issue title and is matched by search_events. | |
| location | No | Optional file path or component where the issue manifests (e.g., 'src/auth.py' or 'login/double-submit'). Used by precheck_file to surface this history later. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It explicitly enumerates side effects: appending an event, creating an issue file, updating summary.md, and marking the issue as active for record_attempt calls. It also states the return value, making the tool's persistence behavior transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the core purpose and return value. The mandatory usage instruction and side-effect list each serve a distinct purpose, with no filler or redundant statements.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity and the presence of an output schema, the description is complete: it covers what the tool does, when to call it, what it returns, and all important side effects. The schema covers parameter semantics, so nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents project, summary, and location thoroughly. The main description adds no meaning beyond the schema, which meets the baseline but does not elevate the score.
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 opens with 'Open a new issue. Returns the issue ID.' This names a specific verb and resource, and the word 'new' distinguishes it from read-oriented siblings like get_issue. The purpose is immediately obvious and not a tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to call the tool: 'MANDATORY: call this IMMEDIATELY when you encounter a bug, regression, or unexpected behavior — BEFORE writing fix code.' It gives clear timing and condition context, though it does not explicitly name alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
precheck_fileA
Check a file's failure history BEFORE modifying it.
MANDATORY: call this BEFORE proposing any change to a file.
Surfaces failed past approaches, unresolved issues, and high churn
so you don't repeat known dead-ends. Cheap (~100 tokens) and prevents
expensive re-debugging cycles.
Read-only; does not modify memory.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. | |
| file_path | Yes | Project-relative or absolute file path to check (e.g., 'src/auth.py'). Matched against the `location` field of logged events — no file content is read from disk. Returns 'no warnings' if the file has no failure history. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and meets it: it discloses read-only behavior, no memory modification, what the tool surfaces (failed approaches, unresolved issues, high churn), and approximate cost. This gives the agent an accurate safety and side-effect profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the core purpose and mandatory instruction appear first, followed by cost, output value, and safety in short sentences. No sentence is filler; every sentence contributes to correct usage.
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 two-parameter, single-required-field tool with a rich output schema and no annotations, the description provides all needed context: when to use it, what it surfaces, cost, and side-effect safety. Nothing critical is missing for an agent to select and invoke 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% and both parameters are richly documented in the input schema, including project resolution and file_path matching semantics. The main description adds no additional parameter-level meaning, so this sits at the high-coverage baseline of 3.
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 first sentence names a specific verb and resource — checking a file's failure history before modification — which clearly differentiates it from the generic sibling tools like search_events or get_issue. The focus on per-file past failures and churn makes the tool's purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs agents to call this tool before proposing any change to a file and explains why: to avoid repeating failed approaches and expensive re-debugging. It does not name excluded cases or alternative tools, but the when-to-use guidance is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_attemptA
Record a fix attempt on the current issue.
MANDATORY: call IMMEDIATELY after each distinct fix attempt — do NOT
batch multiple attempts into one call.
`outcome` must be 'worked', 'failed', or 'partial'. Pass `issue_id`
explicitly to attach to a specific issue; otherwise the attempt
attaches to the active issue. If no active issue exists, an implicit
parent issue is auto-created from this attempt's text (L-008).
Side effects: appends an `attempt` event and updates the issue file.
Does NOT close the issue — call record_fix for that.| Name | Required | Description | Default |
|---|---|---|---|
| outcome | No | Result of the attempt. Must be exactly one of 'worked', 'failed', or 'partial'. Defaults to 'failed' — the safer default when an outcome is uncertain. | failed |
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. | |
| summary | Yes | One-line description of what you tried (e.g., 'tried contain: layout — preview still jumps'). | |
| issue_id | No | Optional zero-padded issue ID (e.g., '0042') to attach this attempt to. When omitted, attaches to the active issue; if no active issue exists, an implicit parent issue is auto-created from this attempt's text. | |
| location | No | Optional file path or component touched by this attempt. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations to carry the burden, the description explicitly discloses side effects: it 'appends an attempt event and updates the issue file,' auto-creates an implicit parent issue when none exists, and clarifies it does not close the issue. This is exactly the behavioral context an agent needs for a mutating tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with MANDATORY, outcome, issue-attachment, and side-effect sections, and it front-loads the purpose. A few sentences restate schema details, but the overall size is justified by the behavioral caveats.
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?
An output schema is present so return values need no explanation. The description covers side effects, auto-created parent issues, and the record_fix boundary. It could more explicitly distinguish itself from log_issue/add_decision, but the 'fix attempt' framing supplies that context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces the outcome enum and issue_id fallback, and adds the rationale that 'failed' is the safer default, but does not add substantial meaning beyond the already-detailed schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ('Record a fix attempt on the current issue') and immediately differentiates itself from the closest sibling by stating 'Does NOT close the issue — call record_fix for that.' An agent can tell this tool from record_fix, log_issue, and add_note contextually.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The MANDATORY line gives an explicit invocation trigger ('immediately after each distinct fix attempt') and an exclusion ('do NOT batch multiple attempts'). It also explains when to pass issue_id versus rely on the active issue, and directs the agent to record_fix for closing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_fixA
Record a confirmed fix and close an issue.
Only call AFTER you have evidence the fix works: test passes, error is gone,
or the user confirmed.
If `issue_id` is provided, the fix is attached to that specific issue.
If `issue_id` is omitted, the active issue is closed.
Side effects: appends a `fix` event and updates summary.md. The active-issue
marker is cleared only when the active issue is the issue being fixed.| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. | |
| summary | Yes | One-line description of the confirmed fix (e.g., 'guarded submit handler with isSubmitting ref'). | |
| issue_id | No | Optional zero-padded issue ID (e.g., '0042') to close. When omitted, closes the active issue. Numeric strings without padding are accepted. | |
| location | No | Optional file path or component where the fix was applied. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does so well. It discloses concrete side effects: appends a fix event, updates summary.md, and clears the active-issue marker only when the active issue is the one being fixed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, followed by a crisp precondition, concise parameter behavior, and side effects. Every sentence earns its place with no redundant wording or restating of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the essential context: when to call, what it does with or without issue_id, and what side effects to expect. It does not explicitly state what happens if there is no active issue and issue_id is omitted, but the overall guidance is sufficient for correct invocation in normal use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema: issue_id omitted closes the active issue, omitted project implies active project, and summary should be a one-line description. This enriches the agent's understanding of the parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action—record a confirmed fix and close an issue—and clarifies the issue_id behavior clearly. This distinguishes it from siblings like record_attempt (recording a try) and log_issue (logging a problem), so agents can pick it correctly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Only call AFTER you have evidence the fix works' and explains the conditional behavior when issue_id is provided versus omitted. It does not name alternative sibling tools, but the precondition and selection logic are clear enough for correct use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_eventsA
Plain-text search across all logged events.
Token-efficient alternative to get_summary when you only need events
matching a keyword. Returns matching event summaries with type and
timestamp.
Read-only. Case-insensitive substring matching against each event's
summary and notes. Empty result returns a friendly message, not an
error.| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of matching events to return (most recent first). Defaults to 10. Recommended range: 1-100. | |
| query | Yes | Case-insensitive substring matched against each event's summary and notes. Plain text only — no regex or boolean operators. | |
| project | No | Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the operation is read-only, specifies case-insensitive substring matching against summary and notes, and explains that an empty result returns a friendly message rather than an error.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short, front-loaded paragraphs. Every sentence adds value: the search scope, the alternative tool, the matching behavior, and the empty-result behavior. There is no filler or redundant restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 100% schema coverage and presence of an output schema, this description is complete enough for an agent to call the tool correctly. It explains the search scope, the matching rules, the read-only nature, and how empty results are handled.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all parameters with 100% coverage. The description mostly restates the query semantics already present in the schema rather than adding new parameter-level meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Plain-text search across all logged events.' It also clearly states the return value (matching event summaries with type and timestamp) and distinguishes itself from get_summary, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names get_summary as the alternative and gives the condition for choosing this tool: when you only need events matching a keyword. This is direct, actionable usage guidance with no need for inference.
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.
17 tool updates
v0.3.2- Changed
add_decision1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
add_note1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Added
current_project - Changed
get_context1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
get_global_gotchas1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
get_instructions1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
get_issue1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
get_plan1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
get_project_map1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
get_score1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
get_summary1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Added
list_projects - Changed
log_issue1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
precheck_file1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
record_attempt1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
record_fix1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
- Changed
search_events1 field changed- added
Input schema / properties / projectAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Which project this call is about — a registered id, alias, or absolute path (e.g. 'ossdrop'). Omit it when the server was started for a single repo, or when an active project is set with `pjm project use`. Call list_projects to see the registered names.", + "title": "Project" +}
1 tool update
v0.2.0- Added
get_plan
1 tool update
v0.1.5- Changed
record_fix1 field changed- added
Input schema / properties / issue_idAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Optional zero-padded issue ID (e.g., '0042') to close. When omitted, closes the active issue. Numeric strings without padding are accepted.", + "title": "Issue Id" +}
1 tool update
v0.1.4- Changed
add_decision1 field changed- added
Input schema / properties / supersedesAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Optional event id (evt_...) of a prior decision this one retires. The old event stays in the log tagged (superseded); only the new decision appears in summary.md. Use when precheck_file flags a decision as possibly stale and you are revising it.", + "title": "Supersedes" +}
10 tool updates
v0.1.3- Changed
add_decision2 fields changed- added
Input schema / properties / location / descriptionAdded value: +"Optional file path or scope where the decision applies (e.g., 'src/auth/' for a module-level choice). Helps precheck_file cite the decision when the file is later touched." - added
Input schema / properties / summary / descriptionAdded value: +"One-line description of the architectural or product decision (e.g., 'use bcrypt rounds=12 for password hashing'). Becomes part of the project's permanent record — write it for a future contributor."
- Changed
add_note2 fields changed- added
Input schema / properties / location / descriptionAdded value: +"Optional file path or library this note applies to (e.g., 'bcrypt' for a library-specific gotcha)." - added
Input schema / properties / summary / descriptionAdded value: +"One-line description of the gotcha, setup detail, or context worth preserving. Prefix with 'gotcha:' or 'lesson:' to enable cross-project promotion — e.g., 'gotcha: bcrypt v4 silently truncates passwords longer than 72 bytes'."
- Changed
get_context4 fields changed- added
Input schema / properties / focus / descriptionAdded value: +"Optional path prefix or keyword to bias selection toward (e.g., 'src/auth/'). When omitted, the context is project-wide." - added
Input schema / properties / tokens / descriptionAdded value: +"Approximate target token budget for the returned markdown (default 2000). Output may be slightly over or under as events are included as whole units. Recommended range: 500-8000." - added
Input schema / properties / tokens / maximumAdded value: +20000 - added
Input schema / properties / tokens / minimumAdded value: +100
- Changed
get_global_gotchas1 field changed- added
Input schema / properties / library / descriptionAdded value: +"Optional library name to filter by (case-insensitive substring match — 'react' also matches 'react-router'). When omitted, returns all gotchas across every library — useful when starting a new feature to scan for any relevant past lessons."
- Changed
get_issue1 field changed- added
Input schema / properties / issue_id / descriptionAdded value: +"Zero-padded 4-digit issue ID returned by log_issue (e.g., '0042'). Numeric strings without padding (e.g., '42') are also accepted."
- Changed
log_issue2 fields changed- added
Input schema / properties / location / descriptionAdded value: +"Optional file path or component where the issue manifests (e.g., 'src/auth.py' or 'login/double-submit'). Used by precheck_file to surface this history later." - added
Input schema / properties / summary / descriptionAdded value: +"One-line description of the bug or unexpected behavior (~140 chars recommended). Becomes the issue title and is matched by search_events."
- Changed
precheck_file1 field changed- added
Input schema / properties / file_path / descriptionAdded value: +"Project-relative or absolute file path to check (e.g., 'src/auth.py'). Matched against the `location` field of logged events — no file content is read from disk. Returns 'no warnings' if the file has no failure history."
- Changed
record_attempt5 fields changed- added
Input schema / properties / issue_id / descriptionAdded value: +"Optional zero-padded issue ID (e.g., '0042') to attach this attempt to. When omitted, attaches to the active issue; if no active issue exists, an implicit parent issue is auto-created from this attempt's text." - added
Input schema / properties / location / descriptionAdded value: +"Optional file path or component touched by this attempt." - added
Input schema / properties / outcome / descriptionAdded value: +"Result of the attempt. Must be exactly one of 'worked', 'failed', or 'partial'. Defaults to 'failed' — the safer default when an outcome is uncertain." - added
Input schema / properties / outcome / patternAdded value: +"^(worked|failed|partial)$" - added
Input schema / properties / summary / descriptionAdded value: +"One-line description of what you tried (e.g., 'tried contain: layout — preview still jumps')."
- Changed
record_fix2 fields changed- added
Input schema / properties / location / descriptionAdded value: +"Optional file path or component where the fix was applied." - added
Input schema / properties / summary / descriptionAdded value: +"One-line description of the confirmed fix (e.g., 'guarded submit handler with isSubmitting ref')."
- Changed
search_events4 fields changed- added
Input schema / properties / limit / descriptionAdded value: +"Maximum number of matching events to return (most recent first). Defaults to 10. Recommended range: 1-100." - added
Input schema / properties / limit / maximumAdded value: +100 - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / query / descriptionAdded value: +"Case-insensitive substring matched against each event's summary and notes. Plain text only — no regex or boolean operators."
14 tool updates
v0.1.1- First observed
add_decision - First observed
add_note - First observed
get_context - First observed
get_global_gotchas - First observed
get_instructions - First observed
get_issue - First observed
get_project_map - First observed
get_score - First observed
get_summary - First observed
log_issue - First observed
precheck_file - First observed
record_attempt - First observed
record_fix - First observed
search_events
TDQS
Scored across 17 tools
Most tools have clearly distinct purposes, especially the read/write split and the issue lifecycle (log_issue, record_attempt, record_fix). A few retrieval tools (get_summary, get_context, search_events, get_issue) overlap in intent, but their descriptions provide strong usage guidance.
The server uses a mostly consistent snake_case verb_noun pattern (get_*, log_issue, add_note). The main deviation is current_project, which is noun-only, and the verbs log/record/add are near-synonyms, creating slight stylistic inconsistency.
At 17 tools, the set is slightly over the typical 3-15 well-scoped range, so it feels a bit heavy. However, the count is justified by the breadth of project memory functionality: separate read, write, issue-lifecycle, and cross-project tools.
The issue lifecycle is well covered (log, attempt, fix, read), and durable memory capture (decisions, notes, gotchas) is solid. Minor gaps exist around updating or deleting existing records, though the append-only design makes that intentional.
Maintenance
Related MCP Connectors
Shared memory for coding agents. Stop re-explaining your codebase every session.
Persistent cross-session memory shared by Codex, Claude Code, ChatGPT, and other AI agents.
Shared memory for AI coding agents. Save once, reuse from Cursor, Claude Code, Codex.
Universal memory for AI agents and tools. Save, organize and search context anywhere.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceA robust server for managing long-term agent memory using Mem0, providing efficient storage and retrieval of agent memories with a lightweight Python-based implementation.MIT
- AlicenseAqualityDmaintenanceProvides versioned, structured memory for AI agents, allowing them to store facts, detect conflicts, and track knowledge history via a hosted SaaS platform. It enables efficient hierarchical information retrieval and semantic search while keeping token usage constant as memory scales.718 npm8Apache 2.0
- AlicenseBqualityBmaintenancePersistent memory and session intelligence for AI coding assistants. Auto-tracks mistakes, decisions, and context via hooks. Mines your full session history for patterns, predictions, and cross-session search.2116MIT
- AlicenseNot gradedqualityCmaintenanceProvides a memory layer for AI coding agents with Git-powered version control, enabling automatic tracking of prompts, context, and code diffs.192MIT