{
  "markdown": "# projectmind\n\n**Persistent, compact project memory for AI coding agents.** Your agent reads one\nsmall digest instead of re-scanning the codebase every session — and a local\nledger shows you exactly how many tokens (and dollars) that saved.\n\n[![CI](https://github.com/Nodemint-dev/projectmind/actions/workflows/ci.yml/badge.svg)](https://github.com/Nodemint-dev/projectmind/actions/workflows/ci.yml)\n![tests](https://img.shields.io/badge/tests-85%20passing-brightgreen)\n![platforms](https://img.shields.io/badge/platforms-linux%20%7C%20macos%20%7C%20windows-blue)\n![node](https://img.shields.io/badge/node-%E2%89%A518-blue)\n![runtime deps](https://img.shields.io/badge/runtime%20deps-2-blue)\n![network calls](https://img.shields.io/badge/network%20calls-0%20(enforced%20by%20CI)-success)\n![license](https://img.shields.io/badge/license-MIT-lightgrey)\n\n![Demo: one projectmind init command scaffolds, seeds, wires every installed agent, gitignores the map, and installs the git hook; the digest opens with the session handoff and projectmind savings shows ~20.5k tokens saved](docs/assets/demo.gif)\n\n![Benchmark: reading the codebase ~1,953 tokens vs projectmind digest ~412 tokens, −78.9%](docs/assets/benchmark.svg)\n\nEvery AI coding session starts the same way: the agent has no memory of your\nproject, so it re-reads files, re-derives your architecture, or asks you to\nre-explain decisions you made months ago. You pay for that in tokens, time, and\nwrong guesses — every single session, on every machine, for every teammate.\n\n`projectmind` fixes this with a **structured, persistent project map**\n(`.projectmind/map.json`): your modules, their dependencies, your architectural\ndecisions, your conventions, your domain glossary. The agent reads a ~400-token\ndigest first, drills into single nodes only when needed, and writes back what it\nlearns — so the *next* session (yours, a teammate's, or a different AI tool's)\nstarts already knowing the project.\n\nThe digest scales with your project's *conceptual* size (modules, decisions),\nnot its *byte* size — so the savings grow with the repo.\n\n## Quick start — one command\n\n```bash\nnpm install -g @nodemint/projectmind\ncd your-repo\nprojectmind init\n```\n\nThat single `init` does everything: scaffolds the map, **seeds it from your\nrepo layout**, detects which AI agents are installed on your machine and\n**wires each one** (MCP server + a rules file carrying the live map), adds\n`.projectmind/` to your `.gitignore` (the map stays local — nothing to push),\nand installs the git hook that keeps the map fresh on every commit.\n\n**Then the one step no tool can do for you: restart your agent** (or start a\nnew chat session). AI agents load their config and rules files at session\nstart — a chat that was already open keeps its old context, and every session\nafter that has the map automatically. Using the VS Code savings extension?\n`Cmd+Shift+P` → *\"Developer: Reload Window\"* once.\n\nWant it available in **every future project without even running `init`**?\n\n```bash\nprojectmind setup --global        # registers the MCP server once, user-wide\n```\n\n(`projectmind init --bare` scaffolds only, and `projectmind setup` re-wires\nagents on demand, if you prefer the pieces separately.)\n\n## See what it saves you — measured, not promised\n\nThe MCP server keeps a **local savings ledger**: every time your agent reads the\nmap instead of scanning files, it records the tokens actually served vs. the\nestimated tokens of the files the agent would have read instead.\n\n![Savings: ~20.5k tokens saved in one scripted day, 22 map reads — mind_digest ~18.5k, mind_query ~1.2k, mind_context ~0.7k](docs/assets/savings.svg)\n\nCheck it anytime:\n\n```\n$ projectmind savings\nprojectmind savings (estimated — local ledger, never leaves this machine)\n\n  Total saved:   ~20.5k tokens across 22 map read(s)\n  ≈ $0.0614 at sonnet-tier input pricing ($3/MTok, as of 2026-06)\n  Today:         ~20.5k tokens (22 read(s))\n\n  By tool:\n    mind_digest      12 reads   ~18.5k saved\n    mind_query        6 reads   ~1210 saved\n    mind_context      4 reads   ~712 saved\n\n  Methodology: tokens ≈ ceil(bytes/4); baseline = files the agent would have read instead.\n```\n\nThe dollar figure needs **zero configuration**: it defaults to Sonnet-tier input\npricing from a built-in table of published rates (Haiku $1 / Sonnet $3 / Opus $5\n/ Fable $10 per MTok input, as of June 2026), and says exactly which assumption\nit used. If you run a different model, set `savings.model` (or an exact\n`savings.inputPricePerMTok`) in `.projectmind/config.json` — but nobody has to.\n\n*(Real output from a scripted day of agent work on the sample project in\n`test/fixtures/` — 12 session starts, 6 module drill-ins, 4 task-context reads.\nReproduce the per-session number with `npm run benchmark`.)*\n\n**VS Code status bar:** the [`integrations/vscode`](integrations/vscode) extension\nshows a live `✦ ~20.5k tokens saved` counter that reads the same local ledger.\nZero dependencies, zero network.\n\nThe ledger is honest by design: every number is labelled an **estimate**\n(`ceil(bytes ÷ 4)`, the rough English+code average), savings are floored at zero,\nand the file is gitignored — it's your private data, on your machine, deletable\nat any time.\n\n**One deliberate gap, stated plainly:** the ledger only counts *tool calls*\n(`mind_digest`, `mind_query`, `mind_context`). The embedded digest described\nbelow never requires a tool call — that's the whole point — so its savings\ndon't show up as a number here. `projectmind savings` names which rules files\ncarry it instead of inventing a token count we can't actually observe.\n\n## Session handoff — pick up exactly where you left off\n\nThe thing every agent session loses is *working state*: what you were in the\nmiddle of, what's next, the gotcha you just discovered. Code graphs can't\ncapture it; chat history dies with the session. projectmind carries it over:\n\n```\n$ projectmind digest\n# shopflow-api — project map\nOrder-management HTTP API with JWT auth, backed by PostgreSQL.\nStack: node, express, postgres\n\n## ⏪ Handoff from last session (2026-07-02)\nAdding refund support to orders-route; next: write the refund tests\n```\n\nYour agent calls `mind_handoff` before the session ends (or before its context\ngets compacted); the note **leads the very next digest**, so the next session —\ntonight on your laptop, tomorrow on your desktop, or a different AI tool\nentirely — resumes in one read instead of re-deriving the task. Notes live in\nyour gitignored local overlay: personal working state, never committed, cleared\nwith `mind_handoff({clear: true})` when done. Humans can use it too:\n`projectmind handoff \"note\"`.\n\n## Works everywhere your team works\n\nNo language assumptions, no platform assumptions: the full test suite (85\ntests, including the git-hook end-to-end and offline-guarantee tests) runs in\nCI on **Linux, macOS, and Windows × Node 18/20/22**. Paths, globs, atomic\nrenames, and the installed git hook are exercised on all three. The map format\nis plain JSON — nothing OS-specific is ever written to your repo.\n\nVerified against real open-source repos (fresh clone → `projectmind init --seed`,\n2026-07-02):\n\n| Repo | Stack detected | Seeded nodes | Repo size (est.) | Digest |\n|------|---------------|--------------|------------------|--------|\n| expressjs/express | node | `examples`, `lib`, `test` | ~175k tokens / 152 files | **~86 tokens** |\n| pallets/flask | python | `examples`, `src`, `tests` | ~153k tokens / 104 files | **~111 tokens** |\n| flutter/pinball | dart, flutter | `lib`, `packages`, `test`, `web` | ~513k tokens / 637 files | **~99 tokens** |\n\nThat's the core scaling property in the wild: the digest tracks a project's\n*conceptual* size, staying ~100 tokens whether the repo is 150k or 500k tokens.\n(A freshly seeded digest is a starter skeleton — a curated map with decisions\nand conventions lands around 400 tokens, like the benchmark fixture. We quote\nthe honest per-session savings number — 78.9% — from the benchmark, not from\nthese whole-repo ratios.)\n\n## How it works\n\n```mermaid\nflowchart LR\n    subgraph agents[\"Your AI agents\"]\n        A1[Claude Code]\n        A2[Cursor]\n        A3[Gemini / Codex / Copilot]\n    end\n    subgraph pm[\"projectmind\"]\n        MCP[\"MCP server\\n(stdio, 6 tools)\"]\n        CORE[\"core\\n(atomic writes, schema-validated)\"]\n        HOOK[\"git post-commit hook\\n+ watch mode\"]\n    end\n    subgraph repo[\"Your repo\"]\n        MAP[\".projectmind/map.json\\nnodes · edges · decisions\\nconventions · glossary\"]\n        DIG[\".projectmind/digest.md\\n+ embedded in CLAUDE.md etc.\"]\n    end\n    LEDGER[\".projectmind/ledger.json\\nlocal savings ledger (gitignored)\"]\n\n    A1 <--> MCP\n    A2 <--> MCP\n    A3 <--> MCP\n    MCP --> CORE\n    HOOK --> CORE\n    CORE <--> MAP\n    CORE --> DIG\n    MCP --> LEDGER\n```\n\nTwo update paths keep the map current **without burning tokens**:\n\n- **Deterministic:** the git hook (and optional `projectmind watch`) map changed\n  files to modules via globs and bump freshness. Pure local computation, zero LLM.\n- **Agent-recorded:** when the agent makes an architectural decision or learns a\n  convention, it calls `mind_update` — a few tokens once, instead of\n  re-discovery every session.\n\nThere is deliberately **no background LLM summarization** — that would burn the\ntokens this tool exists to save.\n\n## What the agent actually reads\n\n```markdown\n# shopflow-api — project map\nOrder-management HTTP API with JWT auth, backed by PostgreSQL.\nStack: node, express, postgres\n\n## Active\n- **auth**: Issues/verifies JWT access tokens; exposes requireAuth Express middleware. [active]\n- **orders-route**: Create and list orders for the authenticated user; totals in integer cents. [active]\n\n## Modules\n- **db**: PostgreSQL pool wrapper: query() helper and withTransaction().\n…\n\n## Key decisions\n- Store money as integer cents, never floats. (2026-06-10)\n- JWT for stateless auth instead of server sessions. (2026-06-15)\n\n## Conventions\n- Never read process.env outside src/config.js.\n…\n```\n\n~412 tokens for the whole thing. The long fields (`notes`, `rationale`, file\nlists) are **excluded from the digest** and only surface through `mind_query` —\ncheap by default, detail on demand.\n\n## MCP tools\n\n| Tool | Purpose |\n|------|---------|\n| `mind_digest()` | **Read first every session.** The compact map. |\n| `mind_context({files})` | **Task-scoped.** Only the modules a task touches + their direct deps. The cheapest read when you know the files. |\n| `mind_query(node)` | Full detail on one node: files, notes, edges. |\n| `mind_search(term)` | Find nodes / decisions / glossary by keyword. |\n| `mind_update(delta)` | Record a structural change, decision, or convention. |\n| `mind_handoff(note)` | Leave a \"resume here\" note that leads the next session's digest. |\n| `mind_stats()` | Map size, digest cost, and your savings ledger. |\n\n## One-command agent wiring — and it doesn't depend on the model choosing to read it\n\n`projectmind setup` idempotently writes the MCP config **and** a workflow\nrules block for each agent — merging into existing configs, never clobbering\n(an unparseable config is backed up and skipped).\n\nHere's the part that matters: MCP tools are a *nudge* — no server can force a\nmodel to call one, so an agent can (and sometimes will) skip `mind_digest` on\na plain \"explain this project\" question, especially mid-task. But rules files\n(`CLAUDE.md`, `.cursorrules`, `.windsurfrules`, `GEMINI.md`, `AGENTS.md`,\n`.github/copilot-instructions.md`) are loaded into every agent's context\n**unconditionally, with zero model choice involved** — that's the actual\nmechanism, not a coincidence. So `setup` doesn't just write instructions to\ncall `mind_digest`; it **embeds the live digest itself** between\n`<!-- projectmind:digest:begin/end -->` markers, and every subsequent\n`mind_update`, CLI edit, git-commit hook run, or `watch` save **re-syncs it\nautomatically**. The project map is present in context from message one, on\nevery agent, with no tool call required at all — the same reliability\nclass as a context-injecting hook, without needing one.\n\n(Only the *repo-committed* map is ever embedded — never your gitignored local\noverlay or handoff notes, so nothing personal leaks into a file you commit.)\n\n| Agent | MCP config | Rules file |\n|-------|-----------|------------|\n| Claude Code | `.mcp.json` | `CLAUDE.md` |\n| Cursor | `.cursor/mcp.json` | `.cursorrules` |\n| Windsurf | `.windsurf/mcp.json` | `.windsurfrules` |\n| Gemini CLI | `.gemini/settings.json` | `GEMINI.md` |\n| Codex / generic | — | `AGENTS.md` |\n| GitHub Copilot | — | `.github/copilot-instructions.md` |\n\nTarget one with `projectmind setup --agent cursor`. Manual wiring is one line\neverywhere:\n\n```json\n{ \"mcpServers\": { \"projectmind\": { \"command\": \"npx\", \"args\": [\"-y\", \"@nodemint/projectmind\", \"mcp\"] } } }\n```\n\n### Install once, use everywhere — global setup\n\n`projectmind setup` above is per-project. Run `projectmind setup --global`\ninstead to register the MCP server **once**, so it's available in every\nproject you open from then on — no per-repo `.mcp.json`, no re-running setup.\nSupported: Claude Code, Cursor, Windsurf, Gemini CLI.\n\n```bash\nprojectmind setup --global\n```\n\nFor Claude Code this shells out to its own `claude mcp add --scope user`\n(the same mechanism tools like codegraph use for global registration) rather\nthan hand-editing its internal config file. For the others it merges into\ntheir global config (`~/.cursor/mcp.json`, `~/.codeium/windsurf/mcp_config.json`,\n`~/.gemini/settings.json`) the same idempotent way the per-project setup does.\n\n**Two things this can't do**, by design:\n- **Rules files stay per-project.** `CLAUDE.md` / `.cursorrules` / etc. are\n  checked-in project conventions — there's no sane \"global\" version of them,\n  so `--global` only registers the MCP *server*, not the nudge-text. Without\n  a project's `.projectmind/` map, `mind_digest` just returns an empty-but-valid\n  digest — harmless, but the agent won't be as strongly reminded to call it.\n- **A chat session already open won't see it.** Every MCP client (Claude Code,\n  Cursor, etc.) loads its server list once at session start — that's an MCP\n  client behavior, not something any server can override. Global scope means\n  every *new* session in every *future* project has it automatically; it does\n  not retroactively add it to a conversation already in progress. Restart the\n  agent once after running `--global`, and you're done for good.\n\n## Where projectmind fits (and what it deliberately isn't)\n\n| | Structural code graphs (e.g. codegraph) | Coding-policy plugins (e.g. ponytail) | **projectmind** |\n|---|---|---|---|\n| Captures | symbols, call paths — the **how** | how agents should write code | intent, decisions, conventions — the **why** |\n| Source | parsed from code | prompt policy | curated by you + your agent |\n| Can it know *why* you chose JWT over sessions? | no | no | **yes** |\n| Carries your working state across sessions | no | no | **yes (handoff)** |\n| Shows you what it saved | no | no | **yes (local ledger)** |\n| Works offline | varies | yes | **always (CI-enforced)** |\n\nYou can't parse *\"money is always integer cents\"* or *\"we chose JWT for\nhorizontal scaling\"* out of source code. That's the layer projectmind owns.\n\nSo it **complements** structural tools instead of cloning them: if a\n`.codegraph/` index exists in your repo, `mind_digest`, `mind_query`, and\n`mind_context` automatically point the agent to codegraph for symbol-level\ndetail. No dependency, no duplication — projectmind is the why, codegraph is\nthe how.\n\n## Keeping the map honest\n\n```\n$ projectmind doctor\nNodes pointing at files that no longer exist:\n  - legacy-auth (globs: src/old-auth/**)\nNodes untouched for more than 90 days:\n  - reports (last touched 2026-03-12, 112 days ago)\n```\n\n- `projectmind doctor` — drift detection: dangling file globs, stale nodes.\n- `projectmind validate` — schema integrity + drift warnings.\n- `projectmind watch` — live freshness on save (`fs.watch`, debounced, local).\n- Corrupt `map.json`? It's backed up to `map.json.corrupt-<ts>` and the session\n  continues with an empty valid map — the agent never crashes on a bad file.\n- Every write is schema-validated and atomic (temp file + `fsync` + rename), so\n  a racing agent and git hook can't corrupt the map.\n\n## The benchmark (reproduce it yourself)\n\n```\n$ npm run benchmark\nProject: sample-project\nBaseline (files an agent would read):  ~1953 tokens  (8 files)\nprojectmind digest:                    ~412 tokens\nSavings:                               78.9%  (~1541 tokens/session)\n```\n\nMethodology, stated plainly: the baseline is the concatenated content of the\nfiles an agent would plausibly read to orient itself (README + package.json +\nall `src/` files of the committed fixture project); tokens are estimated at\n`ceil(chars ÷ 4)`. These are **estimates**, not exact counts — the fixture and\nthe script are in `test/`, so the number is auditable and reproducible. Savings\non a real repo are typically much larger, because real repos have far more than\n8 files while the digest stays roughly constant-size.\n\n## CLI reference\n\n```\nprojectmind init [--seed]                       # scaffold .projectmind/ (+ starter map from repo layout)\nprojectmind seed                                # propose starter nodes (never overwrites curated ones)\nprojectmind setup [--agent <name>]              # wire MCP + rules into agents (default: all)\nprojectmind digest                              # print the digest (what the agent sees)\nprojectmind context [--files a,b] [--node id] [--term t] [--depth 1]\nprojectmind query <id>                          # full node detail\nprojectmind search <term>\nprojectmind add-node <id> \"summary\" [status]    # active | stable | deprecated\nprojectmind add-edge <from> <to> <rel>\nprojectmind decide \"text\" [\"rationale\"]\nprojectmind convention \"text\"\nprojectmind handoff [\"note\"] [--clear]          # leave/show/clear the resume-here note\nprojectmind stats                               # sizes + estimated digest tokens\nprojectmind savings                             # your local savings ledger\nprojectmind validate                            # map integrity + drift warnings\nprojectmind doctor [--stale <days>]             # drift report\nprojectmind watch                               # live freshness updates on save\nprojectmind install-hook                        # git post-commit auto-updater\n\nOptions: --local (per-developer overlay), --root <dir>\n```\n\n## The map, in 20 seconds\n\n```jsonc\n{\n  \"version\": 1,\n  \"project\": { \"name\": \"shopflow-api\", \"stack\": [\"node\", \"express\", \"postgres\"] },\n  \"nodes\": {\n    \"auth\": {\n      \"type\": \"service\",                      // module | component | service | doc | concept\n      \"summary\": \"Issues/verifies JWTs; requireAuth middleware.\",  // one line — the token budget\n      \"files\": [\"src/auth.js\"],               // globs; the hook maps commits → nodes with these\n      \"status\": \"active\",                     // active | stable | deprecated\n      \"notes\": \"Longer detail — never in the digest, only via mind_query.\"\n    }\n  },\n  \"edges\": [{ \"from\": \"auth\", \"to\": \"config\", \"rel\": \"depends-on\" }],\n  \"decisions\": [{ \"id\": \"d3\", \"text\": \"JWT over sessions.\", \"rationale\": \"…\", \"date\": \"2026-06-15\" }],\n  \"conventions\": [\"Money is integer cents.\"],\n  \"glossary\": { \"SKU\": \"Stock Keeping Unit.\" }\n}\n```\n\n**Local-first by default:** `init` gitignores the whole `.projectmind/`\ndirectory — the raw map, your personal overlay (\"mid-refactor on X\",\nhandoffs), and the savings ledger all stay on your machine. Nothing to push,\nnothing to review. The *shareable* knowledge still travels with the repo,\nbecause the digest is embedded in your committed rules files (`CLAUDE.md`\netc.) and auto-synced on every change.\n\n**Team mode (opt-in):** want the full raw map in git so teammates and CI share\none source of truth? Delete the `.projectmind/` line from `.gitignore` —\nthat's the whole switch. Every write is deterministic (sorted keys, atomic),\nso `map.json` and `digest.md` produce clean, reviewable PR diffs. `init` never\noverrides this choice once you've made it.\n\n## Trust FAQ\n\n**Does it send my code anywhere?** No — and you don't have to take our word for\nit. A CI test (`test/offline.test.js`) scans the entire source tree and fails if\nany network API (`http`, `net`, `fetch`, sockets, …) appears. Two runtime\ndependencies (`@modelcontextprotocol/sdk`, `picomatch`), no telemetry, no LLM\ncalls, no accounts.\n\n**What gets committed?** By default, nothing under `.projectmind/` — the map is\nlocal-first and gitignored at `init`. What *is* committed: the digest embedded\nin your rules files (`CLAUDE.md`, `.cursorrules`, …), which is exactly the\npart meant to be shared — and it never includes your personal overlay or\nhandoff notes (regression-tested). Teams can opt into committing the full map\nby removing one `.gitignore` line.\n\n**Are the savings numbers real?** They're honest estimates, clearly labelled,\nwith the methodology printed next to every number and a reproducible benchmark\nin the repo. We'd rather under-claim than exaggerate.\n\n**Does it work in a chat session that's already open?** Partially, and we'd\nrather tell you exactly where the line is: every MCP client loads servers and\nrules files at session start, so a conversation that was open before `init`\nran keeps its old context — no tool (ours or anyone's) can inject into it.\nFrom the very next session on, everything is automatic. If the MCP server was\nalready registered globally (`setup --global`), the `mind_*` tools work even\nmid-session in a brand-new project — only the embedded rules-file digest\nwaits for the next session.\n\n**Can the map rot?** The git hook (installed by `init`) and watch mode keep\nfile↔module freshness current for free; `doctor` flags dangling and stale\nnodes; `validate` checks integrity; and the embedded digest re-syncs on every\nmap write, so what agents see never lags what's recorded.\n\n**Does it lock me into one AI tool?** No. Any MCP-capable agent can use it, the\nrules files cover the rest, and the map itself is plain JSON any tool can read.\n\n## Development\n\n```bash\nnpm install\nnpm test              # 85 tests: schema, atomicity, corruption self-heal, scopes,\n                      # globs, MCP round-trip, ledger, handoff, offline guarantee\nnpm run benchmark     # prints the estimated savings number\n```\n\nMIT © contributors. See [CHANGELOG.md](CHANGELOG.md).\n",
  "bytes": 22449,
  "sha": "80268d2bc989f9e5ab9b8612021f6c3280c013635c21d18533ade7b8d8426a92",
  "repo_slug": "nodemint-dev/projectmind",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_nodemint_dev_projectmind_c31bae9a/readme"
}