内容
# mcp-git-historian

**MCP 服务器,用于 Git 考古 — 变动热点、责任归属摘要、总线因子、提交取证和任意本地仓库的文件历史**
## 为什么
每个代码库都蕴含着答案,这些问题在维护过程中最为重要:*哪些文件总是出问题?谁真正了解这个遗留模块?那个奇怪的常量是什么时候出现的?如果那个开发人员离开了会发生什么?* 答案都埋藏在 Git 历史记录中,但挖掘它们意味着需要使用 `log`、`blame`、`shortlog` 和 pickaxe 调用,并带有神秘的标志 — 所以没人做这件事。
`mcp-git-historian` 直接为你的 AI 助手提供这些取证工具。它调用你已经拥有的 `git` 命令行界面(无需额外依赖,无需网络调用,无需离开你的机器),并返回结构化的、适合大型语言模型的摘要:热点排名、所有权百分比、知识孤岛和代码首次出现的确切提交。
## 工具
| 工具 | 参数 | 返回值 |
|---|---|---|
| `repo_summary` | `repo_path` | 当前分支、总提交次数、首次/最后提交(哈希 + 日期)、前 10 名贡献者、最近 12 个月的每月提交次数 |
| `hotspots` | `repo_path`, `since="1 year ago"`, `top=15` | 按提交次数 + 添加/删除行数排名的文件;排除已删除的文件;前 3 名标记为高变动重构候选 |
| `file_history` | `repo_path`, `file`, `limit=20` | 触及文件的提交(哈希、日期、作者、主题、+/- 行数),通过 `--follow` 跟踪重命名 |
| `blame_summary` | `repo_path`, `file` | 作者的存活行百分比、主导作者、旧行和新行的日期 |
| `bus_factor` | `repo_path`, `top=10` | 按顶级目录:主导作者和提交份额、知识孤岛(>80% 一个作者);全局总线因子(覆盖 >50% 提交的最少作者) |
| `search_commits` | `repo_path`, `query`, `author=""`, `since=""`, `limit=20` | 不区分大小写的提交消息搜索(`git log --grep`),可选作者/日期过滤 |
| `find_change` | `repo_path`, `pattern`, `file=""`, `limit=10` | 通过 pickaxe 找到添加/删除模式的提交(`git log -S`) — “这个代码什么时候出现的?”(`-S` 跟踪出现次数变化;`-G` 也会匹配移动的行) |
## 工作原理
```mermaid
flowchart LR
A[Claude / MCP client] -->|tool calls| B[server.py<br/>FastMCP wiring]
B --> C[core.py<br/>pure stdlib logic]
C -->|subprocess, 30s timeout| D[git -C repo_path<br/>log / blame / ls-files]
D --> E[(local git repository)]
D -->|"porcelain output<br/>(pretty %x1f/%x1e, numstat,<br/>blame --line-porcelain)"| C
C -->|structured dict| B
B -->|JSON result| A
```
所有解析都依赖于机器友好的 Git 输出:自定义 `--pretty` 格式,带有 ASCII 单位/记录分隔符 (`%x1f`/`%x1e`), `--numstat` 用于行变动,`blame --line-porcelain` 用于所有权。所有操作都在本地磁盘上运行仓库。
## 快速开始
```bash
pip install -e .
```
需要 Python 3.10+ 和 `git` 命令行界面。
**Claude Desktop** — 添加到 `claude_desktop_config.json`:
```json
{
"mcpServers": {
"git-historian": {
"command": "python",
"args": ["/absolute/path/to/mcp-git-historian/server.py"]
}
}
}
```
**Claude Code**:
```bash
claude mcp add git-historian -- python /absolute/path/to/mcp-git-historian/server.py
```
## 示例会话
> **用户:** 没有人敢碰 `legacy/parser.py`。谁真正了解这个模块,它的风险有多大?
>
> **Claude:** *(调用 `blame_summary(repo_path="/work/acme-api", file="legacy/parser.py")`)*
>
> 所有权非常集中:**Alice Dev 编写了 94.6% 的存活行**(Bob Ops 占剩余的 5.4%)。最旧的行可以追溯到 2019-03-11,最新的行是 2024-08-02 — 这是旧代码,但仍在被修改。
>
> *(调用 `bus_factor(repo_path="/work/acme-api")`)*
>
> `legacy/` 目录是一个 **知识孤岛**:Alice 提交了 96.2% 的相关提交。仓库的全局总线因子是 **2** — 只有两个人贡献了超过一半的提交。如果 Alice 不可用,`legacy/` 没有现实的第二负责人。
>
> **用户:** 那么解析器中的 `MAGIC_TOKEN` 常量从哪里来?
>
> **Claude:** *(调用 `find_change(repo_path="/work/acme-api", pattern="MAGIC_TOKEN", file="legacy/parser.py")`)*
>
> pickaxe 找到了一个明确引入它的提交:`a1b2c3d`(2019-04-02,Alice Dev)— *"feat: add legacy parser handshake token"*。自此之后,它再也没有被删除或重新添加,所以该常量已经存在了多年。我建议在下一次 `legacy/` 修改时与 Alice 配对,并从 `parse()` 开始编写测试。
## 开发
```bash
pip install -e ".[dev]"
python -m pytest
```
测试套件构建了一个真正的、可丢弃的 Git 仓库(两个作者,一个重命名,一个已删除的文件,固定的提交日期),并且从未导入 `mcp`,因此它使用纯粹的 pytest 运行。
## 许可证
MIT — 请参阅 [LICENSE](LICENSE)。