duckdb-codegraph
Reads and queries a local DuckDB code-graph database, exposing impact analysis, structural explanation, and index reporting through the MCP server's read-only tools.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@duckdb-codegraphwhat breaks if I change payments.charge.Charge?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
duckdb-codegraph
A frugal, embeddable code-graph building block for agentic systems — tree-sitter impact analysis and structure explanation over a local DuckDB file, no external service.
duckdb-codegraph is a python package that exposes the actual structure of a
codebase to a local agent, in 3 steps:
analyze a folder of source files with tree-sitter and extract nodes and edges
store that graph in a single DuckDB database baked next to your agent
answer
impact,explain, andreportquestions with a local function call
Where duckdb-vectors answers
"what text is semantically near this query", duckdb-codegraph answers "what
code is affected if this symbol or file changes" and "what is the structure of
this code". The must-be-reliable deliverable is impact: a transitive
reverse-dependency set over the edge graph, with every best-effort edge flagged
rather than silently dropped.
SDK entry point
Open a store against a local .duckdb file and query it. Open read-only in the
serving path, when the index is a frozen artifact baked into the container:
from duckdb_codegraph import CodeGraphStore
store = CodeGraphStore(db_path="codegraph.duckdb", read_only=True)
result = store.impact("payments.charge.Charge")
for hit in result.affected:
print(hit.distance, hit.resolution, hit.node.qualified_name)
explanation = store.explain("payments.charge.Charge")
report = store.report()impact returns the affected set with per-node distance and resolution;
explain returns a node's defines/fan-in/fan-out/bases/subclasses; report
introspects the index.
store.index(folder) is incremental-by-default: a full rebuild runs when the
database is empty or you pass rebuild=True, and otherwise only changed, added,
and deleted files are reconciled by comparing each file's stored etag against
a freshly computed one (the compute_etag content fingerprint). The global
cross-file resolution is re-run so edges that bound to a changed file are
re-resolved; a no-change re-index is a no-op. The incremental result is
identical to a full rebuild of the same on-disk state.
from duckdb_codegraph import CodeGraphStore
store = CodeGraphStore(db_path="codegraph.duckdb")
store.index("./my-project") # full build on an empty database
store.index("./my-project") # incremental re-index (etag-driven)
store.index("./my-project", rebuild=True) # force a full rebuildRelated MCP server: capability-os
Indexing from the CLI
$ duckdb-codegraph index ./my-project --db codegraph.duckdb # incremental by default
$ duckdb-codegraph index ./my-project --db codegraph.duckdb --rebuild # full rebuildThe index verb is incremental-by-default: it runs a full build when the
database is empty and reconciles only changed, added, and deleted files on a
re-run. Pass --rebuild to force a full rebuild.
MCP tool
duckdb-codegraph mcp is an MCP-over-stdio server exposing three read-only
tools:
impact(target, …)— transitive reverse-dependency set for a symbol or file.explain(target, …)— structural neighbourhood of a symbol or file.report()— introspects the index: database path, schema version, languages, and node/edge counts.
An MCP client spawns duckdb-codegraph mcp as a child process in the same
container and talks to it over stdin/stdout; stdio is a same-container
transport, not a network protocol.
The server also serves over Streamable HTTP, selected with
--transport http:
$ duckdb-codegraph mcp # stdio (default)
$ duckdb-codegraph mcp --transport http # http on 127.0.0.1:8000/mcp
$ duckdb-codegraph mcp --transport http --host 127.0.0.1 --port 8000HTTP binds loopback 127.0.0.1:8000 at path /mcp by default; pass --host
and --port to override. Serving stays strictly read-only over both
transports, and both expose the identical impact, explain, and report
tools with the same JSON-object shapes. The HTTP transport is the groundwork
that will later let a client index a repository in a separate sandbox (for
example a GitHub repository); that remote / sandbox indexing is future work
this transport enables, not something shipped here.
Setup for working on the package itself
Requirements:
Python 3.12+
uv(Python env and builds)
Shell commands:
$ make setup # install the Python toolchain into a local venv
$ make test # run the test suite
$ make lint # ruff, mypy, markdownlintThe Makefile is the toolbox
Drive common tasks through make; do not call the underlying tools directly:
make- list common targetsmake setup— check and install the development toolchainmake lint/make format— check / apply ruff, mypy, markdownlint.make test— run the pytest suite.make self-test— capability evidence: index the package's own source withduckdb-codegraphand run a sequence of labelled requests (list files, list functions, change-impact traversal, cross-module symbol context, index overview, most-depended-upon hotspots), each printing a result and asserting a structural fact. Dogfoods the tool on a real multi-module codebase, distinct from the hermeticmake testsuite.make build— build the wheel and sdist (version from the git tag via hatch-vcs).
Project structure
duckdb-codegraph/
├── src/duckdb_codegraph/ # the package
│ ├── store.py # the CodeGraphStore API
│ ├── indexer.py # folder → DuckDB graph index
│ ├── cli.py # the duckdb-codegraph CLI (incl. the mcp verb)
│ ├── mcp_server.py # the MCP-over-stdio server
│ ├── config.py # Settings / DUCKDB_CODEGRAPH_* env
│ ├── models.py # Node / Edge / ImpactResult pydantic models
│ ├── etag.py # compute_etag content fingerprint
│ └── extractors/ # pluggable extractors (python, javascript/typescript)
├── tests/ # pytest suite
├── pyproject.toml # metadata, deps, tag-driven version (hatch-vcs)
└── Makefile # the task toolboxReleases are tag-driven: the version comes from the git vYYMMDD tag, and
pushing a tag publishes to PyPI.
Configuration
Settings resolve with the precedence: explicit argument >
DUCKDB_CODEGRAPH_* environment variable > default.
Setting | Argument | Environment variable | Default |
Database path |
|
|
|
Indexed source root |
|
|
|
Read-only |
|
|
|
Pointers
Worked examples: documentation/examples.md — the
make self-testrequests, explained with observed results.Documentation site: https://bernard357.github.io/duckdb-codegraph/
PyPI project: https://pypi.org/project/duckdb-codegraph/
License
MIT.
This server cannot be deployed
Maintenance
Related MCP Connectors
Ask a codebase what calls what: search, blast radius, paths between symbols, and diffs.
Deterministic context layer for your codebase: change impact, blast radius, answers with receipts.
Search indexed code, trace dependencies, assess change impact, and recall repository memory.
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Related MCP Servers
AlicenseAqualityAmaintenanceEnables read-only querying of a local repository through a deterministic tree-sitter symbol and edge graph, exposing keyword search with exact file:line hits, regex text search, per-file symbol skeletons, caller/callee traversal, and directory-level maps of clusters, hubs, and hotspots over stdio.1051 npm1Apache 2.0- AlicenseNot gradedqualityCmaintenanceServes an AI coding agent a searchable index of a codebase's existing capabilities and past incidents, so it can find and reuse what already exists before writing new code. Also exposes blast-radius analysis for shared code and lets the agent reindex the knowledge base, all via local retrieval with no model calls or API keys.MIT
- AlicenseNot gradedqualityAmaintenanceServes a repository's code knowledge graph over stdio (MCP) so coding agents can look up symbols, trace callers and callees, compute blast radius, list file symbols, run hybrid lexical-plus-graph search, and get citation-grounded answers from file:line evidence instead of guessing from text chunks. All tools work offline straight from the graph, with prose synthesis only when an OpenAI-compatible LLM endpoint is configured.15MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents and reviewers to query a deterministic code dependency graph for callers, routes, pages, tables, and config with file:line evidence instead of grepping. One server can serve many indexed graphs, supporting cross-repository impact analysis.1,680 PyPI4MIT