CodeRAG

CodeRAG

Enables natural-language Q&A over codebases via MCP, using AST-aware chunking, hybrid retrieval, reranking, and call-graph expansion to answer with file:line citations and impact analysis.

Category
Visit Server

README

RepoSage — agentic code-Q&A over a codebase

Ask a repository questions in natural language — "where is auth handled?", "what breaks if I change this function?", "show every caller of X" — and get answers grounded in real source, with file:line citations.

RepoSage exists because generic RAG ("chat with your PDF") fails on code: fixed token-window chunking cuts functions in half, and pure vector search ignores the call graph that actually connects code. RepoSage treats retrieval quality as the engineering problem and is exposed as an MCP server, so it plugs straight into Claude Code / Cursor.

Retrieval pipeline

repo ─► AST-aware chunking ─► hybrid index ─► fusion ─► cross-encoder ─► graph ─► cited
        (function/class/        (dense +       (dense +   rerank         expand    answer
         method units,           BM25)          BM25)     (top pool)     (1-hop)
         calls + imports)
  • AST-aware chunking — one chunk per function / method / class (never a half-function), plus the calls and imports each definition makes. Zero-dependency (ast stdlib); tree-sitter multi-language is a v2 backend.
  • Hybrid retrieval — dense embeddings + BM25 lexical, min-max normalized and fused with a tunable alpha. Beats either alone on code.
  • Cross-encoder rerank — retrieve a wide pool via fusion, then reorder it with a (query, code) cross-encoder for precision (the standard "retrieve wide, rerank precise" second stage). Toggleable; see the eval for its measured, honest effect.
  • Call-graph expansion — after search finds the best definition, walk one hop along the call graph to pull in what it calls / what calls it. This is the signal generic RAG cannot provide, and it's what makes impact questions answerable.
  • Graceful degradation — if sentence-transformers isn't installed, dense retrieval falls back to a deterministic hashed embedding so the whole system still runs end-to-end on a fresh machine.

MCP tools

Tool Purpose
index_repo(path) AST-ingest a repo and build/persist the hybrid index
status() Index size + active embedding backend
search_code(query, k, hybrid) Ranked definitions with per-signal scores
get_context(query, k, expand_graph) Cited context bundle for answering
impact_radius(chunk_id) Blast radius — who calls this definition

Quickstart

uv venv --python 3.12 .venv           # standard CPython (not free-threaded)
uv pip install -e .                    # core: mcp + rank-bm25 + numpy
uv pip install -e ".[embeddings]"      # optional: real semantic embeddings

Register with Claude Code (from this directory):

claude mcp add reposage -- .venv/Scripts/python.exe -m reposage.server

Then in Claude Code: "index this repo with reposage, then ask where auth is handled."

Evaluation

The differentiator is eval/ — labeled, auditable question sets with an ablation that shows what each layer buys. Two corpora: Flask (pallets/flask, 404 chunks, external — the fair test) and this repo's own src/ (53 chunks, dogfood). Every gold label and call edge is verified against the actual source, not guessed.

# Flask (clone once, then run):
git clone --depth 1 https://github.com/pallets/flask .corpora/flask
python -m eval.run --dataset flask

python -m eval.run                    # dogfood on ./src
python -m eval.run --repo PATH        # any repo (with a matching dataset)

Primary result — Flask (19 questions, 404 chunks, equal 8-result budget)

Config hit@8 MRR
vector-only 0.79 0.563
+ BM25 fusion 0.89 0.576
+ cross-encoder rerank 1.00 0.680
+ graph expansion 0.84 0.568

By category (hit@8):

Category vector + BM25 + rerank + graph
semantic 0.88 0.88 1.00 0.75
keyword (exact identifiers) 1.00 1.00 1.00 1.00
impact 0.40 0.80 1.00 0.80

What the numbers actually say (the honest read, not a rigged monotonic table):

  • The cross-encoder reranker is the big win — on a real corpus. It lifts hit@8 from 0.89 → 1.00 and MRR +0.10, helping both semantic (0.88→1.00) and impact (0.80→1.00). Crucially, the same reranker was a wash on the 53-chunk dogfood corpus (see below) — because a tiny corpus has too few distractors for reranking to matter. The lesson: you cannot fairly evaluate a reranker on a toy corpus. Running both corpora is what surfaced that.
  • BM25 fusion pays off on the queries it should — it takes impact queries from 0.40 → 0.80 (exact symbol names) and lifts overall hit to 0.89. Dense handles paraphrase; BM25 handles literal identifiers; fusion gets both.
  • Graph expansion does not improve ranking — it slightly hurts it (0.89 → 0.84, semantic 0.88 → 0.75), and that's reported rather than hidden. Fusing graph neighbors into the ranked list displaces real hits. The call graph is a context-enrichment / impact-analysis feature, not a ranking-fusion layer — so it's evaluated on its own job instead:

Call-graph quality (Flask) — 8 hand-verified in-repo call edges:

Metric Value
caller-recall 1.00
avg callers/node (noise proxy) 3.12

The AST-derived graph recovers every labeled caller edge — which is what makes impact_radius trustworthy on real code.

Secondary — dogfood on own src/ (18 questions, 53 chunks)

Config hit@8 MRR note
vector-only 0.78 0.452
+ BM25 fusion 0.89 0.615
+ cross-encoder rerank 0.89 0.618 flat — corpus too small to test rerank
+ graph expansion 0.94 0.622

Kept deliberately: the contrast between "rerank is a wash" here and "rerank wins" on Flask is the finding. Small-corpus metrics are also saturated, so treat them as directional only.

Raw metrics: eval/results_flask.json, eval/results.json.

Status

v0.1 — pipeline + MCP server working end-to-end; real embeddings (all-MiniLM-L6-v2) + cross-encoder rerank (ms-marco-MiniLM-L-6-v2) wired; 4-stage eval ablation on two corpora (Flask + dogfood) with call-graph metrics; 9 pipeline tests passing. On Flask the reranker reaches hit@8 = 1.00. Next: a code-domain reranker, smarter graph-aware context assembly, and tree-sitter for non-Python repos.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured