Skip to main content

CodeGraph MCP

CodeGraph is a local MCP server that builds a function-level code graph for TypeScript and JavaScript repositories and exposes it as tools an AI assistant can query. It helps answer structural questions such as who calls a function, what a component renders, which middleware runs on a route, and which symbols are impacted by a change.

This repository is also structured to be installed and run as a Python package for MCP clients. It includes:

  • a package entry point for MCP hosts to launch the server
  • installable metadata for local or registry-based distribution
  • a foundation for adding support for more languages over time

Install locally

python -m pip install -e .

Run as an MCP server

After installation, MCP clients can launch the server with:

codegraph-mcp

Everything runs locally. No source code leaves your machine.

Quick start

# 1. install (once)
E:\RedTokens\.venv\Scripts\python.exe -m pip install -r requirements.txt
cd extractors/typescript && npm install

Then register the server with your client (see Configuration) and, from a chat, point it at any repository you want to analyze:

use_repo("C:/path/to/your/repo")

That's it — the graph builds on first use, then keeps itself in sync. No manual indexing step.


Architecture

Your repo (.ts .tsx .js .jsx .mjs .cjs)
        │
        └─ ts-morph daemon (Node)  ── TypeScript compiler API, stays warm
                │                      resolves calls semantically, incl. CommonJS require()
                │
                │   nodes: function arrow method objMethod route cron class hook value
                │   edges: CALLS RENDERS INSTANTIATES EXTENDS IMPORTS EXPORTS MIDDLEWARE_OF
                ▼
        KùzuDB  (~/.codegraph/graphs/<repo-slug>/db)      ← one graph PER REPO
                │
                │   + RELATED_TO edges, tags, notes  ← written by the AI
                │   + <db>_ai.json sidecar           ← makes those survive rebuilds
                │
        ┌───────┴────────────────────────────────┐
        │   ONE process (codegraph/app.py)       │
        │   ├── MCP over stdio  ──► Claude       │
        │   └── viz over HTTP   ──► your browser │
        └────────────────────────────────────────┘

Why one process

KùzuDB is a single-process embedded database. Two OS processes cannot open the same graph — even read_only=True fails against a live connection. But within one process, MCP tool calls and the viz's HTTP handlers share a single GraphStore whose every execute() is serialized through an RLock. So the AI can write annotations while you watch the visualization — the calls simply queue.

That's why server.py (MCP) and viz.py (HTTP) are launched together by app.py instead of as separate processes.

Two layers

Layer What it captures Written by
Static structural skeleton — what calls/renders/extends what ts-morph, deterministic
AI evolution semantics — "writes to this table", "authenticates this route" AI, via annotate_symbol / add_relationship

The static layer deliberately avoids ORM/framework-specific hardcoding (that would make it Mongoose-only, Express-only). The AI supplies meaning by reading code and persisting what it learns — and that knowledge survives code edits and restarts (see AI sidecar).


The 19 MCP tools

Setup

Tool Purpose
use_repo(path, rebuild=False) Point at a project; builds on first use, else opens + syncs. Call this first.
reindex() Force an immediate re-scan (rarely needed — reads auto-sync).

Query structure

Tool Purpose
search_symbol(query) Substring search → exact names. Entry point for every other tool.
explain_symbol(symbol) Best first call — definitions, callers, callees, renders, class info, AI notes in one shot.
get_callers / get_callees Direct (one hop).
impact_of(symbol, depth) Transitive callers — "what breaks if I change this".
trace_flow(symbol, depth) Transitive callees — execution path.
get_render_tree(component) JSX composition: renders / rendered-by.
get_class_hierarchy(class) extends / subclasses / instantiators.
get_file_imports(file) File deps + reverse deps + exports.
get_middleware_for(route) Middleware chain on a route.

AI knowledge layer

