projectmem
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Local-first memory layer for AI coding agents. Captures issues, attempts, decisions, and cross-project library gotchas — your AI starts experienced, not amnesiac. Native MCP server verified across Claude Desktop, Cursor, Antigravity, and Codex. 100% local · no cloud · no telemetry · MIT.
We don't make AI smarter. We make it experienced.
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
🎬 Watch the demo
Full screen-recorded tutorial- watch on YouTube
📚 Docs
| Doc | What's in it |
|---|---|
| TUTORIAL.md | 15-minute step-by-step walkthrough — set up projectmem on your own project, watch the lifecycle, see the pre-commit warning fire. |
| CHANGELOG.md | Release history. Latest: v0.1.4 — the accountable-judgment release: stale-memory detection, decision supersede, precheck snooze, pjm brief, failed-approach surfacing, CLAUDE.md export, dashboard Overview. |
| Research paper (arXiv:2606.12329) | 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. |
| LICENSE | 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
pip install projectmem
cd your-project
pjm init
That'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.
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. 14 native tools force the AI to read context, check files for known failures, and log work automatically. Verified end-to-end against all four clients.
- Interactive Dashboard —
pjm visualizeopens a four-tab D3.js dashboard: Story Map (failure heatmap), ROI Dashboard, Project Map (tree or graph view), Timeline. - 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 daemon, no ports | ✅ stdio + files | ❌ | ❌ | 🟡 | ❌ server + DB |
| No telemetry, no accounts | ✅ | ❌ default-on | ✅ | ❌ | 🟡 |
| Native MCP server | ✅ 14 focused tools | ✅ | 🟡 53 tools | 🟡 | 🟡 |
| 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).
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 get_summary(), then get_issue(id) only when relevant |
pjm wrap (pre-injection) |
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.
MCP Integration (Recommended)
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.
Paste this block:
"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:
- 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. - 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.
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",
"--root", "/absolute/path/to/your/project"
]
}
}
}
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. - 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.
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"],
"cwd": "/absolute/path/to/your/project"
}
}
}
Then fully quit Antigravity (Cmd+Q on Mac) and reopen — MCP servers only initialize on cold start. All 14 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", "--root", "/absolute/path/to/your/project"]
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. - 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 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 atpython -m projectmem.mcp_server and either set cwd to your project
root or rely on the parent-walk auto-discovery.
MCP Tools Exposed
All 14 tools your AI can call:
Read-side (9 tools):
| Tool | When to use |
|---|---|
get_instructions() |
Start of every session — load workflow rules |
get_summary() |
Start and end — distilled project memory |
get_project_map() |
Start — understand repo structure |
precheck_file(path) |
Before editing any file — surface failure history |
get_issue(id) |
Read one specific issue's full history by ID |
search_events(query) |
Plain-text search across all logged events |
get_context(tokens, focus) |
Token-budgeted memory block with optional focus filter |
get_score() |
A+→F prevention score + ROI numbers |
get_global_gotchas(library) |
Cross-project library lessons inherited from past repos |
Write-side (5 tools):
| Tool | When to use |
|---|---|
log_issue(summary, location) |
Immediately when encountering a bug |
record_attempt(summary, outcome) |
Immediately after each fix attempt (outcome: failed/partial/worked) |
record_fix(summary) |
After confirming a fix resolves the issue |
add_decision(summary, supersedes?) |
When making architectural / design decisions; pass supersedes to retire a stale decision without losing history |
add_note(summary) |
When discovering gotchas, setup details, or constraints |
CLI Reference
Core memory
| Command | Purpose |
|---|---|
pjm init |
Initialize memory + auto-install hooks + inherit global memory |
pjm log <text> |
Start a new issue / debugging session |
pjm attempt <text> [--failed|--worked] |
Record a fix attempt outcome |
pjm fix <text> |
Record the confirmed fix and close the issue |
pjm decision <text> [--supersedes <id>] |
Record an architectural decision; optionally retire a prior one (old event stays in the log, tagged) |
pjm note <text> |
Record durable context or a gotcha |
pjm show |
Print the current summary |
pjm search <query> [--failed-only] |
Plain-text search across all events; --failed-only lists the project's dead ends |
pjm brief |
One-screen session-start briefing: warnings, stale memories, open issues, decisions, score |
pjm export [--claude-md|--cursor] |
Compile live memory into CLAUDE.md / .cursorrules for agents without MCP |
Intelligence layer
| Command | Purpose |
|---|---|
pjm watch [--daemon|--stop|--status] |
Real-time file churn watcher |
pjm precheck [--snooze 2h|--unsnooze] |
Warn about repeating failed approaches before commit; snooze politely (audited) when needed |
pjm wrap <agent> |
Inject token-budgeted memory into Claude/Cursor/Aider |
pjm context [--tokens N] |
Generate token-budgeted project context |
pjm score [--format text|json|badge] |
Letter-grade prevention score |
pjm global <action> |
Manage cross-project memory |
Visualization & utility
| Command | Purpose |
|---|---|
pjm visualize |
Open interactive D3.js dashboard |
pjm stats |
Token ROI summary in the terminal |
pjm backfill |
Auto-populate memory from git history |
pjm hooks install|uninstall |
Manage git hooks manually |
pjm regenerate |
Rebuild summary.md from events.jsonl |
Use
--at "file.py:42"with any logging command to attach precise location metadata.
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 ergonomic - Model 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 [email protected] 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 →
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found