What it is
Graft builds an understanding of your codebase once and writes it into the repo as a folder of linked markdown nodes, one per system, API or concept. Each node holds a plain-English summary, sources, typed links and your own notes. A deterministic tree-sitter pass produces a per-symbol code graph with no model or key. An optional LLM pass (--deep) adds summaries and concept nodes. It wires into Claude Code with a statusline, hooks and an MCP server, and writes instruction files for other agents such as Cursor, Codex and Gemini.
Who it's for
- Developers using Claude Code, Cursor, Codex, Gemini or similar coding agents who want less repeated repo exploration
- Teams on large codebases where agents spend many tool calls and tokens rediscovering structure
- Users who want a local, file-based graph with no database, server or embeddings, and their own LLM provider and key
Requirements
Requirements
- npm (installed via
npm install -g @nanonets/graft, or run withnpx @nanonets/graft init) - Node.js (the README shows a Node version badge but does not state a minimum version)
- A provider key (GRAFT_PROVIDER, GRAFT_API_KEY, GRAFT_MODEL, and GRAFT_BASE_URL for the openai wire format) only for LLM-written parts such as
graft build --deep - Optional: a language server on PATH (rust-analyzer, clangd, gopls, pyright or typescript-language-server) for
graft build --lsp
Setup
Install the CLI and initialize
Install once, then run init. It asks which coding agents to wire up, builds graft/ from your code, and adds a statusline and hooks to .claude/.
bashnpm install -g @nanonets/graft # install the CLI, once graft init # build the graph + wire it into Claude CodePreview changes before writing
Nothing is written until you pick. Use --dry-run to see every file init would touch.
bashgraft init --dry-runSkip the global install
npx works the same way as the global install.
bashnpx @nanonets/graft initShare the wiring with teammates
graft/ is a local regenerable cache added to .gitignore automatically. Commit the wiring in .claude/, and each teammate runs
graft buildto generate their own graph.bashgit add .claude && git commit -m "wire in graft"
Examples
Wire only Claude Code, no prompt
bashgraft init --agents claudeWhat it does: Skips the interactive agent picker and wires Claude Code alone.
Register the MCP server manually
json{ "mcpServers": { "graft": { "command": "npx", "args": ["-y", "@nanonets/graft", "mcp"] } } }What it does: For agents that need the MCP server registered explicitly. It exposes tools such as graft_find_code, graft_file_api, graft_trace_calls, graft_find_all, graft_repo_map and graft_check_freshness.
Add compiler-grade call edges
bashgraft build --lspWhat it does: Adds precise lsp_resolved call edges when a supported language server is on your PATH. It is best-effort, and with no server installed the graph is unchanged.
Disable anonymous telemetry
bashgraft telemetry disableWhat it does: Turns off the anonymous usage ping. DO_NOT_TRACK=1 also works, and graft telemetry debug prints what would be sent.
Pros & cons
Pros
- Pro:Structural graph build (
graft build,graft check) is deterministic tree-sitter and needs no key or network - Pro:Graph is plain linked markdown files with no database, server or embeddings, and is rebuilt against the working tree on every query, including uncommitted edits
- Pro:In the README's SWE-bench Verified run (50 instances), Claude Code with graft resolved 33 vs 27 with 25% fewer tool calls and 23% fewer tokens
- Pro:Vendor-neutral: works with OpenAI, Anthropic, OpenRouter, Fireworks, Groq, LiteLLM, a local model and others via your own key
Cons
- Con:LLM-written summaries and concept nodes (
--deep) require your own provider key and model calls - Con:The graph is a local cache that is not committed, so each teammate must run
graft buildto generate their own - Con:Files in languages outside the 23 supported are skipped, and the crux is not yet inlined into markdown nodes (only in the per-symbol code graph)
Images
