Semantic code graph MCP server for coding agents
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
A free, MIT-licensed MCP server that gives coding agents (Claude Code, Cursor, and compatible clients) a semantic code graph of your project β symbols, cross-file calls, references, imports and cross-language boundaries.
Instead of reading files top-to-bottom or grepping for names, the agent navigates the
structure: who calls this function, what does it depend on, what breaks if I change
its signature. It is a thin runtime layer over the
graphlens analysis engine: graphlens provides
the mechanisms (parsing, stable node identity, resolvers); graphlens-mcp owns the storage,
freshness and the agent-facing surface.
π Documentation: https://neko1313.github.io/graphlens-mcp/
Status: early. The core navigation works; see Known limitations.
Coding agents discover structure the slow way β grep, glob, read one file at a time β
rebuilding call paths by hand before the real work even starts. The motivation is the same
as every other code-context tool: stop the agent from grepping. The approach is what
sets graphlens apart.
Most tools answer this by building their own model of your code β an ad-hoc graph
stitched from heuristics, where every tool maps the codebase a little differently and
nothing is authoritative. graphlens takes the opposite bet: it builds on the language's
own real analysis engines β rust-analyzer, gopls, the TypeScript compiler, the bundled
ty type engine β the LSP-grade tooling the industry already trusts. That yields a stable,
real picture of the project (who actually calls what, across files and languages), not a
bespoke approximation. And a stable foundation is something you can build on: attach context
to the parts of a change that matter, auto-extract semantic clusters, answer impact
questions reliably.
That foundation is the graphlens engine β
parsing, stable node identity, and the resolvers. graphlens-mcp is a smart, agent-facing
layer over it, and β honestly β a worked example of how to use the engine: it persists
the graph (so the whole thing isn't held in memory), adds a semantic + clustering layer on
top, keeps it fresh as you edit, and exposes it to agents as navigation tools plus a bundled
skill. From that example it is growing into a self-sufficient system β one that, measured
against the market's giants, aims for stable, reproducible results: better in some places,
worse in others, but honest about which (see How it compares).
graphlens-mcp ships with a reproducible A/B benchmark (benchmarks/)
that drives the same agent against three interchangeable code-context MCP servers β
graphlens, semble (semantic search), and codegraph (graph index) β plus a no-tools
control that measures how much each server adds over the model's own memory. It runs across
real Go / Rust / Python / TypeScript codebases and grades answers deterministically
against oracle gold (no LLM judge), stratified into SIMPLE lookups vs HARD impact /
cross-file questions, and reports accuracy alongside token / tool-call / dollar cost β
because a cheaper arm at equal accuracy wins.
π Results (10 repos Β· 3 models, strong β genuinely weak Β· ~2,400 graded runs β full breakdown, significance tests and reproduction steps at docs: Benchmarks):
SIMPLE accuracy HARD accuracy HARD tokens (median) HARD completion graphlens 0.980 β 1.000 0.899 β 0.921 22.4k β 34.1k β₯ 0.959 on every model codegraph 0.912 β 0.990 0.655 β 0.939 23.2k β 70.0k drops to 0.765 on the weakest model semble 0.647 β 0.961 0.555 β 0.850 21.6k β 74.9k drops to 0.688 on the weakest model none (control) 0.366 β 0.681 0.453 β 0.685 0.1k β 0.9k β Accuracy alone hides the number that matters to a bill: tokens paid per task. graphlens's HARD-tier token spend stays flat (22kβ34k) whether the driving model is strong or weak; codegraph's and semble's balloon past 70k on the weakest model β more than double graphlens's ceiling β for a worse answer, not a better one. graphlens is the only arm that stays clearly ahead of the no-tools control and keeps completion above 0.95 at every model tier: on the weakest model tested (gpt-oss-20b) it holds 0.900 HARD accuracy at roughly half the token cost of codegraph. Pairwise Wilcoxon signed-rank tests (matched by task) confirm the gap is statistically significant on the weaker models, not an artifact of a few outlier tasks β see the notebook for per-model p-values and effect sizes.
Requires Python β₯ 3.13 (a constraint inherited from graphlens).
Python language analysis works out of the box (the ty type engine ships as a
dependency). Other languages parse immediately and unlock full cross-file semantics once
their toolchain is present (Node for TypeScript, the Go toolchain, etc.); without it that
language is reported as degraded rather than blocking init.
init detects the project's languages, indexes the code into a local graph, writes the
MCP server entry into your agent's config and installs the navigation skill. You do not
run serve yourself β your agent launches it from the config. Restart the agent and ask
it something like "what breaks if I change the signature of create_order?".
| Command | What it does |
|---|---|
graphlens-mcp init | Detect languages β toolchain doctor β full index β configure agents β install skill |
graphlens-mcp serve | Start the MCP server over stdio. Launched by the agent, not by you |
graphlens-mcp status | Show detected languages, toolchain status, and graph size/freshness |
graphlens-mcp reindex | Force a full rebuild (e.g. after installing a new toolchain) |
graphlens-mcp remove | Deregister from agents and (with --purge-db) delete the local graph |
Useful init flags: --root <dir>, --agent claude_code --agent cursor (repeatable),
--no-agent, --no-skills, --db <path>.
The graph lives at <project>/.graphlens/graph.db (SQLite). It is a regenerable cache β
safe to delete; reindex rebuilds it. Add .graphlens/ to your VCS ignore (the bundled
init flow assumes it is not committed).
| Language | Engine | Out-of-box |
|---|---|---|
| Python | ty (bundled) | Full semantics immediately |
| TypeScript | Node bridge | degraded without Node; full semantics with Node installed |
| Go | Go toolchain | degraded without toolchain |
| Rust | SCIP / rust-analyzer | degraded without toolchain |
| PHP | PHP parser | degraded without toolchain |
graphlens-mcp status reports the actual resolver status per language. When a toolchain is
missing, that language is reported as degraded (parsed structure, calls/types not fully
resolved) with an install hint β it never blocks init.
Three tools β everything a symbol or file needs comes back as a navigable graph node,
not a dead grep line. Each response carries a graph-quality status (ok | degraded) so the
agent never mistakes a partial answer for a complete one, plus an indexing flag (true
when a background reindex is running, so edges may be temporarily incomplete).
| Tool | Purpose |
|---|---|
search | Find code by NAME, CONTENT, or MEANING β the one way in. Returns graph nodes with their signature (often enough to answer without a follow-up call). Content is matched literally, not as a regex. Scope with path_glob (e.g. "tests/*", "*.ts", "!tests/*" to exclude a subtree); set exhaustive=true to list every matching file (no cap, no signatures) instead of the ranked top-N |
relations | A symbol's neighbourhood in one call: callers, callees, implementors/subclasses, and non-call references β each with its signature. The impact-analysis tool ("what breaks if I change X?", "what implements X?") |
info | Read a specific target: a symbol (node id or name) β source + signature + location; a file path β its symbol outline |
search and relations accept either a symbol name or a node id directly β you don't
need to look up a node id first. Both cap their response size (a large hit set is ranked by
relevance via a small bundled embedding model, not just truncated) and surface true counts
(callers_total, references_total, β¦) when a list is capped, so the agent sees "15 shown
of 22" instead of guessing. If the embedding model can't be fetched (e.g. a first run with no
network), search transparently falls back to name/content matching.
A single mechanism keeps the graph current: a filesystem watcher (serve starts it by
default; disable with --no-watch). When a file changes on disk the server re-indexes the
connected set β the changed file plus the files that import it and the files it imports β
with one full analyze, so cross-file edges are rebuilt correctly rather than left partial.
Deleting a file prunes its symbols and refreshes its importers. There is no polling and no
structure-only "skeleton" phase: every (re)index produces the full graph the resolver can
give. As a backstop, a tool that touches a file the watcher hasn't processed yet triggers the
same connected re-index on access.
Files created, deleted or edited while the server was down are invisible to an event-based
watcher, so serve runs a one-shot reconcile at startup: it scans the project, indexes
new files, prunes vanished ones, and refreshes any that changed β then hands off to the
watcher.
reindex for an exact
graph. Creating a file that an unchanged file already imports is handled β a second
importer pass re-links that importer once the new file is indexed.COMMUNICATES_WITH edges are
re-synthesized for every boundary a re-indexed file touches, so a new or moved
exposer/consumer is linked without a full reindex. A change that leaves a boundary
entirely (a file that stops exposing an endpoint others still consume) may still need a
full reindex for an exact cross-language view; the boundary-based query resolves
connections regardless.graphlens-mcp remove deregisters the server from your agents; add --purge-db to also
delete the local .graphlens/ cache.
See the Architecture and Semantic search pages on the documentation site for the design and invariants.
MIT β see LICENSE.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/graphlens-mcp)<a href="https://allmcps.com/mcp/graphlens-mcp"><img src="https://allmcps.com/api/badge/graphlens-mcp?style=directory" alt="Graphlens Mcp on AllMCPs" /></a>