repo-history

repo-history

Exposes a repo's historical engineering memory (decisions, landmines, guardrails) via MCP tools for AI coding agents.

Category
访问服务器

README

repo-history

Git archaeology for AI coding agents. Most tools index a repo as it exists today. repo-history walks the repo's entire commit history, works out why it became what it is, and writes durable engineering memory your coding agent can read.

Senior engineers carry context that isn't in the current code: "we tried X and reverted it," "this guard exists because of bug Y," "that abstraction was removed for a reason." That knowledge is buried in commits. repo-history digs it out and writes it down.

Run it once. Commit the output. Every future agent session — and every new teammate — inherits the repo's memory.

What it produces

A .repo-memory/ directory. It leads with the prescriptive guardrails an agent should load — the part a controlled study found actually helps — and keeps the narrative history as a human-onboarding bonus.

File What's in it
GUARDRAILS.md The flagship. Terse do/don't rules + decision-constraints, each evidence-linked and tagged [observed] (stated in a commit/PR) or [inferred] (deduced from a diff). This is what an agent loads.
LANDMINES.md Do-not-repeat lessons: reverts, removed abstractions, failed approaches — with the receipts.
DECISIONS.md Past decisions, framed as constraints, grounded-first.
onboarding/TIMELINE.md How the codebase evolved, in chapters — for humans getting oriented.
onboarding/ARCHITECTURE.md The system today, annotated with how it got here.
onboarding/HOTSPOTS.md Churn, change-coupling, bus-factor. Purely mechanical — zero LLM tokens.
*.json Machine-readable mirrors (carrying the trust grade), shaped so the MCP server can serve them.

Why lead with guardrails? A controlled ablation of repository context files found that narrative overviews don't measurably improve a coding agent's accuracy, while instructions and constraints — exactly what landmines and decision-rules are — do. So the output puts the agent-useful part first and treats the story as onboarding for people.

Real output

repo-history run on its own repo produced 15 decisions and 5 landmines from 7 commits. Every one was reconstructed from commit diffs alone — none of it is written down in the source:

Do not parse git --numstat paths as plain strings; rename output has three distinct shapes. git emits renames as old.py => new.py, src/{old => new}/file.py, and src/{ => sub}/file.py (empty left side) … naive splitting will silently produce bogus paths.

Never trust a recorded head sha blindly — check it still exists before computing a since range. After a rebase or force-push the head stored in index.json can vanish from the repo … rather than silently producing a wrong (and wrongly-scoped) commit range.

The full, unedited run is in examples/self-analysis/.

Install

Requires uv. The AI analysis step also needs Claude Code; the plain CLI (history stats, hotspots) works on its own.

# straight from GitHub — works today
uv tool install git+https://github.com/hr23232323/repo-history

# or, once published to PyPI
uv tool install repo-history

Then add the Claude Code skill:

repo-history install-skill          # adds /repo-history to the current project
repo-history install-skill --global # ...or to every project (~/.claude)

Use

# 1. plan — mechanical pass + episode manifest (deterministic, no LLM, no cost)
repo-history plan --branch main

# 2. analyze — run /repo-history in Claude Code; it fans out subagents over the episodes

# 3. build — render .repo-memory/ from the analyses
repo-history build

# later: only pay for what's new
repo-history status
repo-history plan --since <sha>

Then commit .repo-memory/.

Serve it to agents live (MCP)

Instead of (or as well as) committing the files, expose the memory over MCP so an agent can query it on demand — "why is this file like this?", "anything I should know before I change X?":

uv tool install "repo-history[mcp]"
repo-history mcp        # stdio server over ./.repo-memory

Tools: why_is_this(path), list_decisions(topic), list_landmines(), check_before_you_do(proposal), get_timeline(), get_hotspots(). The server is a pure reader — no LLM, no git, no network.

How it works

Two deterministic halves with the LLM sandwiched between them. The halves only ever talk through files on disk.

git history
    │
    ▼
┌──────────────────── deterministic engine (this package) ─────────────────────┐
│  plan    hotspots · change-coupling · revert detection · drop trivial commits │
│          → segment by release → cluster into "episodes" → condense diffs      │
│          → enrich with PR/issue "why" (GitHub) → scrub secrets                │
└──────────────────────────────────────────────────────────────────────────────┘
    │  .repo-memory/.work/  (one Markdown bundle per episode)
    ▼
┌───────────────── LLM orchestrator (/repo-history skill) ─────────────────────┐
│  map     one subagent per episode → {summary, decisions, landmines}          │
│  reduce  roll them up into a coherent narrative                              │
└──────────────────────────────────────────────────────────────────────────────┘
    │  validated JSON
    ▼
┌──────────────────── deterministic engine (this package) ─────────────────────┐
│  build   render .repo-memory/*.md + *.json                                    │
└──────────────────────────────────────────────────────────────────────────────┘

The LLM step runs inside Claude Code, so it uses your existing subscription. There's no API key to configure and no per-token bill from this tool.

The "why" lives in pull requests

Commits say what changed; the PR that merged them, the issue it closed, and the review discussion usually say why. When the repo is on GitHub and gh is authenticated, repo-history automatically pulls that context into each episode (PR body, linked-issue problem statement, human review notes — bots filtered, and all secret-scrubbed like everything else). It's what lets a claim be graded [observed] rather than [inferred]. No GitHub, no gh, or offline? It falls back to commits-only. Turn it off with --no-github.

Why not analyze every commit?

A large repo has tens of thousands of commits; LLM-analyzing each one is slow, noisy, and expensive. The engine spends tokens only where there's signal:

  • Drop the noise — lockfiles, minified bundles, generated files.
  • Segment by release/tag — free, meaningful history windows.
  • Cluster by change-coupling — commits touching the same files become one episode.
  • Always keep landmarks — reverts get their own episode; they're the richest signal.
  • Condense diffs — squashed and truncated, never whole file blobs.
  • Run incrementally — after the first pass, only new commits cost anything.

Swappable analysis methods

How history is read is a plugin. The pipeline shape is fixed, but the method — what counts as signal, how commits become episodes — is swappable behind a registry.

repo-history methods                          # list registered methods
repo-history plan --method mechanical         # the built-in, LLM-free method
repo-history plan --method mechanical --json  # inspect a method's output, write nothing

Adding one is a single registered file and nothing downstream changes. See docs/adding-a-method.md.

Safety

  • Read-only. The engine only runs git log/git show. It never writes to your repo, and never uses a shell string (no injection via refs or paths).
  • Secrets are scrubbed before any repo content reaches an LLM: private keys, provider tokens, and key = "value" pairs are redacted at the boundary. It errs toward redacting. It's a safety net, not a guarantee — don't rely on it to make a repo full of live credentials safe.
  • Local-first. Output is plain files in your repo. Read them, diff them, review them before you commit them.

Development

uv pip install -e ".[dev]"
uv run pytest

Tests run against a synthetic fixture repo built in a temp dir — with a real rename, a revert, and an annotated tag — so the history shapes that matter are actually exercised.

Status

Alpha, but working end-to-end: the deterministic engine, the /repo-history skill, incremental re-runs, and the MCP server are all in place (see the self-analysis example). The mechanical analysis method is the only one shipped so far; more (and better episode grouping) are where the work goes next.

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选