Tool Purpose
annotate_symbol(symbol, tags, note) Attach tags + a note. Tags merge.
add_relationship(from, to, type, note) Record a semantic edge (WRITES_TO, AUTHENTICATES, …).
get_relationships(symbol, type?) Recall AI edges, both directions.
find_by_tag(tag) All symbols with a tag.

Visualization

Tool Purpose
start_viz(port=0) Start the 3D viz; returns the URL. 0 = first free port from 8000.
stop_viz() Stop it, free the port.
viz_status() Whether it's running, and where.

Node kinds & edge types

Node kind Meaning
function arrow method objMethod callables
route HTTP route handler (carries httpMethod + httpPath)
cron scheduled job
class class declaration
hook useXxx naming convention
value PascalCase const from a call — e.g. const User = mongoose.model(...)
Edge Meaning
CALLS foo() / obj.foo()
RENDERS <Foo/> inside another component's JSX
INSTANTIATES new Foo()
EXTENDS class A extends B
IMPORTS / EXPORTS file-level
MIDDLEWARE_OF middleware → route
RELATED_TO AI-authored, kept in a separate table so discovered ≠ deterministic

AI sidecar

Annotations live as columns on Symbol rows, and a rebuild (reset()) wipes the whole graph. To keep AI knowledge durable, every annotation is mirrored to a JSON sidecar and re-applied after each rebuild, matched by name + file (not symbol id — ids embed line numbers that shift on every edit).

  • Written through on every annotate_symbol / add_relationship
  • Replayed as the last step of every build
  • Orphans (symbol deleted) are kept, so a note snaps back if the symbol returns
  • Survives use_repo(..., rebuild=True)

Visualization

An interactive 3D force graph, served by the same process that speaks MCP.

  • Light/dark theme, colorful gradient background, glass panels
  • 2D / 3D toggle, color by kind or file, optional node labels, focus mode
  • Edge-type filters with live counts — isolate just RENDERS, etc.
  • Gold nodes = AI-annotated; sidebar shows tags, notes, AI relationships
  • ↻ Reset & Rescan — rebuild from the latest code, streamed live
  • Detail panel: kind/async/route badges, direct connections by edge type, transitive impact & flow

Default http://127.0.0.1:8000. If that port is taken it automatically tries 8001–8009 — call viz_status() (or read the startup line on stderr) to see where it landed.

A busy port can never kill the MCP connection: uvicorn calls sys.exit(3) on a failed bind, so ports are probed before uvicorn sees them and serve() is wrapped to swallow SystemExit.


Configuration

Two different clients read two different files — this trips people up.

Client Config file
Claude Code C:\Users\<you>\.claude.json → top-level mcpServers
Claude Desktop C:\Users\<you>\AppData\Roaming\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "codegraph": {
      "command": "E:\\RedTokens\\.venv\\Scripts\\python.exe",
      "args": ["-m", "codegraph.app"],
      "env": { "PYTHONPATH": "E:\\RedTokens" }
    }
  }
}

PYTHONPATH is required — these clients ignore a cwd key, so it's the only way Python finds the package.

Optional env vars:

Var Effect
CODEGRAPH_REPO Auto-open this repo at startup (skips needing use_repo)
CODEGRAPH_VIZ_AUTOSTART=0 Don't start the viz at boot (use start_viz instead)

If Claude Desktop and Claude Code both register it, each spawns its own server. That's now safe — the second gets its viz on 8001 and full MCP — but only one process can hold a given repo's graph (Kùzu). Register it in one client if you want a single shared graph.


Paths reference

Code

