
repo2graph
io.github.Srinivasan-78由 GitHub 账号 Srinivasan-78 发布v5.0.0更新于 Nov 1, 2026
Ask a codebase a question, get back the source that answers it — every block cited to file:line.
概览
本地 MCP 服务器,把代码库索引成调用/导入图,并向助手返回带引用、受 token 上限约束的源码答案。
- 可以做什么
- 用 BM25 加一跳图扩展检索仓库,返回以 file:line 引用开头的源码块
- 查看某个符号的调用者、被调用者、基类和定义文件,每条边都带置信度
- 按跳数和访问上限遍历符号的反向依赖(影响范围)
- 生成仓库结构图,并把每次回复限制在硬性 token 上限内(MCP 下最多 12k token)
- 解释某条边为何存在,或某段代码为何被检索到
- 适用场景
- 适合需要助手回答跨文件的结构性问题时使用,例如谁调用了什么、某符号被哪些代码依赖、哪些测试覆盖某模块,并希望答案带引用且不超出固定上下文预算。README 明确说明:单文件关键词查找用 grep 更合适。
- 运行要求
- 以 Python 包形式通过 stdio 在本地运行(uvx,Python 3.11–3.14),需先用 build 命令索引仓库。无需 API 密钥、模型、语言服务器或数据库。Linux 需 glibc 2.34 以上;Alpine/musl 及较旧发行版不受支持。可选的向量检索需额外安装包并下载模型。
安装
在 SourceWeft 中
- 打开 控制台中的 repo2graph,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
repo2graph
Cited, token-bounded answers about a codebase, for coding agents and CI.
[repo2graph building a map of a repository, then answering a question about it, in a terminal]Ask a repository a question and get back the source that answers it. Every block is headed
[cite: path:start-end], and the whole reply fits under a token ceiling that the tool enforces.
One tree-sitter pass records who calls whom, who imports what, and which files keep changing
together in git. Retrieval starts from BM25 matches and follows those links.
It needs no model, no API key, no language server and no database. Building, querying and the
MCP server make no network calls; the only exceptions are rag --answer (opt-in, sends the pack
to an LLM), repo2graph github and a rag/query target given as a GitHub spec (both clone a
repository), and --vectors/embed (download the embedding model on first use). Parsers are part of that promise:
tree-sitter-language-pack is pinned below 1.0 so every grammar arrives compiled into the
installed wheel, rather than being downloaded on first parse — see
SECURITY.md. Use it from the CLI, as an MCP server in Claude Code or Cursor, or as a GitHub Action.
Try it
Give an agent the same thing over MCP:
Cursor, Claude Desktop and other clients: docs/mcp.md. Step-by-step with expected
output: demo in docs/cli.md. What it produces on
thirteen well-known repositories — Django, FastAPI, React, Kubernetes, Linux and others, each at a
pinned commit with the command to reproduce it: examples/.
In VS Code, the extension in editors/vscode/ (a preview, built from
source) shows the callers, callees, base classes and co-changed files of the symbol at the cursor,
through the same MCP server.
Is it better than grep?
On cross-file structural questions, yes. On single-file lexical queries, no — grep is the
better tool. Both halves are measured on 40 lexical and 40 structural questions about Flask,
requests, FastAPI and Hono that repo2graph was not tuned against, scored against the
definitions that answer them, every retriever held to the same token budget
(method, full tables and diagnosis; raw rows in
results_holdout_final.json).
Where repo2graph wins: cross-file structural questions
grep structurally cannot traverse dependency edges, compute reverse call closures, or follow cross-module delegation. On questions whose evidence provably spans a cross-file graph edge:
The graph is what does it, and that is the comparison that matters: expansion adds +5/+12/+24 pp over the same retriever with expansion switched off. Against grep the margin is +15/+39/+41 pp — it widens with budget rather than closing, because grep has no edge to follow however much room it is given. It also gets there for fewer tokens than grep at every budget, by 7, 7 and 398 mean tokens, because a cited definition is a smaller thing to return than a window around every textual hit.
Where grep wins: single-file lexical questions
On purely lexical questions where the evidence sits in a single file, text search is grep's
optimum, and this gap is real: −11/−19/−14 pp. We have not closed it. The remaining cause looks
like vocabulary mismatch rather than ranking — a question that says "datetime" does not match
code that says "timestamp" — which is why the
dense-vector path closes it to −2 pp at 8,000
tokens and more BM25 tuning has not. That path needs a downloaded model, so it is opt-in
(pip install "repo2graph[rag]") and the zero-dependency default stays the default.
That extra pulls PyTorch, which on Linux brings the NVIDIA CUDA wheels (several GB); the model is
fetched from Hugging Face on first use and its own licence and training data are yours to review
before you adopt it. Once it is cached, set HF_HUB_OFFLINE=1 so later runs make no request.
If that is too much to carry — on a CI runner, say — pip install "repo2graph[rag-static]" and
--embed-backend static get dense retrieval without torch: model2vec is a token→vector table
plus mean pooling, so inference is numpy, and it costs ~60 MB of packages and a ~31 MB model.
It is a different model (256-dim against 384), not a cheaper way to run the same one, so expect
it to retrieve differently — the figures above are the rag backend's. Pass the same
--embed-backend on the query side as you did to embed: the recorded model id is prefixed per
backend, so a mismatch is refused rather than silently fused.
Where repo2graph wins for agents: fewer turns
In simulated agent workflows (search → read → answer, via scripts/agent_eval.py). No
model is in the loop — the "agent" is a deterministic policy over real ripgrep and a real index:
Four times the structural success rate, and it reaches an answer in one or two turns where grep needs three. The turn count is the number that moved most — structural went 3.1 to 1.9 — because sharper seed ranking puts the answer in the first pack more often, and a turn saved is worth more to an agent than a token saved. It is not cheap: 4.4× grep's tokens on the structural set and 2.8× on the lexical one, and grep wins precision per read on both. repo2graph buys recall and turns with context; the budget-matched comparison is the single-shot tables above.
For completeness, the 35+10 question set this page used to report — visible since the first version of these tables and therefore a regression set, not evidence — now reads 44/63/80% lexical against grep's 35/61/72%, and 60/80/100% structural against grep's 20/20/70%. Those are the better-looking numbers, which is exactly why the held-out set is the one quoted above.
What it does do that grep doesn't:
- Relationships in one hop.
repo_neighboursreturns a symbol's callers, callees, base classes and defining file, each with a line number. Every edge carries aconfidence: a name that could mean several definitions is markedambiguousand priced at1/n, not guessed. - A hard ceiling. The pack is measured, clamped and re-measured before it's returned (12k tokens max over MCP), so an agent can't flood its own context through this tool.
- Reverse closures from the graph.
repo_blast_radiuswalks what depends on a symbol, bounded by hop count and visit cap, with a citation per edge.
How it compares with Serena, Aider's repo map, CodeGraphContext, code-graph-rag, Sourcegraph, Cursor's index and Claude Code's own search, and with the dependency-graph tools Madge, dependency-cruiser and CodeSee, including when to use those instead: docs/comparison.md. Looking for a Sourcetrail alternative? It is not a drop-in replacement — there is no interactive desktop UI — and the comparison says what it does instead.
Five questions to start with
GitHub Action
@v5 follows every 5.x release; pin an exact tag (@v5.0.0) to upgrade by hand. The Action never
calls an LLM. Inputs and outputs: docs/cli.md.
Commands
Full flags: docs/cli.md. Python API: docs/python-api.md. Build cost up to 50,000 files: benchmarks/perf/README.md.
What it can't do
- Resolve calls by type. Calls are matched by name, scoped by class, file, imports and
directory.
x.get()on a receiver of unknown type is recorded as a low-confidence guess, not a fact. For exact references, use a language-server tool, or handbuild --scip index.scipa SCIP index (fromscip-python,scip-typescript, ...) to make the calls and bases it covers exact; see docs/architecture.md. - See dynamic dispatch, reflection or computed imports. A missing edge doesn't prove that no call exists.
- Cross language boundaries (Python calling C++ through bindings).
- See a route that is registered by a call.
build --framework-edgeslinks decorator-declared routes to their handlers (FastAPI, Flask, Starlette, Sanic, NestJS) and adds a node per endpoint, soGET /users/{id}is a thing you can ask about. Express, Hono and Django'surlpatternsregister with a call instead —app.get("/x", handler)— where the handler is an argument and often an inline function, and those get no edge.
Symbols, calls and classes are extracted for Python, JS, TS, TSX, Go, Rust, Java, Ruby, C, C++,
C#, PHP, Kotlin, Swift, Scala, Bash, Lua, Objective-C and HCL (Terraform), plus the <script> blocks
of Vue and Svelte components and the code cells of Jupyter notebooks. Every other file is still
indexed as text. The
specific cases that defeat it — reflection dispatch, string-keyed registries, barrel re-exports —
are pinned as known failures in the
synthetic regression suite, and
per-language coverage is scored, unevenly, in
docs/architecture.md §4.
Two of those nineteen are benchmarked on real repositories: Python (Flask, requests, FastAPI) and TypeScript (Hono). Treat the rest as parsed-and-unmeasured. That is not a formality — the retrieval benchmark found two parse gaps in the one TypeScript repository as soon as it looked, one of which was hiding Hono's entire public API, and neither would have been visible without a real repository to ask questions about.
Status
The 3.x CLI, MCP tools and output schema follow semver. Default paths run locally, send no telemetry and exclude secrets from agent replies unconditionally (what never leaves your machine, how credential files are excluded, reporting a vulnerability). A Dockerfile for read-only, non-root local builds is provided (.github/SECURITY.md).
Platform & Environment Requirements
Run repo2graph doctor to diagnose environment and platform support.
Security & Maintenance Posture
- Single maintainer: repo2graph is developed and maintained by a single author (@Srinivasan-78).
- Automated gates: Pull requests must pass automated CI checks (ruff, mypy, multi-OS test matrix, synthetic regression benchmarks).
- Review policy: Pull requests require 0 third-party review approvals to merge to
main. - Commit signing: Commit signing is not currently enforced on
main. - Integrity: Releases are published to PyPI with provenance attestations.
uv.lockpins every dependency by hash for CI and contributors (uv sync --frozen); a plainpip install repo2graphresolves its own versions within the ranges inpyproject.tomland does not read it.
Contributing
Branch from develop. Start with .github/CONTRIBUTING.md and
docs/architecture.md. The most useful contribution right now is new
questions for the retrieval benchmark, especially on repositories
you know well. All docs: architecture, CLI,
MCP, Python API, comparison.
MIT licensed.
来源:README.md,提交 2a30c17
工具
0版本历史
10- v5.0.0最新Nov 1, 2026
- v4.1.0Oct 23, 2026
- v4.0.0Oct 12, 2026
- v3.0.0Oct 6, 2026
- v2.2.0Sep 27, 2026
- v2.1.0Sep 24, 2026
- v2.0.0Sep 22, 2026
- v1.6.0Sep 20, 2026
- v1.5.4Sep 18, 2026
- v1.5.1Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分