Projectmem
About
Local-first memory and judgment layer for AI coding agents. Captures issues, failed attempts, fixes, and decisions in readable Markdown + JSONL, re-injects them into future sessions, and warns at git commit before you repeat a mistake. 14 tools, works with Claude, Cursor, Antigra
Details
- Author
- riponcm
- Downloads
- 370
- Categories
- Other, Developer Tools, AI, Automation
Jump to
- Persistent project memory across every session
- Pre-commit warnings before repeating a failed approach
- 14 MCP tools for reading and writing memory
- 100% local, no cloud or telemetry
- Works with Claude, Cursor, Antigravity, and Codex
- Reduces context‑rebuilding tokens by up to 50%
Setting up with Highlight
This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:
- Download and install Highlight from highlightai.com/download
- Navigate to the plugins tab and select "Add Custom Plugin"
-
Configure the plugin with the settings below
Plugin Name
ProjectmemCommand (node, npx, python, etc.)Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.
- Enable "Start Automatically" if you want the plugin to start when Highlight launches
From the repository
Install with pip install projectmem, then configure your MCP client with command: "pjm-mcp" and args: ["--root", "/absolute/path/to/your/project"]. The server exposes 14 MCP tools that your AI client can use to read and write project memory directly.
Claude Desktop / Cursor
Paste into your MCP client config file to install this server.
{
"mcpServers": {
"projectmem": {
"projectmem": {
"command": "pjm-mcp",
"args": [
"--root",
"/absolute/path/to/your/project"
]
}
}
}
}
McpServers
{
"projectmem": {
"command": "pjm-mcp",
"args": [
"--root",
"/absolute/path/to/your/project"
]
}
}
We don't make AI smarter. We make it experienced.
AI coding memory— the local-first memory + judgment layer for AI coding agents. Save up to 50%+ of AI tokens. Stop repeating yesterday's bug.
Website•Guide•Demo•Changelog•Paper
AI coding 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-sourceagent memorylayer built for that job. It islocal-first: memory lives in a plain.projectmem/directory inside your repository, with no cloud, no account and no telemetry. A nativeMCP serverexposes 15 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 storestyped events— issues, attempts, fixes, decisions, notes — which is what makes the one thing no other tool does possible: apre-commit warningthat firesbeforeyou repeat an approach that already failed.
pip install projectmem cd your-project && pjm init
Full screen-recorded tutorial- watch on YouTube
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.
projectmemis 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 trackswhatchanged.projectmemtrackswhyit changed, what was tried, and what failed.
pip install projectmem cd your-project pjm init
That's it.pjm initinstalls 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 isprojectmem. Apjmalias is installed for speed.
0.1.6 madeoneproject's memory something you could watch.0.2.0 lifts that to your whole workspace — and closes the gap between whathappened(memory) and what your codeis(structure).
- 🌐Global dashboard—pjm dashboardis one page overeveryproject 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 globalview, 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+Cstops 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'sGraphandFlowviews 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 everread.
- 🔥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 youmeanto do— deliberatelynotthe 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.
Global Dashboard — everypjm init-ed project in one view: grades, issues, savings, and a "needs attention" list, aggregated at read time. Each card opens that repo's own dashboard.
The visualization suite (shipped in 0.1.6)
Your project's memory is also something you canwatch— 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), andUniverse(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 readingPROJECT → 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, withproblems branching left(issues, failed attempts) andknowledge branching right(fixes, decisions, notes). Hover any card and its whole issue thread lights up. The classic list remains as "Details".
Showoff · Universe — every bright star is a real event from this project's memory
Project Map · Flow — what happened, file by file, flowing into append-only memory
Timeline · Time Spine — problems on the left, knowledge on the right, real time down the middle
- Pre-Commit Warnings—pjm precheckwarns youbeforeyou 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; projectmemnever deletes. Every decision that cites a file is cross-checked against that file's git history — when the file has moved on, the memory isflagged("predates 7 commits to auth.py — confirm or supersede") and a human decides. Retire it cleanly withpjm 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 bypjm 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 yourplan.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), andShowoff— animated story scenes with a built-in video recorder.
- 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 globalview, never a globalstore— 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 overlaysfailure heatfrom 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 youmeanto do), kept deliberately apart from the append-only event log (whathappened).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.
✅ 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 isno databaseandnothing 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 theoptionalpjm dashboard --serve, an ephemeral local viewer you start and stop with Ctrl+C — never a background service.
- Import your existing memory—pjm import(planned for 0.2.1)will migrate history frommem0,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 issueand 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.
AI never readsevents.jsonldirectly.That file is for tools (pjm score,pjm context,pjm wrap). Tools distill the raw log into compact AI-readable summaries.
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.
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 toolso 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.
- 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.jsonon macOS,%APPDATA%\Claude\claude_desktop_config.jsonon Windows.
"mcpServers": { "projectmem": { "command": "/opt/anaconda3/bin/python", "args": [ "-m", "projectmem.mcp_server", "--root", "/absolute/path/to/your/project" ] } }
- Use the absolute path topython(e.g./opt/anaconda3/bin/python, or runwhich pythonto find yours). Claude Desktop subprocesses don't inherit your shellPATH, so bare"python"often fails.
- We pass the project root via--root, not thecwdJSON field.Claude Desktop's current build (with the Epitaxy / Cowork workspace system) silently ignores thecwdfield — the server ends up running withcwd=/and can't find.projectmem/. The--rootflag is honored by projectmem directly (read fromsys.argv) and works regardless of how Claude Desktop spawns the subprocess.
Thenfully quit Claude Desktop (Cmd+Q on Mac)and reopen — MCP servers only initialize on cold start.
Two ways to register the MCP server — pick whichever fits your workflow:
- Global (recommended):Cursor menu →Settings…→ left sidebarTools & 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", "--root", "/absolute/path/to/your/project" ] } } }
Two things to know about this block (same gotchas as Claude Desktop):
- Use the absolute path topython(runwhich pythonto find yours). Cursor subprocesses don't reliably inherit your shellPATH.
- Pass the project root via--root, not thecwdJSON field.Cursor — like Claude Desktop — silently ignorescwd: the server ends up running withcwd=~and can't find.projectmem/. The--rootflag is honored by projectmem directly and works around the bug.
Thenfully quit Cursor (Cmd+Q on Mac)and reopen. projectmem also auto-discovers.projectmem/by walking up from CWD (like git does for.git/), and honorsPROJECTMEM_ROOTand a--root <path>CLI argument.
Antigravity (Google's AI IDE) speaks standard MCP.
- Open theAgentwindow (the chat panel on the right).
- Click the⋯ Additional Optionsbutton in the panel header.
- ChooseMCP Servers→Manage MCP Servers→Add new(orEdit Config).
The raw file is at~/.gemini/antigravity/mcp_config.jsonif you prefer editing it directly.
{ "mcpServers": { "projectmem": { "command": "python", "args": ["-m", "projectmem.mcp_server"], "cwd": "/absolute/path/to/your/project" } } }
Thenfully quit Antigravity (Cmd+Q on Mac)and reopen — MCP servers only initialize on cold start. All 15 projectmem tools register identically to Claude Desktop / Cursor.
Codex stores MCP config asTOML(not JSON) in~/.codex/config.toml. There's a UI form atSettings → MCP Servers → Add MCP Server, but during cross-client verification the form'sSave button didn't reliably persist— the file-edit path is faster and more reliable.
Easiest — edit~/.codex/config.tomldirectly:
Append this block (preserves any existing config):
[mcp_servers.projectmem] command = "/opt/anaconda3/bin/python" args = ["-m", "projectmem.mcp_server", "--root", "/absolute/path/to/your/project"] cwd = "/absolute/path/to/your/project"
- Use the absolute path topython(runwhich pythonto find yours). Codex subprocesses don't reliably inherit your shellPATH.
- Pass the project root via--rootin args(defense in depth). Thecwdfield appears to work in Codex, unlike Claude Desktop and Cursor — but--rootcosts nothing and saves us if any future Codex build regresses.
- Set your reasoning effort tomediumor 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.
python -c "import tomllib; tomllib.load(open('/Users/<you>/.codex/config.toml','rb')); print('OK')"
Should printOK. 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 inps auxright 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 tomedium(notlow) for the full session-start trio behavior. Once set, it persists per-session.
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.
Any MCP-compatible client works — point your tool atpython -m projectmem.mcp_serverand either setcwdto your project root or rely on the parent-walk auto-discovery.
Use--at "file.py:42"with any logging command to attach precise location metadata.
plan.md— intent, kept separate from memory
pjm initscaffolds a.projectmem/plan.md: yourideas and plans — what youmeanto do, in plain Markdown (Ideas · Active plans · Next · Someday · Shipped). It's the one file that is deliberatelynotthe event log:
- events.jsonl → summary.mdrecords whathappened(append-only, never rewritten).
- plan.mdrecords what youintend— and you (or the AI) edit it directly, likePROJECT_MAP.md.
Your AI reads it at session start viaget_plan()and updates it in place: adding ideas, checking items off, moving finished work down toShipped. A plan is never logged as an event, so intent stays cleanly out of your memory's audit trail.pjm planprints it;pjm plan "auto-batch the exporter"appends an idea. It's committed (not gitignored) so intent is shared with your team.
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.
By default,projectmemcommits thedistilledfiles (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 — justgit cloneand 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
- 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.
projectmemstands on the shoulders of these excellent open-source projects:
- Typer— the CLI framework that makespjmfeel ergonomic
- Model Context Protocol— Anthropic's open spec that lets AI agents talk to local tools
- watchdog— cross-platform filesystem event monitoring (the heart ofpjm watch)
- D3.js— the interactive visualizations inpjm visualize
projectmem is described in a peer-readable research paper:
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





