{
  "markdown": "<p align=\"center\">\n  <img src=\"assets/logo.png\" alt=\"GraphPilot\" width=\"120\" />\n</p>\n\n<h1 align=\"center\">GraphPilot</h1>\n\n<p align=\"center\">\n  <strong>Structural memory for coding agents.</strong><br />\n  A refactor-safe, branch-aware, evidence-backed code graph that runs entirely on your machine.\n</p>\n\n<p align=\"center\">\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/License-Apache_2.0-blue.svg\" alt=\"License: Apache 2.0\" /></a>\n  <a href=\"https://nodejs.org\"><img src=\"https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg\" alt=\"Node ≥20\" /></a>\n  <img src=\"https://img.shields.io/badge/version-0.1.0-blue.svg\" alt=\"v0.1.0\" />\n  <img src=\"https://img.shields.io/badge/status-alpha-orange.svg\" alt=\"alpha\" />\n  <img src=\"https://img.shields.io/badge/tests-239%20passing-brightgreen.svg\" alt=\"239 tests\" />\n  <a href=\"https://glama.ai/mcp/servers/graphpilot-oss/graphpilot\"><img src=\"https://glama.ai/mcp/servers/graphpilot-oss/graphpilot/badges/score.svg\" alt=\"GraphPilot MCP server\" /></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#quickstart\">Quickstart</a> ·\n  <a href=\"#the-four-tools\">Tools</a> ·\n  <a href=\"#how-it-works\">How it works</a> ·\n  <a href=\"#editor-setup\">Editor setup</a> ·\n  <a href=\"docs/limitations.md\">Limitations</a> ·\n  <a href=\"bench/README.md\">Benchmarks</a>\n</p>\n\n<p align=\"center\">\n  <img src=\"docs/press/hero.gif\" alt=\"GraphPilot demo — install, index, and query a real TypeScript repo in under 30 seconds\" width=\"900\" />\n</p>\n\n---\n\n## What it is\n\nGraphPilot is a local CLI + MCP server that indexes your TypeScript/JavaScript repo into a structural graph (symbols, callers, callees, blast radius) and exposes it to coding agents — Claude Code, Cursor, Cline, Windsurf, Continue — so they stop re-`grep`ping the same files every conversation.\n\nThe problem it solves: agents burn tokens, hallucinate function names, and miss structural relationships (\"what calls this?\", \"what breaks if I rename it?\") because each session starts from zero. GraphPilot is the persistent structural memory in between.\n\n**Token cost drops. Hallucinations drop. Refactors get safer.**\n\nPut a real coding agent (claude-sonnet-4-5) on **40 structural questions about fastify** — a ~300-file Node.js framework — and give it nothing but file reads. Then hand it GraphPilot's four tools and ask the same 40. The agent with GraphPilot uses **61 % fewer tokens**, costs **$3.68 instead of $8.88 — $5.20 saved per session** — and gets **more** of them right, not fewer (37 correct vs 33). Same model, same questions, same repo; the only change is whether the structural index is there. [Reproduce it →](benchmark/README.md)\n\nA separate correctness benchmark backs the savings with precision: on 10 standardized structural queries GraphPilot scores **F1 0.89 vs grep's 0.42** while reading **99.9 % fewer bytes** (721 B vs 528 KB), and the byte-cost win holds at scale — indexing **microsoft/TypeScript** (601 files, 17 k symbols, 70 k call edges in 10 s) gives **sub-millisecond queries** and a **99.99 % bytes-read reduction**. [Full methodology →](bench/README.md)\n\n## One binary, two modes\n\nGraphPilot ships as a single npm package (`@graphpilot-oss/graphpilot`) with two runtime modes — most users run both.\n\n| Mode           | Command                    | What it does                                                                 |\n| -------------- | -------------------------- | ---------------------------------------------------------------------------- |\n| **CLI**        | `graphpilot index <path>`  | Walks your repo, builds the structural graph, writes it to `~/.graphpilot/`  |\n|                | `graphpilot watch <path>`  | Keeps the graph fresh (~10 ms per file save)                                 |\n|                | `graphpilot status <path>` | Health probe — when the graph was last refreshed, file/symbol/edge counts    |\n| **MCP server** | `graphpilot mcp`           | Speaks MCP over stdio — your coding agent calls into this to query the graph |\n\n**The flow:** the **CLI** builds the index once (and `watch` keeps it warm). The **MCP server** is what your coding agent talks to — you never invoke it yourself, you just point your agent's MCP config at `graphpilot mcp` once and the agent spawns it on every session.\n\n<p align=\"center\">\n  <img src=\"docs/diagrams/data-flow.svg\" alt=\"GraphPilot data flow: you run index/watch to build ~/.graphpilot/<repo>/graph.json; the read-only graphpilot mcp server reads it and serves your coding agent over stdio JSON-RPC\" width=\"720\" />\n</p>\n\nIf you only want CLI access to your code graph (no agent), run `graphpilot index` and then `graphpilot stats` / inspect `graph.json` directly. If you only want the agent integration, you still need to run `graphpilot index` once — the MCP server is read-only against the on-disk graph.\n\n## What makes it different\n\nOther code-graph tools treat your repo as a static blob: index once, query forever, no branch awareness, no proof of where an answer came from. GraphPilot is built around three properties none of them ship:\n\n- 🔍 **Evidence anchors.** Every tool response carries `file:line @ sha` on every symbol and call site. The agent can quote the anchor verbatim and you can verify it instantly — hallucinations get exposed the moment you jump to the line.\n- 🌿 **Differential impact.** Pass `since: <commit|branch>` to `gp_impact` and the result is filtered to files your branch actually touches. PR-scoped refactor analysis in one call instead of `git diff | xargs grep`.\n- 🪵 **Worktree-aware by default.** Two `git worktree add`-ed branches naturally produce two separate indexes — no manual config. Run `graphpilot index ./src/feature` from a subdir and it transparently re-roots to the worktree top. Opt out with `--no-worktree`.\n\nAdd to that: **local-first** (no telemetry, no remote calls, enforced by an ESLint policy on `src/` itself), **deterministic** (same repo → same graph), **sub-second incremental** updates via watch mode.\n\n## Quickstart\n\n**Prerequisites**\n\n- Node.js ≥ 20 (`node --version` to check)\n- An MCP-capable coding agent (Claude Code, Cursor, Cline, Windsurf, or Continue)\n- A TypeScript or JavaScript repo to index\n\nEnd-to-end time: ~3 minutes.\n\n**1. Install the CLI**\n\n```bash\nnpm install -g @graphpilot-oss/graphpilot\n# or: pnpm add -g @graphpilot-oss/graphpilot\n# or one-shot, no install: npx @graphpilot-oss/graphpilot <command>\n```\n\nVerify it landed on your `PATH`:\n\n```bash\ngraphpilot --version\n# → 0.1.0\n```\n\nIf you see `command not found: graphpilot`, your global npm bin is not on `PATH`. Run `npm config get prefix` and add `<prefix>/bin` to your shell's `PATH`, or use the `npx` form above.\n\n**2. Build the structural index for your repo**\n\nRun this once per project. It walks your source tree, parses each TS/JS file with tree-sitter, extracts symbols + call edges, and writes the graph to `~/.graphpilot/<repo-id>/graph.json`.\n\n```bash\ngraphpilot index ~/code/my-app\n```\n\nExpect a one-line summary like `indexed 412 files · 3,981 symbols · 7,204 edges · 1.8s`.\n\n**3. Wire it into your coding agent**\n\nGraphPilot speaks MCP over stdio. Add this server entry to your agent's MCP config — every supported client uses the same two-line shape:\n\n```json\n{\n  \"mcpServers\": {\n    \"graphpilot\": {\n      \"command\": \"graphpilot\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\nWhere this file lives depends on the client (`~/.cursor/mcp.json`, `~/.claude.json`, Cline's settings panel, etc.). Pre-made configs with the exact file path for each agent are in [`examples/`](examples/) — copy the one for your client.\n\nRestart the agent. It now has four new tools: `gp_recall`, `gp_callers`, `gp_impact`, `gp_index` — see [The four tools](#the-four-tools) below for what each one does and when the agent should reach for it.\n\n**4. Try it**\n\nAsk your agent a structural question instead of letting it grep:\n\n> _\"Use gp_impact to show me everything that breaks if I rename `parseToken`.\"_\n\nYou should see a response with `file:line @ sha` anchors you can click straight to. If the agent doesn't reach for the tool, prompt explicitly: \"use the `gp_` MCP tools.\" If it can't see them at all, the MCP config wasn't picked up — run `graphpilot doctor` to pinpoint why (or see [`docs/troubleshooting.md`](docs/troubleshooting.md)), then restart the agent.\n\n**5. Keep the index fresh as you edit (optional but recommended)**\n\n```bash\ngraphpilot watch ~/code/my-app\n```\n\nSub-10 ms incremental updates on each file save. Leave it running in a terminal tab.\n\n**6. Drop per-editor routing rules into your repo (optional)**\n\n```bash\ngraphpilot init\n```\n\nAuto-detects which editors you have installed (Cursor, Claude Code, Cline, Windsurf, Continue) and writes the matching rules file (`.cursorrules`, `CLAUDE.md`, etc.) to the current directory. The rules teach the agent to reach for `gp_*` tools before grep.\n\n```bash\ngraphpilot init --all            # write rules for every supported editor\ngraphpilot init --client cursor  # one editor only\ngraphpilot init --dry-run        # preview without writing\n```\n\nFull 5-minute walkthrough with screenshots: [`docs/quickstart.md`](docs/quickstart.md).\n\n## The four tools\n\nGraphPilot exposes four MCP tools. Each one answers a structural question your agent would otherwise solve by grepping and reading files.\n\n### `gp_recall` — find a symbol by name\n\nUse this when the agent asks \"where is X defined?\" or needs to locate a function before reasoning about it.\n\n- **Input:** `{ query, limit?, substring?, path? }`\n- **Returns:** symbols matching the name (exact case-insensitive by default; `substring: true` for partial matches), each with `file:line @ sha`.\n- **Replaces:** `grep -rn \"function X\"` plus reading each hit to find the real definition.\n\n```text\nAgent: gp_recall({ query: \"parseToken\" })\n→ parseToken (function) — src/auth.ts:42 @ a1b2c3d\n  export function parseToken(raw: string): Token | null\n```\n\n### `gp_callers` — list callers (or callees)\n\nUse this when the agent needs to know \"who calls X?\" or \"what does X call?\" — the two fundamental questions of refactoring.\n\n- **Input:** `{ symbol, direction?: 'callers' | 'callees', limit?, includeUnresolved?, path? }`\n- **Returns:** every call edge where the symbol is target (callers) or source (callees), with anchors.\n- **Replaces:** `grep -rn \"X(\"` followed by manual filtering of comments, strings, and renamed shadows.\n\n```text\nAgent: gp_callers({ symbol: \"authenticate\", direction: \"callers\" })\n→ login → authenticate — src/routes/login.ts:18 @ a1b2c3d\n→ refreshSession → authenticate — src/session.ts:64 @ a1b2c3d\n```\n\n### `gp_impact` — blast radius in one call\n\nUse this when the agent asks \"what breaks if I rename X?\" or \"what depends on this?\" — the single most expensive question an agent normally solves.\n\n- **Input:** `{ symbol, depth? (1–5, default 3), since?, path? }`\n- **Returns:** direct callers, transitive callers grouped by BFS depth, tests likely affected, public-API flag, summary stats.\n- **Killer feature:** pass `since: 'main'` and the result is scoped to files your branch actually touches — PR-scoped refactor review without `git diff` gymnastics.\n\n```text\nAgent: gp_impact({ symbol: \"extractSymbols\", depth: 2, since: \"main\" })\n→ Direct callers (2):    indexDirectory, applyUpdate\n→ Depth-2 callers (1):   cmdIndex\n→ Tests affected (3):    tests/indexer.test.ts, tests/symbols.test.ts, tests/cli.test.ts\n→ Public API:            no\n```\n\n### `gp_index` — refresh from inside the agent\n\nUse this after the agent (or the user) has made a batch of structural edits and wants the graph to reflect them without dropping to a shell.\n\n- **Input:** `{ path? }`\n- **Returns:** re-indexes the repo and invalidates the per-path query cache.\n- **Pairs with:** `graphpilot watch` for sub-10 ms incremental updates between explicit re-indexes.\n\n## How it works\n\n<p align=\"center\">\n  <img src=\"docs/diagrams/how-it-works.svg\" alt=\"How GraphPilot works, in two phases. Build time (CLI index/watch): your repo flows through indexer.ts, parser.ts, and symbols.ts + edges.ts, which storage.ts writes to graph.json at ~/.graphpilot/<repo-id>/ (mode 0600). Serve time (read-only MCP server): query.ts reads graph.json, mcp.ts exposes 4 tools over stdio JSON-RPC with evidence anchors, served to Claude Code, Cursor, Cline, Windsurf, and Continue.\" width=\"760\" />\n</p>\n\nData flow is one-way: source → tree → symbols + edges → JSON → query → agent. GraphPilot never modifies your code.\n\nFull pipeline writeup with file references: [`docs/architecture.md`](docs/architecture.md).\n\n## When to use which tool\n\n| If the agent is about to…               | Reach for…                     | Why                                                   |\n| --------------------------------------- | ------------------------------ | ----------------------------------------------------- |\n| `grep` for a function by name           | `gp_recall`                    | One call, no false positives from comments or strings |\n| Read 20 files looking for \"who calls X\" | `gp_callers`                   | Pre-computed reverse index, sub-millisecond           |\n| Plan a rename or signature change       | `gp_impact`                    | Direct + transitive + tests + public-API in one call  |\n| Review a PR's structural blast radius   | `gp_impact({ since: 'main' })` | Differential — only callers your branch touches       |\n| Re-grep after editing several files     | `gp_index`                     | Incremental: lets the next call see your edits        |\n\nFor string literals, error messages, config values, or anything in a language other than TS/JS: **stay with grep.** GraphPilot indexes code structure, not text.\n\n## Editor setup\n\nGraphPilot speaks MCP over stdio, so it works with any MCP-capable client. Ready-to-paste configs live in `examples/`:\n\n| Client                        | Folder                                           |\n| ----------------------------- | ------------------------------------------------ |\n| **Claude Code** (Anthropic)   | [`examples/claude-code/`](examples/claude-code/) |\n| **Cursor**                    | [`examples/cursor/`](examples/cursor/)           |\n| **Cline** (VS Code extension) | [`examples/cline/`](examples/cline/)             |\n| **Windsurf** (Codeium)        | [`examples/windsurf/`](examples/windsurf/)       |\n| **Continue.dev**              | [`examples/continue/`](examples/continue/)       |\n| Any other MCP client          | See [`docs/mcp-setup.md`](docs/mcp-setup.md)     |\n\nEach folder contains: a `README.md` walkthrough, a sample config file with the exact JSON to paste, and (where the client supports it) a routing template so the agent automatically reaches for GraphPilot on structural questions.\n\n## Privacy & security\n\nGraphPilot is **local-first by promise and by build gate**.\n\n- **No telemetry, no remote calls, ever.** Verifiable: `src/` has zero `http`, `fetch`, `axios`, or analytics imports — enforced by an ESLint rule plus a meta-test that proves the rule fires on every banned import.\n- **No `child_process`, no `exec`, no `spawn`.** Git facts are read directly from `.git/` via pure-JS helpers.\n- **Source code never leaves your machine.** Only structural metadata (names, locations, signatures, call relationships) lives in `~/.graphpilot/`.\n- **Signatures are redacted** for common secret patterns (OpenAI/Anthropic `sk-`, GitHub `ghp_`/`ghs_`, AWS `AKIA`, JWTs, PEM headers, Slack/Stripe tokens) before they're written to disk.\n- **Strict file permissions:** dir `0o700`, files `0o600`.\n- **Schema validation on load:** tampered or corrupt `graph.json` falls back to \"no index\" rather than poisoning the agent.\n- **Hand-rolled input validators** on every MCP tool — unknown fields are rejected, every field type-checked, numbers range-checked, strings length-capped.\n\nThreat model and per-defence test references live in [`docs/architecture.md`](docs/architecture.md). Report security issues per [`SECURITY.md`](SECURITY.md).\n\n## Limitations\n\nGraphPilot v0.1 makes deliberate trade-offs to ship small and sharp:\n\n- **TS/JS only.** Python, Rust, Go, Java are out of scope for v1. Python is demand-gated for v0.2 / v0.3.\n- **Name-based resolver** (no import-path tracking, no type-based method dispatch). Expected resolution rate: ~25–35 % of edges resolve to in-repo symbols; the rest are stdlib / third-party. That's enough because the questions agents actually ask (_\"who calls X in my repo?\"_) are the ones the dumb resolver answers correctly.\n- **No semantic search.** `gp_recall` is name-only. \"Find code similar to this snippet\" is deferred until 30+ users ask for it.\n- **No `.graphpilotignore`** yet (defaults skip `node_modules`, `dist`, `build`, `.git`, `coverage`, `.next`, `.nuxt`, `.cache`, `out`, `*.d.ts`).\n- **Single repo per query.** Workspace abstraction is on the v1.x roadmap.\n\nFull list with mitigations: [`docs/limitations.md`](docs/limitations.md).\n\n## FAQ\n\n**Does it send my code anywhere?**\nNo. There is no network code in `src/`, no telemetry, no update check. An ESLint rule blocks adding any of those at the build gate.\n\n**Will it slow down my editor?**\nThe MCP server is idle until your agent calls a tool. Tool calls are sub-millisecond after the first lazy load. Watch mode adds ~3–10 ms per file save.\n\n**What happens to the graph when I switch branches?**\nIf you use `git worktree`, you automatically get a separate graph per worktree. On a single working copy that you switch with `git checkout`, the graph reflects the last `gp_index` (or watch-mode updates). Run `gp_index` after a branch switch to refresh.\n\n**Do I need to re-index every session?**\nNo. The graph persists at `~/.graphpilot/<repo-id>/graph.json`. Re-index after sweeping changes; otherwise, watch mode keeps it fresh incrementally.\n\n**Why TypeScript/JavaScript first?**\nThat's where the maintainer's pain was, and tree-sitter-typescript covers TS, TSX, JSX, and JS in a single grammar. Python is the next likely addition; vote with a GitHub Discussion.\n\n**How does this compare to LSP?**\nLSPs are scoped to one editor and one buffer at a time, and they re-compute on each query. GraphPilot is editor-agnostic, persists across sessions, and answers structural questions (who-calls, blast-radius) that LSPs don't expose uniformly.\n\n**The agent can't see the tools / something's not working.**\nRun `graphpilot doctor` — it checks Node, `PATH`, the index, the MCP handshake, and per-client config in one shot. Symptom-by-symptom fixes live in [`docs/troubleshooting.md`](docs/troubleshooting.md).\n\n## Documentation\n\n- [`docs/quickstart.md`](docs/quickstart.md) — 5-minute walkthrough\n- [`docs/mcp-setup.md`](docs/mcp-setup.md) — per-client config reference\n- [`docs/troubleshooting.md`](docs/troubleshooting.md) — symptom-indexed fixes (start with `graphpilot doctor`)\n- [`docs/architecture.md`](docs/architecture.md) — pipeline writeup with file refs\n- [`docs/limitations.md`](docs/limitations.md) — v1 caveats (read this)\n- [`bench/README.md`](bench/README.md) — benchmark methodology + results\n- [`examples/`](examples/) — ready-to-paste configs for every supported client\n\n## Contributing\n\nGraphPilot is small, opinionated, and accepting contributions. Start with [`CONTRIBUTING.md`](CONTRIBUTING.md) — especially the _\"What we are NOT doing in v1\"_ section before you propose a feature.\n\nFound a security issue? Please follow [`SECURITY.md`](SECURITY.md) instead of opening a public issue.\n\n## License\n\n[Apache-2.0](LICENSE). Copyright 2026 Akshay Sharma — [codewithakki@gmail.com](mailto:codewithakki@gmail.com)\n",
  "bytes": 19534,
  "sha": "b23e4c2d2fd9d14529f2f880915e419994f8d80c936e49376fd88fa5273f8514",
  "repo_slug": "graphpilot-oss/graphpilot",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_graphpilot_oss_graphpilot_493b6c91/readme"
}