Skip to content

Product 02 · deterministic code knowledge graph

CodeGraph

tree-sitter → SQLite + FTS5 · CLI + MCP · no model

One index, three front doors. tree-sitter parses a repository into a project-level index of symbols, calls and dependencies, then answers structural questions against it: who calls this, what does this reach, what does changing it touch. Those answers come out of a full syntax-tree parse — not a text match that happened to line up, and not a model.

Premise

There is no model inside it, which is why the bytes are reproducible

This is not a feature that was left out — it is the premise the whole thing rests on. The binary carries no embeddings, no vector index and no LLM call, so the same repository and the same question return byte-identical output on your laptop, on a colleague’s machine and on a CI runner. Reproducibility is what makes the next three things possible:

  1. 01Handed to a coding agent, it is a fact rather than a sample. Asking twice in one session cannot produce two different answers.
  2. 02It can be diffed in CI. A changed impact radius means the code structure changed, not that the weights felt different today.
  3. 03It can be reproduced when it is wrong. A deterministic pipeline gives a bug exactly one path to walk back down.

01

The problem it solves

grep cannot answer "what does changing this function touch". grep matches characters, not call relationships: same-named methods, re-exported symbols, calls dispatched through a trait or an interface — it sees none of them, and it will always hand you the matches inside comments and string literals as well. So you fall back to opening files and walking callers upward until you feel you have got them all — and that feeling is where regressions come from. CodeGraph computes that structure ahead of time, persists it, and answers the question in one query.

  • 01

    People editing an unfamiliar repository

    You inherit a few hundred thousand lines and need to know, before touching anything, who depends on this symbol and how far a change reaches. Read the radius first, then decide how to change it.

  • 02

    Coding agents

    One structural query returns the relevant symbols’ source plus the call paths between them, replacing dozens of grep-and-read round-trips — more accurate context, fewer tokens, shorter loops. That is what the MCP door exists for.

  • 03

    Editors and IDEs

    Reach the same index over local HTTP instead of each reimplementing cross-file resolution. For remote development, HTTP is also the only transport that reliably works.

  • 04

    CI and code review

    The blast radius of a change can be computed, diffed and quoted in a review. Deterministic output is what turns "this change reaches three more modules than the last one" into a verifiable sentence.

02

How it works

Four stages. None of them needs a network, and none of them sends your code anywhere. The index is written into the repository’s own .codegraph/ directory.

  1. 01

    Parse

    tree-sitter builds a syntax tree per file with a per-language grammar, extracting symbol definitions, call sites and file-to-file dependencies, then resolves symbols across files. This stage sets the ceiling on how precise every later answer can be.

  2. 02

    Persist

    Results go into a per-project SQLite database, with full-text search handled by FTS5. SQLite is compiled into the binary, so the host needs no system library installed.

  3. 03

    Query

    Symbol search, callers, callees, dependencies, change-impact radius, and a whole-graph export ranked by PageRank centrality. Queries read the index — sub-millisecond, not a fresh walk of the repository.

  4. 04

    Follow

    A background daemon watches for file changes on a 2-second debounce and updates the index incrementally, lagging writes by about a second. Every client on one project — terminal tabs, agents, editors — shares that single daemon; it exits once they all disconnect and the idle timeout elapses.

03

Three front doors, one index

The index is built once. People, agents and editors each come in through whichever door suits them and see the same data — there is no case where the CLI answer and the agent answer disagree.

  • 01

    CLI

    for you

    $ codegraph query "<symbol>" -p .

    A Clap subcommand set: init, index, sync, query, files, status, callers, callees, impact, affected, check, export, unlock — plus completion installers for bash, zsh, fish, powershell and elvish.

  • 02

    MCP over stdio

    for coding agents

    $ codegraph serve --mcp

    A standard MCP stdio server. codegraph install --yes detects the agents and IDEs you already have and writes their config; codegraph skill install additionally drops the usage guide into each one’s skill directory.

  • 03

    MCP over HTTP

    for editors and remote work

    $ codegraph serve --http

    Binds 127.0.0.1:8111 by default and is not exposed off the host. codegraph http list shows what is running; codegraph http stop <addr> ends one of them. This is the recommended transport for SSH remote development.

04

What you can ask it

The command line and the MCP tools sit on one implementation, so the answers match.

What you can ask it
QuestionCommand lineMCP tool
Where is this symbol defined?codegraph querycodegraph_search
How does this area work?codegraph exportcodegraph_explore
Give me its source and its call trailcodegraph query --jsoncodegraph_node
Who calls it?codegraph callerscodegraph_callers
What does it call?codegraph calleescodegraph_callees
What does changing it touch?codegraph impactcodegraph_impact
Which files did this change affect?codegraph affected
Is the index ready?codegraph statuscodegraph_status

impact returns the transitive closure, not one layer of callers — which is the main thing it does that walking the call chain by hand does not. export can order the whole graph by PageRank centrality, which is how you find the real hubs in a repository you have never seen.

05

Install and first run

