codegraph Local code graph exposed as 8 MCP tools. Accelerates exploration with O(1) SQLite lookups and FTS5 search — slashing the grep + Read loops needed to orient in a codebase. It does not replace grep. Codegraph is a tree-sitter approximation of the call graph, not a compiler-grade one: it is fast and low-token but unsound (it has false negatives). Treat it as the accelerator for orientation and traversal, and keep grep as the source of truth for completeness. See Soundness & limits below — this distinction is load-bearing, not a footnote. When to use - Brownfield repo where structure is…

| sort | uniq -c | sort -rn | head -10\n```\n\n## Phase 1 — Install timing\n\nCritical observation: whether tree-sitter native bindings trigger `node-gyp` compilation.\n\n```bash\nmkdir -p /tmp/cg-spike && cd /tmp/cg-spike\n\n{ /usr/bin/time -v npx --yes @colbymchenry/codegraph --version ; } 2> install.time.log\n\ngrep -iE \"node-gyp|prebuild|rebuild|gcc|make\\[\" install.time.log | head -20 || echo \"no native build signals\"\n\ndu -sh ~/.npm/_npx 2>/dev/null\ndu -sh /tmp/cg-spike\n```\n\n## Phase 2 — Index timing\n\n```bash\ncd \u003crepo-root>\n\n{ /usr/bin/time -v npx @colbymchenry/codegraph init ; } 2> init.time.log\n{ /usr/bin/time -v npx @colbymchenry/codegraph index ; } 2> index.time.log\n\nnpx @colbymchenry/codegraph status > status.txt 2>&1\ncat status.txt\n\nls -lah .codegraph/\ndu -sh .codegraph/\n```\n\n## Phase 3 — Query smoke test (CLI path)\n\nCloud session cannot restart Claude Code to load the MCP server. Probe via CLI — this still exercises the SQLite query layer end-to-end.\n\nPick 3 queries meaningful for the specific repo. If unfamiliar, `codegraph files` or `ls` first. Prefer one each of: symbol lookup / cross-file call traversal / task context.\n\nRun these from inside the repo — `query`, `context`, and `files` operate on `cwd` and reject a trailing path argument. Only `init`, `index`, `status`, `sync` take a path.\n\n```bash\ncd \u003crepo-root>\n{ /usr/bin/time -v npx @colbymchenry/codegraph query \"\u003cSYMBOL>\" --json ; } 2> q1.time.log > q1.out.json\n{ /usr/bin/time -v npx @colbymchenry/codegraph context \"\u003cTASK>\" --format markdown --max-nodes 20 ; } 2> q2.time.log > q2.out.md\n{ /usr/bin/time -v npx @colbymchenry/codegraph files --json ; } 2> q3.time.log > q3.out.json\n```\n\nBaseline — same symbol lookup with grep:\n\n```bash\n{ /usr/bin/time -v grep -rn \"\u003cSYMBOL>\" --include=\"*.ts\" --include=\"*.js\" --include=\"*.go\" --include=\"*.py\" . 2>/dev/null | head -50 ; } 2> grep.time.log\n```\n\n## Phase 4 — Persistence probe (manual follow-up)\n\nCannot complete in current session. Record as open items for the operator:\n\n- [ ] End current session; start a new session on the same repo\n- [ ] `.codegraph/codegraph.db` still present?\n- [ ] `~/.npm/_npx` codegraph cache still present?\n- [ ] `codegraph status` works directly, or requires fresh install?\n- [ ] `.codegraph/codegraph.db` size — viable for git LFS / artifact cache?\n\nDo not speculate answers.\n\n## Phase 5 — Report template\n\nOutput as the final reply, no wrapping commentary:\n\n````markdown\n# CodeGraph Cloud Spike Report — \u003crepo>\n\n**Repo**: \u003crepo> @ \u003ccommit-sha>\n**Runtime**: Claude Code Cloud (or: local / devcontainer), Node \u003cver>, \u003cnproc> cores, \u003cmem>\n**Date**: \u003cdate>\n\n## 0. Repo baseline\n- Files: \u003cN>\n- Size: \u003csize>\n- Top languages: \u003cext: count, ...>\n\n## 1. Install cost\n- Wall: \u003cXm Ys>\n- Native compilation: \u003cyes/no, which packages>\n- ~/.npm/_npx footprint: \u003csize>\n\n## 2. Index cost\n- `init` wall: \u003cs>\n- `index` wall: \u003cXm Ys>\n- Indexed files: \u003cN>\n- Nodes / edges: \u003cN> / \u003cN>\n- `.codegraph/` size: \u003csize>\n- Total cold-start (1 + 2): \u003cXm Ys>\n\n## 3. Query latency\n| Query | codegraph wall | output size | grep baseline |\n|---|---|---|---|\n| symbol search | \u003cs> | \u003cN lines> | \u003cs> |\n| context build | \u003cs> | \u003cN bytes> | — |\n| files structure | \u003cs> | \u003cN entries> | — |\n\n## 4. Persistence — open items\n- [ ] new-session: .codegraph/ preserved?\n- [ ] new-session: npx cache preserved?\n- [ ] .codegraph/codegraph.db size git-LFS-viable?\n\n## 5. Inference (this run only, no extrapolation beyond same-size repos)\n- Cold-start range for similar repos: \u003cX min>\n- Cloud worth-it: \u003cpending §4>\n\n## 6. Anomalies\n- \u003craw error / unexpected behavior, if any>\n````\n\n## Cross-repo summary (after all three reports)\n\n| Repo | Files | Cold-start | DB size | Per-query (search) | Notes |\n|---|---|---|---|---|---|\n| onsager-ai/onsager | | | | | |\n| crawlab | | | | | |\n| codervisor/leanspec | | | | | |\n\n## Reminders\n\n1. Every step uses `/usr/bin/time -v` — no skips\n2. Do not grep the whole repo to figure out what to query — use `codegraph files` or `ls` first\n3. Failures recorded raw, no silent retry\n4. Do not try to fix codegraph itself — black-box measurement\n5. Complete all phases before emitting Phase 5 report; no streaming partials\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5627,"content_sha256":"f42010cbd9ecaf68c5c6d056116da1ca03d6e4509314cd2e7251ada6a3f71971"},{"filename":"references/usage.md","content":"# codegraph — Tool Usage Rules\n\nAdapted from upstream's global instructions, with main-session vs subagent split made explicit.\n\n## The 8 MCP tools\n\n| Tool | Use for | Caller scope | Output weight |\n|---|---|---|---|\n| codegraph_search | Find symbol by name | main + subagent | light |\n| codegraph_callers | What calls X | main + subagent | light |\n| codegraph_callees | What X calls | main + subagent | light |\n| codegraph_impact | Blast radius before editing | main | light |\n| codegraph_node | One symbol's details | main + subagent | light–medium |\n| codegraph_files | Indexed file structure | main + subagent | light |\n| codegraph_status | Index health | main | light |\n| codegraph_context | Build task context (returns source blocks) | subagent only | heavy |\n\nNote: newer versions (verified on the npm CLI `v0.9.9`) expose a 9th tool, `codegraph_explore`, and the MCP server's own instructions name it the **PRIMARY** tool: one capped call returns the verbatim source of the relevant symbols grouped by file (Read-equivalent), so for \"how does X work\" / architecture / \"where is X\" questions it is usually the *only* call needed — prefer it over a `context`-using subagent on versions that have it.\n\n## Do\n\n- Main session: use the light tools (`search`, `callers`, `callees`, `impact`, `node`, `files`, `status`) for targeted lookups before editing\n- Any \"how does X work\" / \"explain the Y subsystem\" / \"where is Z implemented\" → spawn an Explore subagent and let it use `codegraph_context` (heavy) freely\n- Trust subagent results: do not re-read files that the subagent's context already returned source for\n- Check `codegraph_status` once per session to confirm index freshness; sync if stale (`codegraph sync`)\n\n## Don't\n\n- Call `codegraph_context` directly in main session — its source blocks pollute main context\n- Re-index manually if status shows fresh — the file watcher handles it on local; in cloud sessions the index is bounded to session lifetime anyway\n- Trust the index for files modified within the last few seconds — auto-sync has a ~1–2s debounce window\n- **Trust `callers`/`callees`/`impact` for *completeness*** (every caller before a rename, exhaustive blast radius). They're unsound — they silently drop unresolved method/generic/trait-dispatch edges. Confirm with grep; see SKILL.md → *Soundness & limits*.\n- **Query an overloaded name with bare `callers`/`callees`.** Results conflate or under-resolve across same-named definitions. Use `codegraph_node` on a specific symbol id, or grep.\n\n## Grep is the completeness backstop (not a fallback)\n\nEarlier guidance said \"don't fall back to grep — that defeats the point.\" That was wrong, and is corrected here. Grep is not a fallback for codegraph; it is the **authoritative source for completeness** where codegraph is only an accelerator. Use codegraph to *orient and pre-rank*; use grep to *confirm* whenever missing a result is costly (renames, signature changes, security audits). A codegraph-vs-grep delta means \"codegraph missed it,\" not \"grep over-matched.\" Full rationale + the decision matrix live in SKILL.md.\n\n## Subagent prompt template\n\nWhen delegating exploration, include this in the subagent prompt:\n\n> This project has CodeGraph initialized (`.codegraph/` exists). Use `codegraph_context` as your primary tool — it returns full source sections from all relevant files in one call.\n>\n> Rules:\n> 1. Follow the explore call budget in the tool description; it scales with project size.\n> 2. Do not re-read files that `codegraph_context` already returned source code for. The returned sections are complete and authoritative.\n> 3. Only fall back to grep/glob/read for files listed under \"Additional relevant files\" if you need more detail, or if codegraph returned no results.\n\n## CLI equivalents (when MCP is not wired, e.g. cloud sessions)\n\n| MCP tool | CLI command |\n|---|---|\n| codegraph_search | `codegraph query \u003cname> --json` |\n| codegraph_context | `codegraph context \"\u003ctask>\" --format markdown --max-nodes \u003cN>` (absent on some versions, e.g. CLI `v0.9.9` — use `query` + `callers`/`callees` instead) |\n| codegraph_files | `codegraph files --json` |\n| codegraph_status | `codegraph status` |\n| codegraph_callers / callees / impact | `codegraph callers \u003cname>` / `callees \u003cname>` / `impact \u003cname> [--depth N] [--json]` — confirmed present in CLI `v0.9.9` |\n| (no `node` subcommand) | use `codegraph query \u003cname>` for a symbol's location |\n\nUse CLI bypass when in cloud session without MCP wiring; the heavy/light distinction still applies.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4564,"content_sha256":"b5ef87c4b5fe4d2ae47f5186bca0e6c39b8a935b995bc0b06afdd5db4ce36687"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"codegraph","type":"text"}]},{"type":"paragraph","content":[{"text":"Local code graph exposed as 8 MCP tools. Accelerates exploration with O(1) SQLite lookups and FTS5 search — slashing the grep + Read loops needed to ","type":"text"},{"text":"orient","type":"text","marks":[{"type":"em"}]},{"text":" in a codebase.","type":"text"}]},{"type":"paragraph","content":[{"text":"It does ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" replace grep. Codegraph is a tree-sitter ","type":"text"},{"text":"approximation","type":"text","marks":[{"type":"em"}]},{"text":" of the call graph, not a compiler-grade one: it is fast and low-token but ","type":"text"},{"text":"unsound","type":"text","marks":[{"type":"strong"}]},{"text":" (it has false negatives). Treat it as the accelerator for orientation and traversal, and keep grep as the source of truth for completeness. See ","type":"text"},{"text":"Soundness & limits","type":"text","marks":[{"type":"strong"}]},{"text":" below — this distinction is load-bearing, not a footnote.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to use","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Brownfield repo where structure is non-obvious","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Task involves: \"where is X used\", \"what breaks if I change Y\", \"trace flow from A to B\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Long-running session — cold-start cost amortizes over multiple queries","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When NOT to use","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Single-file edits or trivial lookups","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Session likely shorter than cold-start cost (see ","type":"text"},{"text":"references/spike.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for per-repo numbers)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Repo not initialized AND no cached ","type":"text"},{"text":".codegraph/","type":"text","marks":[{"type":"code_inline"}]},{"text":" AND short session","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Soundness & limits — read before trusting a result","type":"text"}]},{"type":"paragraph","content":[{"text":"Codegraph is built on tree-sitter, not the compiler, so its call/reference edges are an ","type":"text"},{"text":"approximation","type":"text","marks":[{"type":"strong"}]},{"text":". It fails in three confirmed ways. The governing rule falls out of them:","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Grep is the source of truth for ","type":"text","marks":[{"type":"strong"}]},{"text":"completeness","type":"text","marks":[{"type":"strong"},{"type":"em"}]},{"text":". Codegraph is the accelerator for ","type":"text","marks":[{"type":"strong"}]},{"text":"orientation and traversal","type":"text","marks":[{"type":"strong"},{"type":"em"}]},{"text":". Never invert these.","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"paragraph","content":[{"text":"The asymmetry is the whole argument: for a refactor, a ","type":"text"},{"text":"false negative is dangerous","type":"text","marks":[{"type":"strong"}]},{"text":" (you miss a caller, ship a break); a false positive is merely annoying (you glance and discard). Codegraph has false negatives; grep does not. So codegraph may ","type":"text"},{"text":"propose and rank","type":"text","marks":[{"type":"em"}]},{"text":", but grep ","type":"text"},{"text":"confirms","type":"text","marks":[{"type":"em"}]},{"text":" whenever the answer must be exhaustive.","type":"text"}]},{"type":"paragraph","content":[{"text":"The three failure modes (measured on a ~580-file Rust+TS repo):","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Unsound edges → false negatives.","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"callers","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"callees","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"impact","type":"text","marks":[{"type":"code_inline"}]},{"text":" miss real call sites when the receiver type can't be resolved from syntax alone (calls on locals, generics, trait objects). Measured: a method with ","type":"text"},{"text":"8","type":"text","marks":[{"type":"strong"}]},{"text":" real callers returned ","type":"text"},{"text":"2","type":"text","marks":[{"type":"strong"}]},{"text":" — the 5 dropped were ","type":"text"},{"text":"local.method()","type":"text","marks":[{"type":"code_inline"}]},{"text":" and generic-dispatch sites, with ","type":"text"},{"text":"no warning","type":"text","marks":[{"type":"strong"}]},{"text":". Exact on unique free-functions + direct calls (verified 1/1, 2/2); unreliable on method dispatch.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Name resolution is fuzzy and overload-blind.","type":"text","marks":[{"type":"strong"}]},{"text":" Bare-name queries prefix-match (","type":"text"},{"text":"useWorkspace","type":"text","marks":[{"type":"code_inline"}]},{"text":" answered for ","type":"text"},{"text":"useWorkspacesQuery","type":"text","marks":[{"type":"code_inline"}]},{"text":" — a ","type":"text"},{"text":"different symbol","type":"text","marks":[{"type":"em"}]},{"text":") and conflate overloads (","type":"text"},{"text":"execute","type":"text","marks":[{"type":"code_inline"}]},{"text":", with 19 definitions, returned ","type":"text"},{"text":"sqlx","type":"text","marks":[{"type":"code_inline"}]},{"text":"'s ","type":"text"},{"text":".execute()","type":"text","marks":[{"type":"code_inline"}]},{"text":" DB calls, not the trait method). For any name with multiple definitions, drop to ","type":"text"},{"text":"codegraph_node","type":"text","marks":[{"type":"code_inline"}]},{"text":" on a specific symbol id; bare ","type":"text"},{"text":"callers","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"callees","type":"text","marks":[{"type":"code_inline"}]},{"text":" are unattributable.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The index lags the disk.","type":"text","marks":[{"type":"strong"}]},{"text":" CLI sees nothing until ","type":"text"},{"text":"codegraph sync","type":"text","marks":[{"type":"code_inline"}]},{"text":" (~0.3s); the MCP file-watcher closes the gap to ~1–2s. Right after an edit, the index is wrong — grep/Read is ground truth until it catches up.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Decision matrix","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Task","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tool","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Why","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Orient / \"explain subsystem X\" / first survey","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"codegraph ","type":"text","marks":[{"type":"strong"}]},{"text":"explore","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"One call, ranked, verbatim source — far less context than grep+Read","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Callers of a ","type":"text"},{"text":"uniquely-named","type":"text","marks":[{"type":"strong"}]},{"text":" free function","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"codegraph ","type":"text","marks":[{"type":"strong"}]},{"text":"callers","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" (trust it)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Exact on unique names + direct calls","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Find ","type":"text"},{"text":"ALL","type":"text","marks":[{"type":"strong"}]},{"text":" callers before a signature change / rename","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"grep authoritative","type":"text","marks":[{"type":"strong"}]},{"text":"; codegraph only to pre-rank","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Codegraph is unsound here — completeness can't depend on it","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Anything with an ","type":"text"},{"text":"overloaded name","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"execute","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"lookup","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"run","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"new","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"grep","type":"text","marks":[{"type":"strong"}]},{"text":", or codegraph ","type":"text"},{"text":"node","type":"text","marks":[{"type":"code_inline"}]},{"text":" on a specific id","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bare-name codegraph conflates / under-resolves unpredictably","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Impact of a core type","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"codegraph ","type":"text","marks":[{"type":"strong"}]},{"text":"impact --depth 1","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" to pre-rank, then grep to confirm","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Default depth-2 inflates (test fns + one ","type":"text"},{"text":"file","type":"text","marks":[{"type":"code_inline"}]},{"text":" entry per file) and isn't depth-ranked","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Just-edited code","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"grep","type":"text","marks":[{"type":"strong"}]},{"text":" (or ","type":"text"},{"text":"codegraph sync","type":"text","marks":[{"type":"code_inline"}]},{"text":" first)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Index is stale until reindex","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Trait-dispatch / generic call sites","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"grep + reading","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Both weak; codegraph silently drops them, grep at least surfaces the text","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"Workflow:","type":"text","marks":[{"type":"strong"}]},{"text":" start with ","type":"text"},{"text":"explore","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the map and ","type":"text"},{"text":"callers","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"impact","type":"text","marks":[{"type":"code_inline"}]},{"text":" for direction — but the moment the answer must be ","type":"text"},{"text":"complete","type":"text","marks":[{"type":"em"}]},{"text":" (a rename, \"did I get everyone?\"), confirm with grep and treat any codegraph-vs-grep delta as \"codegraph missed it,\" not \"grep over-matched.\"","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Prerequisites","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Node 18+ on PATH","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Project has ","type":"text"},{"text":".codegraph/","type":"text","marks":[{"type":"code_inline"}]},{"text":" (run ","type":"text"},{"text":"codegraph init","type":"text","marks":[{"type":"code_inline"}]},{"text":" if not)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For cloud sessions: cold-start cost verified via ","type":"text"},{"text":"references/spike.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the target repo","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Files","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/install.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — installation for local / Claude Code Cloud / devcontainer","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/usage.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — which of the 8 MCP tools to use when, with main-session vs subagent rules","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/spike.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — cold-start measurement protocol; run once per new target repo before relying on codegraph in cloud sessions","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Known integration targets","type":"text"}]},{"type":"paragraph","content":[{"text":"Cold-start measured locally (Node 22, 4 cores). Cloud cold-start still pending — re-run ","type":"text"},{"text":"references/spike.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" in a cloud session before relying on these numbers there.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Repo","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Indexed files","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Nodes / edges","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"DB size","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cold init+index","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Query wall","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"onsager-ai/onsager","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"578 (rust + tsx/ts)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8.6k / 20k","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"24 MB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"12s","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~0.9s","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"crawlab-team/crawlab","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"644 (go)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"6.8k / 15k","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"11 MB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"6s","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~0.9s","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"codervisor/leanspec","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"695 (tsx/rust/ts)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8.9k / 21k","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"23 MB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"10s","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~0.9s","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"Per-query wall is dominated by Node startup — the SQLite work itself is milliseconds. End-to-end cold-start including one-shot ","type":"text"},{"text":"npx install","type":"text","marks":[{"type":"code_inline"}]},{"text":" is ~13–19s for repos in this size class.","type":"text"}]}]},"metadata":{"date":"2026-11-02","name":"codegraph","author":"@skillopedia","source":{"stars":7,"repo_name":"dev-skills","origin_url":"https://github.com/onsager-ai/dev-skills/blob/HEAD/skills/codegraph/SKILL.md","repo_owner":"onsager-ai","body_sha256":"effb466edb67311e30f24ba2691d9b8665bfe9dd445cf23a163baf5a80be6d94","cluster_key":"dfdcdc2abbf8dd5c5457036a2601e3314fe18651b3795c3be4d2b4ccf19eaf12","clean_bundle":{"format":"clean-skill-bundle-v1","source":"onsager-ai/dev-skills/skills/codegraph/SKILL.md","text_bytes":13897,"source_commit":"080075df0b75a033aca8f4026fcce710078089da","skills_sh_rank":14404,"attachment_count":3,"text_attachments":3,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/codegraph/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"software-engineering","category_label":"Engineering"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"software-engineering","import_tag":"skills-sh-top20k-2026-11","description":"Pre-indexed code knowledge graph (MCP, SQLite + tree-sitter) for faster, lower-token exploration of brownfield codebases. Use when starting work on a repo larger than ~500 files or when the task involves cross-file traversal — \"where is X used\", \"what calls Y\", \"what breaks if I change Z\", \"trace flow from A to B\", \"explain this subsystem\". Skip for single-file edits or sessions shorter than the cold-start cost. Triggers include \"codegraph\", \"code graph\", \"index this repo\", \"where is X defined\", \"find callers of\", \"callees of\", \"blast radius of changing X\", \"explore this codebase\". Cuts the grep + Read loops needed to orient, via O(1) SQLite lookups and FTS5 search over 8 MCP tools — but it's an unsound tree-sitter approximation, so grep stays the completeness backstop for renames/exhaustive callers."}},"renderedAt":1793665831858}

codegraph Local code graph exposed as 8 MCP tools. Accelerates exploration with O(1) SQLite lookups and FTS5 search — slashing the grep + Read loops needed to orient in a codebase. It does not replace grep. Codegraph is a tree-sitter approximation of the call graph, not a compiler-grade one: it is fast and low-token but unsound (it has false negatives). Treat it as the accelerator for orientation and traversal, and keep grep as the source of truth for completeness. See Soundness & limits below — this distinction is load-bearing, not a footnote. When to use - Brownfield repo where structure is…