Path What
E:\RedTokens\ project root
codegraph\app.py entrypoint — MCP (stdio) + viz, one process
codegraph\server.py the 19 MCP tools + server instructions
codegraph\viz.py FastAPI viz app + VizController (start/stop/port fallback)
codegraph\viz_page.html the entire 3D UI (single self-contained file)
codegraph\workspace.py active repo, per-repo DB resolution, lazy auto-sync
codegraph\graph_store.py KùzuDB wrapper, schema, queries, AI sidecar
codegraph\indexer.py full build + incremental sync
codegraph\callsites.py tree-sitter call sites (tier 2/3 fallback)
codegraph\extractors\ tiered extractor protocol + tier-1 ts-morph client
codegraph\AUTONOMY.md how to make the AI drive this by itself
extractors\typescript\extractor.js the ts-morph daemon (Node)
extractors\typescript\try.js manual daemon test: node try.js <repoPath> [symbol]
.venv\ Python environment

Data (nothing is stored inside your repos)

Path What
~\.codegraph\graphs\<name>-<hash>\db that repo's KùzuDB graph
~\.codegraph\graphs\<name>-<hash>\db_cache.json per-file content hashes for sync
~\.codegraph\graphs\<name>-<hash>\db_ai.json AI sidecar — annotations + RELATED_TO
~\.codegraph\state.json last-used repo

The slug is basename-sha1(abspath)[:8], case-normalized — so two checkouts named backend never collide, and E:\Proj / E:\proj resolve to the same graph.

Runtime

Viz URL http://127.0.0.1:8000 (falls back to 8001–8009)
MCP transport stdio (client-spawned)

How syncing works

The graph is kept fresh automatically — you never reindex by hand.

  1. Every read tool calls ensure_ready() first: hash every source file, compare to cache (debounced 3s).
  2. Nothing changed → no-op, returns immediately.
  3. Files modified/created → incremental path: the daemon patches just those files and returns the recomputed edge set; only those files' node slices are swapped.
  4. Files deleted → full rebuild (the daemon has no remove-file path; a fresh glob drops them correctly).
  5. Either way, the AI sidecar is replayed last so annotations survive.

Note on performance: the incremental path is verified correct (byte-identical to a full rebuild) but is currently only marginally faster, because the daemon is spawned per sync call and recomputes all edges globally. Real speedup needs a persistent daemon across syncs + scoped edge extraction — see the known-limitations note below.


Running standalone (dev)

python -m codegraph.app        # MCP over stdio + viz  (what clients launch)
python -m codegraph.server     # MCP only
python -m codegraph.viz        # viz only
python -m codegraph.indexer <repo> [--sync]   # build/sync a graph from the CLI

Don't run two of these against the same repo at once — Kùzu allows one process per graph.

Metadata

Release files for redtokens-codegraph-mcp 0.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for redtokens-codegraph-mcp 0.1.4
File Size Uploaded
redtokens_codegraph_mcp-0.1.4.tar.gz 2.7 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for redtokens-codegraph-mcp 0.1.4
File Interpreter ABI Platform
redtokens_codegraph_mcp-0.1.4-py3-none-any.whl Python 3 none any Details

Total release size: 5.5 MB

Release files / redtokens_codegraph_mcp-0.1.4.tar.gz

Download URL redtokens_codegraph_mcp-0.1.4.tar.gz
Size 2.7 MB
Tags Source
SHA-256 checksum
How to use checksums
1b69a192e2b4c06a7c09e646fce2151f6649dd6d0438b8ff18e8bda0c272b644
BLAKE2b-256 checksum
How to use checksums
43cc042e8b542195fab0150902b8b885c6fccabf670f8d2aa7188e9bd01e45ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.6

Release files / redtokens_codegraph_mcp-0.1.4-py3-none-any.whl

Download URL redtokens_codegraph_mcp-0.1.4-py3-none-any.whl
Size 2.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
eac71b68a7e86049a9c63c93ee26ed55bcdcdf3b2a2cbc9469a929599cb1dd00
BLAKE2b-256 checksum
How to use checksums
82e9e2caf85ee2adc60ece410594afc010e848b209a352a5be9551f7e573a8f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.6

Release history Release notifications | RSS feed

0.1.6

2 release files

0.1.5

2 release files

This release

0.1.4 This release

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page