The one-liner detects your platform, downloads the matching prebuilt binary and puts it on your PATH — no Rust toolchain, no compile wait. It is not published to crates.io, so the registry path of a plain cargo install will not find it; with a Rust toolchain, use the --git form below.

Install

# Linux and macOS

$ curl -fsSL https://raw.githubusercontent.com/sunerpy/codegraph-rust/main/scripts/install.sh | sh

# Windows (PowerShell 5.1+)

$ irm https://raw.githubusercontent.com/sunerpy/codegraph-rust/main/scripts/install.ps1 | iex

# or from source — not published to crates.io

$ cargo install --git https://github.com/sunerpy/codegraph-rust codegraph-rs

First run

# build the index into ./.codegraph/

$ codegraph init && codegraph index

# look a symbol up

$ codegraph query "GraphTraverser" -p .

# see what changing it would reach

$ codegraph impact GraphTraverser

# wire the MCP server into installed agents

$ codegraph install --yes

Set CODEGRAPH_VERSION to pin a release instead of taking the latest. In CI, CODEGRAPH_NO_DAEMON=1 forces foreground mode; pass --no-watch to skip file watching. Exclude patterns live in .codegraph/config.toml under [indexing] exclude, custom extension mappings in .codegraph/codegraph.json.

06

Language support

38 languages are parsed, but not to the same depth — and the depth is the number that matters. The three tiers below are graded by extraction depth; do not collapse them into "supports 38 languages".

Tier 129Full symbol extraction
TypeScript · TSX · JavaScript · JSX · ArkTS · Python · Go · Rust · Java · C · C++ · C# · PHP · Ruby · Swift · Kotlin · Dart · Scala · Lua · Luau · Objective-C · R · Solidity · Nix · Terraform · Erlang · CFML · GDScript · Pascal
Tier 26Embedded / template extraction
Vue · Svelte · Astro · Razor (.cshtml) · Liquid · XML / MyBatis mapper
Tier 33File level only
YAML · Twig · Properties

In tier 2, symbols come from the scripts and template markup embedded in a host file, so the granularity depends on how that file was written. Tier 3 records files and the relationships between them, with no symbol-level call graph. The language set is fixed and there is no heuristic fallback — a file is either in the table or it is not in the graph.

07

Platforms

Six prebuilt targets, published as codegraph-<version>-<target>.<ext>. Linux builds are statically linked against musl — no glibc dependency and no system SQLite.

Platforms
PlatformArchTarget tripleFormat
Linuxx86_64 (musl, static)x86_64-unknown-linux-musl.tar.gz
Linuxaarch64 (musl, static)aarch64-unknown-linux-musl.tar.gz
macOSx86_64x86_64-apple-darwin.tar.gz
macOSaarch64 (Apple Silicon)aarch64-apple-darwin.tar.gz
Windowsx86_64x86_64-pc-windows-msvc.zip
Windowsaarch64 (ARM64)aarch64-pc-windows-msvc.zip

You can also download an archive straight off the releases page, extract it, and put codegraph on your PATH.

08

Stack and storage

Every choice here serves the same goal: one binary, no external dependency, reproducible output.

Language
Rust, Edition 2024. Shipped as a single executable with no runtime.
Parsing
tree-sitter, one grammar per language, plus cross-file symbol resolution.
Storage
Per-project SQLite with FTS5 for full-text search. SQLite is statically linked, so nothing needs installing on the host.
Index location
.codegraph/ inside the repository — codegraph.db and its WAL, config.toml, codegraph.json, and the daemon’s pid, socket and log.
Command line
Clap subcommands, with completion scripts for five shells shipped in the binary.
Background process
A per-project shared daemon over a Unix socket, watching files and updating the index incrementally; it exits once all clients disconnect and the idle timeout elapses.
Network
Indexing and querying are entirely offline. The HTTP transport binds 127.0.0.1 by default.
Licence
MIT.

09

What it does not do

Stating the boundary is worth more than listing another feature — especially for a tool this easy to mistake for something else.

  • 01

    No similarity retrieval

    No embeddings, no vector store, no turning a question into a vector and looking for near neighbours. It answers structural questions using edges that genuinely exist in the syntax tree. If you want to find code by "roughly what it means", this is the wrong tool.

  • 02

    No judgement

    It tells you the call relationships and the blast radius, not whether the code is any good or whether it has a bug. Types stay the compiler’s job, style the linter’s, correctness the test suite’s.

  • 03

    Cross-file resolution is best effort

    Cross-file symbol resolution is name-based, so an ambiguous call returns several candidates. Dynamic dispatch, reflection and calls assembled at runtime are invisible to static parsing.

  • 04

    The index is not instantaneous

    The daemon lags file writes by roughly a second. Query immediately after an edit and you may read the previous version; tool responses flag which files are pending re-index.

  • 05

    The language set is fixed

    A language outside those 38 is not heuristically "parsed as best we can" — it simply does not enter the graph. That is a deliberate trade: better to under-collect than to emit edges nothing supports.

Get it

Run init once in any repository

Prebuilt binaries, the one-line installer and a source build are all below. It is an MIT-licensed personal project; issues and pull requests live in the same repository.