@ai-application-toolkit/codegraph
v0.3.1
Published
Turn a folder of source code into a queryable, multi-language code graph (symbols, imports, references) with LLM context ranking.
Maintainers
Readme
@ai-application-toolkit/codegraph
Turn a folder of source code into a queryable, multi-language code graph — files, symbols, imports and references — built with tree-sitter, plus PageRank context ranking for feeding the right code to an LLM.
Part of the AI Application Toolkit.
Install
pnpm add @ai-application-toolkit/codegraphGrammars ship as WebAssembly via tree-sitter-wasms — no native build step.
Supported languages
TypeScript (.ts/.mts/.cts), TSX, JavaScript (.js/.jsx/.mjs/.cjs),
Python, Go, C# (.cs), Java and Rust. Adding a language is a grammar .wasm
plus a set of tag-query patterns — the core does not change.
Import resolution is file-path based for the JS family (relative imports) and
Python; C#, Java, Go and Rust use namespace/module imports, so cross-file
imports edges are not inferred for them — but contains and (name-based)
references edges are.
CLI (npx)
No install needed — run any command with npx.
First time on a project? Run one command — that's it. codegraph scans the
folder for you on first use, so you do not need to run build (or anything
else) first:
# Explore the codebase as an MCP server (Claude Desktop, Cursor, another agent):
npx @ai-application-toolkit/codegraph serve /path/to/project
# …or just build a reusable on-disk index and stop there:
npx @ai-application-toolkit/codegraph index /path/to/projectOn the first run codegraph walks the whole folder once, saves an incremental
index, and — for serve — prints a URL like http://localhost:3000/mcp. Every
run after that is near-instant: only changed files are re-parsed.
Commands at a glance
| Command | What it does | Saves an index? |
| --- | --- | --- |
| serve <dir> | Serve the graph as an MCP server over HTTP | Yes, builds one if missing |
| index <dir> | Build or update the on-disk index | Yes |
| sync <dir> | Update an existing index (errors if there is none) | Yes |
| status <dir> | Show an index's freshness, size and counts | No |
| list [dir] | List a repo's indexes (--global lists all cached ones) | No |
| build <dir> | One-shot, in-memory summary printed to the terminal | No |
buildis not a setup step. It's a throwaway scan for a quick look and leaves no cache behind, so running it beforeserve/indexsaves you nothing. To actually work with a project, reach forserveorindex.
serve — explore over MCP
# Omit --port to auto-select a free port from 3000; a busy --port falls back to
# the next free one.
npx @ai-application-toolkit/codegraph serve ./src --port 3000
# Publish a public URL via untun (Cloudflare quick tunnel)
npx @ai-application-toolkit/codegraph serve ./src --tunnelserve starts instantly from the saved index, refreshes in the background, and
watches for changes — hot-swapping the graph on edits (--no-watch to disable).
It needs the optional dependency @ai-application-toolkit/mcp, and --tunnel
needs untun; both are imported lazily so build stays lightweight. On its
first run --tunnel downloads cloudflared and prompts you to accept its
license, so run it in an interactive terminal.
build — a quick, throwaway look
# Print a summary + the top-ranked symbols (nothing is saved)
npx @ai-application-toolkit/codegraph build ./src
# Dump the full graph as JSON
npx @ai-application-toolkit/codegraph build ./src --json > graph.json
# Restrict languages (works on every command)
npx @ai-application-toolkit/codegraph build ./src --lang typescript,python,csharpPersistent index
index, sync and serve keep a SQLite index that caches per-file parse
results, so only changed files are re-parsed — unchanged files are skipped by an
mtime/size check without even being read, making a warm rebuild near-instant.
index builds or updates the index; sync updates an existing one (and errors
if there is none); build is a one-shot in-memory scan that uses no index.
No install needed on modern Node. The SQLite backend is chosen at runtime:
better-sqlite3if it is installed (stable, quiet), else- Node's built-in
node:sqlite(Node ≥ 23.4) — zero dependency, else servefalls back to a plain in-memory build (no cache).
So on recent Node it just works; on older Node run npm i better-sqlite3. Force
a backend with CODEGRAPH_SQLITE_DRIVER=node (skip the native module) or
=better.
Index location. Defaults to <dir>/.codegraph/index.db (add .codegraph/
to .gitignore). Override with:
--index <path>— an explicit file, or setCODEGRAPH_INDEX--global— store under~/.cache/codegraph/(per project), keeping the repo clean
npx @ai-application-toolkit/codegraph index ./src --global
npx @ai-application-toolkit/codegraph serve ./src --index /tmp/mygraph.dbLibrary API
import { buildCodeGraph } from '@ai-application-toolkit/codegraph'
const graph = await buildCodeGraph({ dir: './src' })
graph.findDefinition('buildCodeGraph') // where is it declared?
graph.findReferences('CodeGraph') // who uses it?
graph.fileSummary('src/build.ts') // symbols + imported files
// Call graph:
graph.callers('parseFile') // who calls it (confidence-scored via impact)
graph.callees('buildCodeGraph') // what it calls
graph.impact('parseFile', { direction: 'callers' }) // blast radius, grouped by depth
// "What matters around what I'm editing?" — ranked context for an LLM:
graph.rankedContext({ seeds: ['parseFile'], limit: 15 })Call graph & impact analysis
On top of coarse, name-based references, codegraph resolves a scope-aware call
graph: calls edges from a symbol to the definition it invokes, each with a
confidence score (1.0 exact, 0.8 high, 0.5 medium). Resolution uses imports,
this, and lightweight type tracking (new X() / typed params → x.method())
for TS/JS/Python; other languages resolve by name/uniqueness. It is precision-
first — ambiguous or cross-language calls are skipped rather than mis-wired.
codegraph_impact returns the full blast radius in one call — every
transitive caller grouped by depth with confidence — so an agent knows what a
change risks before touching it:
// codegraph_impact { "symbol": "registerAllPlugins" }
{ "target": "registerAllPlugins",
"groups": [{ "depth": 1, "nodes": [{ "name": "Bridge", "file": "…/Bridge.java", "line": 192, "confidence": 1 }] }],
"truncated": false }As tools / capability
import { buildCodeGraph, defineCodegraphCapability } from '@ai-application-toolkit/codegraph'
import { collectCapabilityTools } from '@ai-application-toolkit/capability'
import { createRuntime } from '@ai-application-toolkit/runtime'
const graph = await buildCodeGraph({ dir: './src' })
const codegraph = defineCodegraphCapability(graph)
const runtime = createRuntime({ tools: collectCapabilityTools([codegraph]) })
// Tools: codegraph_search_symbols, codegraph_find_definition,
// codegraph_find_references, codegraph_neighbors,
// codegraph_file_summary, codegraph_relevant_context,
// codegraph_callers, codegraph_callees, codegraph_impact,
// codegraph_affectedAsk your codebase (RAG)
rankedContext is built for retrieval: derive seeds from a question, let
personalized PageRank surface the relevant symbols, read their source, and hand
that to a model adapter.
const graph = await buildCodeGraph({ dir: './src' })
const ranked = graph.rankedContext({ seeds: ['rankedContext'], kind: 'symbol', limit: 6 })
// -> rankedContext, computePageRank, RankedContextOptions, … (the ranking code)
// read each symbol's startLine..endLine, pack into a prompt, call your adapterA runnable end-to-end version (codegraph retrieval → Claude) lives in
examples/codegraph-qa.ts.
Serve over MCP
Because the capability is just toolkit tools, you can expose the whole graph as an MCP server — any MCP client (Claude Desktop, the MCP Inspector, another agent) can then explore the codebase remotely:
import { startHttpMcpServer } from '@ai-application-toolkit/mcp'
import { collectCapabilityTools } from '@ai-application-toolkit/capability'
const graph = await buildCodeGraph({ dir: './src' })
await startHttpMcpServer({
name: 'codegraph-mcp',
version: '1.0.0',
tools: collectCapabilityTools([defineCodegraphCapability(graph)]),
port: 3000
})
// Streamable HTTP at http://localhost:3000/mcpRunnable: examples/codegraph-mcp-http.ts.
How it works
buildCodeGraph walks the folder, parses each file with tree-sitter, and
extracts symbols, references and imports using tag queries. Import and
reference edges are resolved best-effort and high-precision: ambiguous
cross-file names are skipped rather than guessed, which keeps the graph clean
for context selection. rankedContext runs PageRank (personalized when you
pass seeds) over the import/reference graph.
License
MIT © Danny LAN
