Skip to main content
Glama
Joel-Wwalker

Codebase Archaeology MCP

by Joel-Wwalker

Codebase Archaeology MCP

An MCP server that answers "why is this line here?" for a local git repo by tracing a line back to the commit that actually introduced it, then to the PR and review discussion behind that commit.

The problem

git blame attributes a line to whoever last touched it. In real repos that is usually a formatter run, an import reorder, or a rename. The naive pipeline — blame → commit → PR — returns "Bob, prettier migration, 2024" and tells you nothing about intent.

This server defeats that:

  • blame runs with -w -C -C (whitespace ignored, moved/copied code followed) and honours .git-blame-ignore-revs.

  • line history follows a range backwards through edits and renames (git log -L), detects cosmetic commits (git show -w produces no output → the change was whitespace-only), and compensates for -L range drift, so likely_origin is the commit that genuinely introduced the content — not the formatter, and not the neighboring lines' history.

  • PR lookup uses GitHub's commits/{sha}/pulls endpoint, which works for squash and rebase merges where commit-message parsing silently fails.

  • When the trace bottoms out at the commit that created the file, the answer says so — git log -L cannot see across a file split, and pretending otherwise would be lying.

Related MCP server: review-dojo-mcp

Tools

Tool

Question it answers

why_this_line(repo, path, line, context=0)

Start here. The whole story: last touch, true origin, evolution, origin PR + review discussion, and an interpretation when blame's answer is misleading.

blame_range(repo, path, start, end)

Who last touched these lines (formatters already discounted)?

line_history(repo, path, start, end, limit=15)

Every commit that changed this range, with likely_origin and a cosmetic_skipped count.

find_removal(repo, pattern, path="", limit=10)

"There used to be a retry here — where did it go?" Pickaxe (git log -S), each hit labelled added / removed / modified.

commit_context(repo, sha)

Full message, author, files, stat for one commit.

pr_for_commit(repo, sha, include_comments=True)

The PR that introduced a commit, with inline review comments and discussion.

repo may be any path inside the work tree; file paths are resolved against the repo root and anything escaping it is rejected.

Setup

Python 3.11+ and git on PATH.

pip install -r requirements.txt

Run over stdio:

python server.py

or explore interactively:

fastmcp dev server.py

Client configuration (stdio)

{
  "mcpServers": {
    "codebase-archaeology": {
      "command": "python",
      "args": ["C:/path/to/code-arch/server.py"],
      "env": {
        "ARCHAEOLOGY_REPOS": "C:/Users/you/src/repo-a;C:/Users/you/src/repo-b",
        "GITHUB_TOKEN": "ghp_...",
        "ARCHAEOLOGY_CACHE": "C:/Users/you/.cache/archaeology.sqlite"
      }
    }
  }
}

Environment variables

Variable

Meaning

ARCHAEOLOGY_REPOS

Allowlist of repositories the server may read, separated by the platform path separator (: on Unix, ; on Windows). A repo qualifies if its toplevel is one of these paths or inside one. Unset = any local repo is allowed — set it when exposing the server to anything you don't fully trust.

GITHUB_TOKEN

GitHub token for PR lookups. Optional, but unauthenticated calls are capped at 60 req/hr; one why_this_line costs up to 3. Rate-limit errors name this variable.

ARCHAEOLOGY_CACHE

Path of the SQLite HTTP cache (default ~/.cache/codebase-archaeology/http_cache.sqlite). Responses are kept ~7 days; commit→PR mappings are effectively immutable, so cached answers cost zero API calls.

Honest limits

  • git log -L cannot trace across a file split (content extracted into a new file). The origin will be the splitting commit, flagged with origin_is_file_creation: true and an interpretation pointing at find_removal to dig further.

  • Cosmetic detection is whitespace-based (git show -w). A formatter that changes quote characters is not "cosmetic" by this test, but the lineage trace still walks through it to the real origin.

  • git log -L on a huge file with deep history is genuinely slow; that is why limit defaults to 15 and git calls time out at 30s.

Tests

python -m pytest

The suite builds a throwaway repo reproducing the failure mode (real origin → whitespace-only reformat → reword) and asserts, among other things, that naive blame credits the formatter while every tool here names the true origin. GitHub tests run against a fake transport — no network needed.

Related MCP Connectors

Related MCP Servers