repo2graph

Bir ajan bir kod tabanını grep ile taradığında, ya tüm dosyaları bağlama döker ya da farklı kelimeler tahmin ettiği için kodu tamamen kaçırır. repo2graph bunun yerine gerçek çağrı grafiğini oluşturur ve neyi döndüreceğine karar vermek için bunu kullanır — böylece çağıranlar ve çağrılanlar zaten ekli olarak, sabit bir token bütçesi içinde gerçek kaynak kodu elde edersiniz.

Dokümantasyon

repo2graph

Cited, token-bounded answers about a codebase, for coding agents and CI.

PyPI CI License: MIT

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) and repo2graph github (clones a repository). Use it from the CLI, as an MCP server in Claude Code or Cursor, or as a GitHub Action.

Try it

uvx repo2graph demo                                   # bundled example repo, five questions answered
uvx repo2graph build . -o .r2g                        # index your own code
uvx repo2graph rag "how does routing work" -o .r2g    # a cited, budget-bounded context pack

Give an agent the same thing over MCP:

claude mcp add repo2graph -- uvx --from "repo2graph[mcp]" repo2graph-mcp .

Cursor, Claude Desktop and other clients: docs/mcp.md. Step-by-step with expected output: docs/quickstart.md.

Is it better than grep?

No, not at finding code. We measured it on 35 questions about Flask, requests, FastAPI and Hono, scored against the definitions that answer them, with both tools held to the same token budget (method, per-question results, reproduction):

Budgetrepo2graphgrep, then read around the hits
2,000 tokens30%35%
4,000 tokens39%61%
8,000 tokens52%72%

Graph expansion adds nothing over BM25 alone at these budgets. The causes are ranking problems: whole-file and whole-class chunks win the seed ranking and use up the budget, and expansion doesn't follow the edge direction the question asks for. They're diagnosed in the benchmark write-up and are the next thing to fix.

What it does do that grep doesn't:

  • Relationships in one hop. repo_neighbours returns a symbol's callers, callees, base classes and defining file, each with a line number. Every edge carries a confidence: a name that could mean several definitions is marked ambiguous and priced at 1/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.
  • PR blast radius in CI. repo2graph impact reports what a diff touches: callers, importers, subclasses, and the files git history says usually change alongside it (CO_CHANGE).

How it compares with Serena, Aider's repo map, CodeGraphContext, code-graph-rag, Sourcegraph, Cursor's index and Claude Code's own search, including when to use those instead: docs/comparison.md.

Five questions to start with

Ask your repoWhat the graph adds
Where is authentication enforced?the guard itself, plus the routes that call it
What calls <function>?CALLS edges into it, each with a confidence score
What tests cover <module>?IMPORTS edges from the test module back to the code under test
What would be affected by changing <api>?the definition, then its direct callers from the CALLS edges into it (explain node)
Trace <a request> from route to persistence.the handler and its callees one hop at a time, each block cited to file and line

GitHub Action

- uses: actions/checkout@v4
  with: { fetch-depth: 0 }   # full history, so CO_CHANGE edges are meaningful

- uses: Srinivasan-78/repo2graph@v2
  with:
    git-history: "500"
    commit-branch: graph     # optional: publish graph.html to a browsable branch

@v2 follows every 2.x release; pin an exact tag (@v2.2.0) to upgrade by hand. The Action never calls an LLM. Inputs, outputs and the PR-impact workflow: docs/github-action.md, docs/pr-impact.md.

Commands

CommandDoes
repo2graph build <path> -o .r2gParse a repo into a graph and chunks (--incremental, --git-history N)
repo2graph query "<q>" -o .r2gBM25 search plus one graph hop
repo2graph rag "<q>" -o .r2gBudget-bounded, cited context pack (--answer sends it to an LLM: opt-in, the only path that sends code anywhere)
repo2graph impact -i .r2g --base mainBlast radius of a diff
repo2graph explain <edge|node|retrieval>Why an edge exists, or why a block was retrieved
repo2graph github <owner/repo> -o <dir>Fetch, build and clean up without a local clone
repo2graph demoIndex a bundled example and answer the five questions above
repo2graph map, repo2graph stats, repo2graph index-status, repo2graph embedRe-render graph.html, report counts and freshness, add optional dense vectors
repo2graph doctor, repo2graph bug-report, repo2graph explain-path, repo2graph completionDiagnose setup, build a privacy-safe bug bundle, say why a path is (not) indexed, shell completion
repo2graph-mcp <path>stdio MCP server: repo_map, repo_search, repo_neighbours, repo_impact, and two status tools

Full flags: docs/cli.md. Python API: docs/python-api.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.
  • 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).
  • Rebuild itself when files change. index-status reports staleness; rebuild with build --incremental.

Symbols, calls and classes are extracted for Python, JS, TS, TSX, Go, Rust, Java, Ruby, C, C++, C#, PHP, Kotlin, Swift, Scala, Bash and Lua. Every other file is still indexed as text. Measured rates for each limitation: docs/limitations.md.

Status

The 2.x CLI, MCP tools and output schema follow semver: breaking changes wait for 3.0. Default paths run locally, send no telemetry and exclude secrets from agent replies unconditionally (privacy, threat model, security policy). A Docker image for read-only, non-root deployments is described in docs/ENTERPRISE_DEPLOYMENT.md.

Contributing

git clone https://github.com/Srinivasan-78/repo2graph && cd repo2graph
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
make lint format-check typecheck test

Branch from develop. Start with .github/CONTRIBUTING.md, docs/good-first-issues.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: docs/README.md.

MIT licensed.