polycodegraph
About
Multi-language code-graph MCP server with 18 tools (find_symbol, callers, callees, blast_radius, dataflow_trace) for AI assistants — local-first, no API key required, ~3× fewer tokens than Claude+grep at the same correctness.
Details
- Author
- smochan
- Categories
- Developer Tools, Knowledge Base
Jump to
Setup
Install polycodegraph in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/smochan/polycodegraph
Follow the installation instructions in the repository README, then restart your MCP client.
Parse any repo into a queryable code graph. Trace one parameter from a frontend fetch through every layer to the SQL query. Powers Claude Code, Cursor, and Windsurf via MCP — so your AI assistant reads focused context instead of the entire codebase.
Same Claude Sonnet 4.6. Same 10 questions about two real repos (codegraph itself + FastAPI). Only the registered MCP server changes. Reproduce withcodegraph bench agent, raw data inbench/RESULTS_AGENT_LATEST.md.
pip install polycodegraph # the PyPI distribution name codegraph init # the CLI binary + Python module + MCP server are all codegraph (see footnote ↓) codegraph build # parse repo → .codegraph/graph.db codegraph serve # web dashboard at http://127.0.0.1:8765
That's it. Three commands and you have a queryable graph, a 3D dashboard, and an MCP server your IDE can talk to.
Adding a new language is a single tree-sitter parser module + fixture file (~3 hours — seecodegraph/parsers/go.pyfor the v1 template). PRs welcome.
polycodegraph has exactly one opinion:build the right graph, and every interesting feature falls out for free.
The inputs that feed the graph go beyond imports and call edges. polycodegraph reads tree-sitter parses forPython, TypeScript, JavaScript, and Go; capturesevery call-site's arguments as text; recognizes24 framework decoratorsso FastAPI / Flask / Celery / pytest / Click / MCP / Django / SQLAlchemy handlers are never confused with dead code; detectsroutes(@app.get("/x")) andfrontend fetches(fetch,axios,useSWR,useQuery); andstitches URLs across the stack(/{id} ↔ ${id} ↔ :id) so it can trace a fetch all the way to its handler.
The outputs that comefor freeonce the graph is right:
Decorator-aware dead code, role classification (HANDLER / SERVICE / COMPONENT / REPO), blast radius, cycles, untested-function detection, an end-to-end cross-stack trace with rename annotations, a 3D focus-mode dashboard, a Learn Mode lifecycle modal, local embeddings for semantic + hybrid search, an 18-tool MCP server, and a PR-review CI that graph-diffs the branch againstmain.
One SQLite file. No daemon. No network. Travels with your git branch.
┌─────────────────────────────────────────────────────┐ │ tree-sitter parsing │ │ (Python, TS/JS, TSX, JSX, Go) │ └─────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ Cross-file resolution (R1, R2, R3) │ │ ✓ per-name imports ✓ relative imports │ │ ✓ constructor calls ✓ decorators │ │ ✓ self.X.Y chains ✓ fresh instances │ └─────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ SQLite graph (nodes + edges) │ │ DF0: call-site arguments │ │ DF1: routes (FastAPI, Flask, aiohttp) │ │ DF2: fetches (fetch, axios, SWR, useQuery) │ │ DF3: URL stitching (/{id} ↔ ${id} ↔ :id) │ │ DF4: end-to-end trace (fetch→handler→service→DB) │ └─────────────────────────────────────────────────────┘ ↙ ↓ ↘ CLI tools Web dashboard MCP server (graph, roles, (3D focus view, (18 tools for cycles, dead architecture, Claude Code, code, untested) learn mode) Cursor, etc.)
Benchmark — same Claude, varying graph MCP
Four configurations. Same Claude Sonnet 4.6. Same 10 questions across two real codebases (polycodegraph itself + FastAPI).All four configs include Claude's native grep + file-reading tools— what every dev gets out of the box in Claude Code or Cursor. The only thing that changes is whether a graph MCP isalsoregistered alongside.
- claude+grepalone is the most correct (8/10)— Claude can answer most codebase questions by grepping and reading whole files. But it pays the price:336k tokens, $1.17, 78s avg latency.
- + polycodegraphmatches that within one question (7/10) at3× lower cost and 4× lower latency(90k tokens, $0.37, 20s).Because polycodegraph returns small focused subgraphs (~20-50 tokens per call) instead of grep-dumping whole files into Claude's context.
- The other graph MCPs are strictly worse than just grepping.code-review-graph: 3/10 at $0.68. graphify: 5/10 at $0.50. They add tool overhead without paying off in correctness.
Reproduce:codegraph bench agent --only claude+grep,claude+grep+polycodegraph,claude+grep+code-review-graph,claude+grep+graphify. Raw per-run JSONL inbench/agent_raw_latest.jsonl. Full methodology inbench/README.md.
pip install polycodegraph codegraph init codegraph build
codegraph initwrites a project-level.mcp.jsonin the repo —Claude Code and Cursor auto-pick that upas soon as you open the project. For other clients you currently need to add the server to their global config manually (v0.2 will do this for you).
// Claude Code (global) → ~/.claude.json // Cursor (global) → ~/.cursor/mcp.json (or .cursor/mcp.json per workspace) // Windsurf → ~/.windsurf/mcp.json // OpenAI Codex CLI → ~/.codex/mcp.json // GitHub Copilot CLI → ~/.config/copilot/mcp.json // Zed → ~/.config/zed/settings.json under "context_servers" // Continue → ~/.continue/config.json under "experimental.modelContextProtocolServers" { "mcpServers": { "codegraph": { "command": "codegraph", "args": ["mcp", "serve"] } } }
The same five-line JSON snippet works for every client — only the file path changes.
"Which HANDLER nodes have no test coverage?""Show me all the callers ofUserService.loginwith their arguments.""TraceGET /api/users/{id}from the frontend fetch all the way to the database.""What's the blast radius of changing this function?"
All 18 tools return small, focused subgraphs — no context-window flooding.
pip install 'polycodegraph[embed]' codegraph embed # chunks the repo, embeds with nomic-ai/CodeRankEmbed
Unlocks thesemantic_searchandhybrid_searchMCP tools. ~140 MB model download, runs locally, no API keys.
A small FastAPI + SQLAlchemy + React fixture lives inexamples/cross-stack-demo/. Run polycodegraph on it to see DF0, DF1, DF1.5, DF2, DF3, and DF4 all light up:
codegraph build --no-incremental --root examples/cross-stack-demo codegraph dataflow trace "GET /api/users/{user_id}"
See thedemo READMEfor expected output.
What polycodegraphdoesn'tdo yet. Listed here so the benchmark and README claims stay clean.
- Type inference(Mypy / Pyright). DF0 captures argumenttext, not types. Roadmap v0.3.
- Argument-value identity across hops.DF4 emits ordered hops with rename annotations; full single-value propagation from fetch body → route param → service arg → DB column is deferred (v0.3).
- Docstrings are stored on every node but not yet consumed by analysis.Embeddings use them as fallback body text; dead-code, role classification, and dataflow ignore them. Roadmap v0.3.
- Git-history mining(commit-message semantics, author / touch-frequency signals). Not implemented. Git is used only for the current HEAD SHA and PR-review diff. Roadmap v0.4.
- Per-language resolver parity(v0.1.2). Python ships the full R1/R2/R3 fixes. TypeScript R2 patterns (path aliases, fresh-instance binding, decorator-call edges) are deferred.
- Typer CLI symbols are not tagged HANDLER(v0.1.x). DF1.5 only classifies HTTP framework decorators.
- Async / await visualization(v0.4). DF4 walks the synchronous call graph only.
- Error-path branch rendering(v0.4). Learn Mode shows the happy path.
- Auth middleware as a distinct phase(v0.4). Today auth shows up as a regular CALL node.
- Multi-param simultaneous highlighting(v0.4). Single-param selection only.
- Cross-process traces(v0.4). Can't yet link multiple.codegraph/graph.dbfiles.
On the self-graph: from 451 dead-code findings to 0
We run polycodegraph on its own source as a regression target. Dead-code findings dropped from451 → 24+ → 15 → 0as the resolver hardened, decorator-aware entry-point detection landed, and intentional public-API methods were marked with# pragma: codegraph-public-api.
- 3,320 nodes(files, classes, functions, imports)
- 7,557 edges(5,245 CALLS, 1,357 DEFINED_IN, 886 IMPORTS, 28 INHERITS, 12 ROUTE, 27 FETCH_CALL, 1 READS_FROM, 1 WRITES_TO)
- 3 cycles, all documented and accepted (dashboard redraw, parser self-recursion, MCP serve/run resolver false positive)
- 0 dead-code findings(with pragma exemptions for public-API methods)
- 637 tests passing(537 Python pytest + 100 Node tests)
The wedge isn't a fancier graph algorithm — it's that polycodegraph treatstrace this argument across the stackas a first-class operation, not a follow-up grep. Embedding-based retrieval tools (code-review-graph, Cursor, Cody) handle prose / docstrings well; the right architecture isgraph + embeddings in the same MCP loop, and v0.1.0 ships both.
# Graph building codegraph init # interactive setup: detect languages, configure ignore globs, register MCP codegraph build # parse repo with tree-sitter, write/update .codegraph/graph.db codegraph status # graph freshness, last build time, drift indicators # Analysis codegraph analyze # whole-project audit: dead code, cycles, untested, hotspots, metrics codegraph query callers <symbol> # reverse-BFS: who calls this? codegraph query callees <symbol> # forward traversal: what does this call? codegraph query subgraph <symbol> codegraph query deadcode codegraph query untested codegraph query cycles codegraph query hotspots codegraph query metrics # Visualization codegraph serve # web dashboard at http://127.0.0.1:8765 codegraph viz # Mermaid / interactive HTML / SVG codegraph explore # static subgraph explorer pages (good for sharing) codegraph dataflow trace "<M> <path>" # walk DF1→DF4 to trace endpoint frontend→DB # PR review + baselines codegraph review # graph-diff current branch vs baseline; CSV or Markdown codegraph baseline save # snapshot current graph as the local baseline codegraph baseline status codegraph baseline push # optional S3 remote codegraph hook install # pre-push git hook running codegraph review codegraph hook uninstall # MCP + embeddings codegraph mcp serve # MCP stdio server: 18 tools for Claude Code / Cursor / Windsurf codegraph embed # chunk + embed (nomic-ai/CodeRankEmbed); enables semantic + hybrid search # Cross-repo workspace mode codegraph workspace init # ~/.codegraph/workspace.yml codegraph workspace add <path> codegraph workspace remove <path> codegraph workspace list codegraph workspace status codegraph workspace sync [--only <name>]
- Per-name imports:from x import a, b, c→ 3 separate IMPORTS edges
- Relative imports:from ..sibling import func→ resolved path
- Same-file constructor calls:MyClass()→ CALLS edge to__init__
- Follow import targets across file boundaries
- Recognize direct assignments (x = imported_func)
- Detect decorator stacks and classify functions by framework
- Decorator-call edges:@my_decoratorapplied todef func()→ CALLS edge to decorator
- self.X.Ychains:self.service.get_user()→ CALLS edges through property chain
- Fresh-instance binding:MyClass().method()→ CALLS edge to both__init__andmethod
- Conditionalself.Xassignments tracked from__init__
DF0 — Call-site arguments— text capture at parse time, no type inference. Powers signature tooltips + edge labels.
DF1 — HTTP routes— FastAPI / Flask / aiohttp. Syntheticroute::METHOD::/pathnodes.
DF1.5 — Role classification— HANDLER (route-decorated), SERVICE (called by HANDLERs), COMPONENT (utility), REPO (DB access).
DF2 — Frontend fetches—fetch,axios.,useSWR,useQuery, genericapiClient.. Captures method, URL, body-key shape.
DF3 — URL stitching— placeholder normalization, body-key overlap bonus, one-to-many tolerated.
DF4 — End-to-end trace— walks call graph + DF1/DF2 cross-layer edges, emits ordered hops with per-hop arg-flow mapping. Snake_case ↔ camelCase ↔ PascalCase normalization souser_id=userId=UserId. Rename annotations:(was userId)when local name differs.
serialize_hld()surfaces three layers —Infrastructure(framework / ORM / cache / queue / HTTP clients),Application(HANDLER / SERVICE / COMPONENT / REPO nodes),Data(HANDLER-to-route, handler-to-FETCH_CALL, repo-to-SQLAlchemy with DF4 hop chains). Learn Mode reads this to animate request lifecycles.
polycodegraph ships its own PR-review workflow as a template. Once activated, every PR runs polycodegraph on itself, posts the diff, and fails on high-severity findings.
gh auth refresh -h github.com -s workflow cp .github/ci-templates/pr-review.workflow.yml .github/workflows/pr-review.yml git add .github/workflows/pr-review.yml git commit -m "ci: activate codegraph PR review" git push
What it does:*builds a baseline graph fromorigin/main, builds a head graph from the PR, runscodegraph review --format markdown --fail-on high, posts the result as a sticky PR comment.
python -m venv .venv && source .venv/bin/activate pip install -e ".[dev]" ruff check . # lint mypy --strict codegraph # type-check pytest -q # 537 Python tests node --test tests/.js # 100 Node tests ./scripts/test-pr-review-locally.sh # dry-run the PR review workflow
CI checks are defined in.github/workflows/ci.yml. New to the repo? Start withdocs/GETTING_STARTED.md. For commit conventions and PR process, seeCONTRIBUTING.md.
This project is installed from PyPI aspolycodegraphbecause the bare namecodegraphwas already taken when v0.1.0 shipped. Everything else — the Python package you import, the CLI binary you run, and the MCP server key you register — iscodegraph, the original project name. We're planning to unify onpolycodegrapheverywhere in v0.2 (CLI rename with acodegraphalias for one release). For now: two names, one tool.
polycodegraph stands ontree-sitter(parsing),vasturiano/3d-force-graph(3D rendering),networkx(graph algorithms),pydantic(typed schema),typer(CLI),rich(console output),nomic-ai/CodeRankEmbed(embeddings), and theModel Context Protocol Python SDK.
Commercial support, deployments, and custom-licensed forks available — contactsmochan07@gmail.com. polycodegraph itself is and stays MIT; the contact line exists for teams who want enterprise support or specific license arrangements on top.
Pull requests welcome. SeeCONTRIBUTING.mdfor local setup, CI checks, commit conventions, and the one-clickContributor License Agreementyou'll be asked to sign on your first PR.
This is a web browser that enables your coding agent, such as Claude Code, to visit websites on your behalf and assist you in identifying bugs or creating UI test cases.
A stateful LSP runtime for AI agents: warm language server sessions with 50+ tools for go-to-definition, find-references, diagnostics, rename, and more across 30+ languages.
MCP server that gives coding agents program-analysis primitives — data flow, call graphs, taint analysis — so they reason from ground truth instead of grep-and-guess. (same as the GitHub About — keeps your messaging consistent across the web).
An MCP service that equips your workspace with a complete set of AI-accessible development tools for reading, editing, executing, and managing code.
Visual Studio extension with 20 Roslyn-powered MCP tools for AI assistants. Semantic code navigation, symbol search, inheritance, call graphs, safe rename, build/test.
A tool for safely executing local Python code without requiring external data files.
AI-to-AI code review platform — Claude, Codex, and Gemini cross-check each other via MCP, REST API, and CLI for consensus-based results.
Persistent code index using Tree-sitter for fast, precise code search. Replaces grep with ~50 token responses instead of 2000+.
AI-powered code quality analysis to detect best practice violations, security issues, and architectural problems in real-time.
Orchestrates a dual-AI engineering loop where a Primary AI plans and implements, while a Review AI validates and reviews, with continuous feedback for optimal code quality. Supports custom AI pairing (Claude, Codex, Gemini, etc.)
AmazingMCP — MCP Server for .NET / C# Codebases
An MCP server that gives AI agents deep understanding of C# codebases via Roslyn — type search, dependency graphs, usage analysis, and architecture overviews, all from a live in-memory compilation.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





