mcpField
R
repo-pulse

repo-pulse

本地服务
github.com/hasanyelaldi版本控制01 周前更新

关于 repo-pulse

repo-pulse 是只读 MCP 服务,可将本地 Git 历史整理为代码审查风险、代码归属和版本变更等洞察,供工程团队与 AI 助手使用。它无需网络或托管平台账户,可离线运行。

主要功能

  1. 01分支审查背景与风险排序
  2. 02热点文件和协同变更分析
  3. 03代码归属与贡献者洞察
  4. 04版本说明和引用比较
  5. 05过期分支与提交历史工具

适用场景

  1. 01PR 提交前评估分支风险并寻找审查者
  2. 02发现频繁修复的文件和隐藏依赖
  3. 03识别代码归属集中及知识缺口
  4. 04起草版本说明并查找过期分支

MCP 相关

向 MCP 客户端提供只读工具、仓库概览资源和提示词。服务通过标准输入输出运行,并分析明确允许的本地 Git 仓库。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"hasanyelaldi-repo-pulse": {
"command": "npx",
"args": [
"-y",
"repo-pulse-mcp"
],
"env": {
"REPO_PULSE_REPOS": "<REPO_PULSE_REPOS>",
"REPO_PULSE_TOOLS": "<REPO_PULSE_TOOLS>"
}
}
}
}
启动命令npx -y repo-pulse-mcp
需要配置的环境变量
REPO_PULSE_REPOSAbsolute paths of the git repositories to serve, separated by ':' (';' on Windows)
REPO_PULSE_TOOLSComma-separated toolsets (review, ownership, releases, history) or tool names to enable; all tools by default

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmrepo-pulse-mcp0.5.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

repo-pulse-mcp

CI npm MCP Registry Read-only License: MIT

将 Git 历史记录转化为 AI 助手可据此采取行动的答案:此分支有哪些风险、谁应该审查、哪些文件总是出问题,以及自上次发布以来有哪些变化。

repo-pulse 是一个面向本地 Git 仓库的只读 Model Context Protocol 服务。它通过标准输入/输出运行,只需要 Node.js 和 git,不会修改仓库,也不会访问网络。你可以向助手询问:

  • 🔍 “我准备开一个 PR。有哪些风险、我遗漏了什么,以及谁应该审查?”
  • 🐛 “哪些文件总是出问题?哪里改动最频繁?”
  • 👥 “谁最了解计费模块?我们是否依赖某一个人?”
  • 🔗 “哪些文件总是和这个文件一起变更?”
  • 🚀 “自上次发布以来有哪些变化?起草发布说明。”
  • 🧹 “哪些分支已过时,哪些已经合并?”

它适用于任何本地 Git 仓库,无论是从 GitHub、GitLab、Bitbucket 或其他地方克隆的,还是完全没有远程仓库的。拉取请求、问题或 CI 状态等平台数据不在其范围内。

Claude Code 使用 repo-pulse 审查 vitejs/vite 分支:风险文件、遗漏的相关文件和审查者

一次真实的 Claude Code 会话:仅使用 repo-pulse,不用 shell,审查 vitejs/vite 的一个分支。请参阅录制过程。

快速开始

需要 Node.js 22.12+ 和 git。无需克隆或构建:服务直接通过 npm 运行。

# Claude Code: run inside the repository you want to ask about
claude mcp add repo-pulse -- npx -y repo-pulse-mcp --repo "$PWD"

然后询问 “自上次发布以来有哪些变化?”,或使用内置提示词审查你的分支:/mcp__repo-pulse__review_branch main。如需了解 Claude Desktop 和其他 MCP 客户端的配置,请参阅安装。

功能

共 13 个工具,按其回答的问题分组。🆕 表示最新工具。

🔍 代码审查与风险
工具可回答的问题
review_context 🆕一次调用即可为分支或 PR 提供简报:按过往改动频率和修复次数排序的变更文件、通常会与其一同变更但此次被遗漏的文件,以及审查者
file_hotspots按变更频率排序的文件,并列出其中有多少次变更属于 Bug 修复。types: ["fix"] 可找出总是出问题的文件
change_coupling在相同提交中总是一起变更的文件对:导入关系无法体现的隐藏依赖
👥 归属与团队
工具可回答的问题
knowledge_map 🆕谁熟悉某个文件或目录(近期工作权重更高),以及总线因子和依赖某个人的文件
code_age 🆕每个文件距上次修改已有多久、最陈旧的目录,以及最后一位作者已离开的文件
contributor_summary某个时间段内每位作者的提交数,也可以指定某个路径
🚀 发布与分支
工具可回答的问题
release_notes_draft两个引用之间按约定式提交类型分组的提交,以及 Markdown
list_tags按时间从新到旧排列的标签、HEAD 上的最新发布版本,以及尚未发布的提交数量
compare_refs两个分支、标签或提交之间的领先/落后数量及其间的提交
stale_branchesN 天内没有提交的分支,以及每个分支是否已合并
🕒 历史与活动
工具可回答的问题
recent_activity最近 N 天的提交,可按作者和路径筛选
commit_search提交说明中提及工单 ID、功能名称或任意文本的提交
file_history单个文件的提交记录及行数统计,并跟踪重命名后的文件
📦 还包括
类型名称功能
资源repo://{name}/overview当前分支、最后一次提交、最新标签,以及提交/分支/标签数量
提示词review_branch 🆕分支审查简报:高风险文件、被遗忘的文件、审查者和检查清单
提示词release_notes 🆕自上一个标签以来润色后的发布说明,并建议下一个版本
提示词ownership_report 🆕目录的负责人、总线因子和知识风险,并提供后续步骤
提示词cleanup_branches 🆕将陈旧分支分为可安全删除和需要决定两类,并提供命令
提示词weekly_engineering_update引导模型使用工具收集数据并撰写更新

所有工具都标注了 readOnlyHint: true,声明了 outputSchema,并同时返回 structuredContent 和 JSON 文本块,以兼容较旧的客户端。完整的输入和输出请参阅 工具参考。

示例对话

你: 我准备为 feature/search 提交 PR。有什么需要注意的吗?

助手 (调用 review_context,参数为 base: "main"、head: "feature/search"):4 次提交 涉及 6 个文件。src/api.ts 风险较高:过去六个月,它在 main 上变更了 14 次,其中 6 次是修复 Bug。你可能忘了 test/api.test.ts:它在 10 次提交中有 9 次与 src/api.ts 一同变更,但不在此分支中。建议的审阅者: Alice,她掌握着这些文件近期的大部分相关知识。

你: 谁最了解 src/billing/?我们是否依赖某一个人?

助手 (调用 knowledge_map,参数为 path: "src/billing"):公交系数为 1。Carol 掌握着近期相关知识的 72%,并且是 14 个文件中 11 个文件的主要负责人;其中 9 个文件只有她一人了解。Bob 远远排在第二位,占 18%。下次修改账单功能时,让 Bob 和 Carol 搭档,有助于传播这些知识……

你: 哪些代码已经很久没人动过了?

助手 (调用 code_age,参数为 minAgeDays: 365):一半的文件在过去 18 个月里都没有变更。src/legacy/ 是最老的目录(中位数为 3.2 年),其中有 41 个文件最后由已不再在此提交代码的人修改。知识正在从这里流失……

你: 本季度哪些地方变更频繁?哪些地方总是出问题?

助手 (调用 file_hotspots,参数为 days: 90):src/core/insights.ts 经 3 个人参与,变更了 23 次,远超其他文件,其中 9 次是修复。这很适合拆分或补充测试……

你: 自上次发布以来有哪些变化?

助手 (调用 release_notes_draft,使用默认值:最新标签 → HEAD):自 v0.2.0 以来共有 14 次提交。有一项不兼容变更:配置文件已移至 repo-pulse.json。新功能包括活动记录的作者筛选和分支合并检测。还有 3 项 Bug 修复,主要针对空仓库。以下是可粘贴到 GitHub 发布页面的 Markdown 草稿:……

你: 我们能清理一些分支吗?

助手 (调用 stale_branches,参数为 days: 30):有 6 个分支超过 30 天没有提交。其中 4 个已经合并到 main,可以安全删除:……

你: (选择 weekly_engineering_update 提示词)

助手 (调用 recent_activity、contributor_summary、file_hotspots、stale_branches): 要点 — …

以上对话仅作示例:名称和数字均为虚构。

以下是在 vite 上进行的真实会话,询问尚未发布的变更和陈旧分支:

Claude Code 使用 repo-pulse 汇总 vitejs/vite 中尚未发布的变更和陈旧分支

为什么选择 repo-pulse?

目前已有适用于 GitHub、GitLab 和 git 本身的 MCP 服务,而且具备 shell 的编码 Agent 可以直接运行 git log。repo-pulse 并不打算取代它们,而是承担不同的工作:它将本地 git 历史转化为答案,并且可以安全地自动批准。

repo-pulseGitHub / GitLab MCP通用 git MCP / shell
返回内容汇总洞察平台 API 对象原始 git 输出
能否修改任何内容不能,由允许列表强制限制通常可以(取决于令牌权限范围)可以
是否需要令牌或网络不需要需要不需要
能否查看本地和未推送的分支可以不可以可以
是否支持不依赖托管平台的仓库支持不支持支持
能否查看拉取请求、问题和 CI不能可以不能

实际意义如下:

  • 步骤更少,数据准确。 像“变更集中在哪里?”“发布说明该写什么?”或“哪些分支已合并且已过时?”这样的问题,通常需要运行多条 shell 命令并手动编写计数管道,而这些操作可能会悄无声息地出错。repo-pulse 使用经过测试的代码进行计数,并返回确定性的 JSON,说明应用了哪些筛选条件。有些工具还能完成单条 git 命令做不到的事:review_context 一次调用即可综合某个分支的变更量、修复历史、变更关联和代码所有权。
  • 可验证的只读操作。 每个工具都标注了 readOnlyHint,并受 git 子命令允许列表限制(参见安全模型),因此客户端无需每次都请求批准即可运行。你不会把同样的权限交给 shell 或能够提交和推送的 git 服务。
  • 适用于没有 shell 的环境。 Claude Desktop 等聊天客户端无法运行 git。借助 repo-pulse,工程经理或技术负责人可以直接询问有关仓库的问题。
  • 适用于 git 能打开的任何仓库。 它支持离线和气隙环境,也适用于可自托管或没有远程服务的仓库,并且绝不会返回作者的电子邮件地址。

应将它与平台服务搭配使用,而不是用它替代平台服务。 如果你还需要拉取请求、问题或 CI 状态,请将它与 GitHub 或 GitLab MCP 搭配使用。如果你使用的编码 Agent 已经具备 shell,且偶尔才需要运行 git log,那么你可能不需要 repo-pulse。

基准测试

Claude Code(Sonnet 5.5)针对 vite 和 express 的同样四个问题分别作答两次:一次只使用只读 shell,另一次只使用 repo-pulse。完整的方法、答案和注意事项请参阅 bench/README.md。

问题Shell:轮次 · 时间 · 结果repo-pulse:轮次 · 时间 · 结果
最近 90 天的十大热点2 · 6.6 s · ✅2 · 6.5 s · ✅
与 config.ts 耦合的文件2 · 7.4 s · ❌ 统计偏少2 · 8.6 s · ✅
最新版与前一版本的发布说明3 · 14.0 s · ✅3 · 12.5 s · ✅
已合并且 90 天未更新的分支5 · 15.9 s · ✅2 · 4.3 s · ✅

基准测试使用 v0.3.0(10 个工具)运行。坦诚地说:对于简单的一次性问题,repo-pulse 的 token 消耗并不更低,因为优秀的模型能写出精简的 shell 管道,而 repo-pulse 的工具定义在每个会话中都会消耗 token(当前 13 个工具约需 4k)。它在多步骤问题、准确获取数据,以及完全不提供 shell 的客户端中更有优势。

要求

  • Node.js 22.12+
  • git 2.24+(用于 --end-of-options)

安装

此软件包已发布到 npm,无需克隆或构建。此服务只会提供你明确允许的代码仓库。通过 CLI 参数或环境变量传入这些仓库(macOS/Linux 使用 : 分隔,Windows 使用 ;):

npx -y repo-pulse-mcp --repo ~/code/my-app --repo ~/code/my-lib
# or, as plain arguments
npx -y repo-pulse-mcp ~/code/my-app ~/code/my-lib
# or
REPO_PULSE_REPOS=~/code/my-app:~/code/my-lib npx -y repo-pulse-mcp

如果未配置任何代码仓库,此服务将拒绝启动。它也已在 MCP Registry 中登记为 io.github.hasanyelaldi/repo-pulse-mcp。

选择工具

每个启用工具的定义都会在每个会话中消耗 token,全部 13 个工具约需 4k。如果你只需要其中一部分,可使用 --tools(或 REPO_PULSE_TOOLS)仅启用所需工具;可以使用 功能 中的分组、单个工具名称,或两者组合:

工具集工具定义
reviewreview_context、file_hotspots、change_coupling约 1.3k token
ownershipknowledge_map、code_age、contributor_summary约 950 token
releasesrelease_notes_draft、list_tags、compare_refs、stale_branches约 950 token
historyrecent_activity、commit_search、file_history约 800 token
all全部(默认)约 4k token
npx -y repo-pulse-mcp --repo ~/code/my-app --tools review,list_tags
# or
REPO_PULSE_TOOLS=review,ownership npx -y repo-pulse-mcp ~/code/my-app

名称无效时,服务会在启动时停止,并列出所有有效名称。提示词依赖对应的工具:review_branch 需要 review_context,release_notes 需要 release_notes_draft,ownership_report 需要 knowledge_map,cleanup_branches 需要 stale_branches,而 weekly_engineering_update 需要它使用的四个工具。

Claude Code

在你要提问的代码仓库中运行:

claude mcp add repo-pulse -- npx -y repo-pulse-mcp --repo "$PWD"
Claude Desktop

编辑 claude_desktop_config.json(macOS:~/Library/Application Support/Claude/,Windows:%APPDATA%\Claude\),然后重启 Claude Desktop。请使用绝对路径:

{
  "mcpServers": {
    "repo-pulse": {
      "command": "npx",
      "args": ["-y", "repo-pulse-mcp", "--repo", "/absolute/path/to/your/repository"]
    }
  }
}
从源码安装
git clone https://github.com/hasanyelaldi/repo-pulse-mcp.git
cd repo-pulse-mcp
npm ci
npm run build
node build/index.js --repo /absolute/path/to/your/repository
Podman / Docker
podman build -t repo-pulse-mcp .
podman run -i --rm \
  -v "$PWD:/repos/project:ro" \
  -e REPO_PULSE_REPOS=/repos/project \
  repo-pulse-mcp

代码仓库以只读方式挂载。在启用了 SELinux 的主机(Fedora、RHEL)上,请在卷选项中添加 ,Z。如果你更喜欢 Docker,可以将 podman 替换为 docker;此镜像未使用任何 Docker 专属功能。对于 MCP 客户端,将 podman 设为 command,其余部分设为 args。

工具参考

每个工具都接受可选的 repo 参数:仓库名称(目录名称,显示在概览资源中)或其绝对路径。默认使用第一个已配置的仓库。

结果为精简 JSON,提交列表包含 shortHash(git 的缩写哈希,长度足以在仓库中明确区分),而不是完整哈希;任何接受引用的位置都可以使用它。

review_context
输入类型默认值说明
basestring–必填。更改将合并到的目标引用
headstringHEAD包含更改的引用
daysinteger180回溯读取 base 历史的天数
halfLifeDaysinteger90审阅者的近期权重,与 knowledge_map 中相同
excludestring[]–最多 20 个用于跳过文件的 glob,语法与 file_hotspots 相同
minSharedinteger2缺失配套文件所需的最少共同提交数
minDegreeinteger50缺失配套文件所需的最低耦合度(%)
maxFilesPerCommitinteger30跳过涉及更多文件的历史提交(见下文)
limitinteger201–100,分别应用于每个列表

输出:{ repo, base, head, baseCommit, headCommit, windowDays, commits, truncated, changeAuthors, filesChanged, additions, deletions, historyScanned, scanTruncated, files: [{ path, additions, deletions, changes, fixes, lastChanged, owner, ownerShare }], missingCompanions: [{ path, coupledWith, sharedCommits, degree }], reviewers: [{ author, share, filesKnown, lastCommit }] }

一次调用即可将 file_hotspots、change_coupling 和 knowledge_map 结合起来,针对 base..head 中更改的文件,并以 base 的历史为依据:

  • files 是更改过的文件,按风险从高到低排列:先按在 base 上的修复次数排序,再按更改次数排序。新文件没有历史记录,因此 changes 为 0,owner 为 null。
  • missingCompanions 是未更改但通常会与已更改文件同时更改的文件(degree 与 change_coupling 相同),例如可能被遗漏的测试或配置文件。
  • reviewers 按对已更改文件的近期加权了解程度排序,并排除更改的作者。share 是相对于所有人的了解程度计算的,其中包括更改作者。

已更改的文件来自 base..head 中的非合并提交,因此,即使某个文件被更改后又改回,仍会计入。涉及文件数超过 maxFilesPerCommit 的提交仍会计入 changes 和 fixes,但不会计入所有权或耦合度。重命名不会被追踪。

file_hotspots
输入类型默认值说明
daysinteger901–3650
pathstring–限定在某个子树范围内
excludestring[]–最多跳过 20 个 glob,例如 ["*.lock", "dist/"]。不含 / = 任意深度,末尾带 / = 目录
typesstring[]–仅统计这些 conventional-commit 类型,例如 ["fix"]
limitinteger101–100

输出:{ repo, windowDays, types, commitsScanned, scanTruncated, commitsMatched, fixesFromKeywords, filesChanged, hotspots: [{ path, changes, fixes, additions, deletions, authors, lastChanged }] }

合并提交会被排除,重命名也不会被追踪,因此重命名后的文件会从头开始。要追踪单个文件的重命名历史,请使用 file_history。

fixes 统计 changes 中属于错误修复的提交数量:经常变更且多数变更都是修复的文件,比只是在不断增大的文件更适合作为重构候选项。使用 types: ["fix"] 时,只统计修复提交,因此排名会显示那些总是出问题的文件。 提交类型取自 conventional-commit 标头(fix(api): …)。如果提交没有此类标头,但主题中提到 "fix"、"bug" 或 "hotfix",则该提交会计为修复;fixesFromKeywords 会显示通过这种方式找到的修复数量,因此非零值意味着统计结果是估算值。标头始终优先,因此 docs: fix typo 不算修复。

change_coupling
输入类型默认值说明
daysinteger901–3650
filestring–仅包含与此文件相关的文件对
pathstring–限定在某个子树范围内
excludestring[]–最多跳过 20 个 glob,语法与 file_hotspots 相同
minSharedinteger2文件对要列出所需的最少共同提交数
maxFilesPerCommitinteger30涉及文件数更多的提交会被跳过
limitinteger101–100

输出:{ repo, windowDays, commitsScanned, scanTruncated, commitsSkipped, pairCount, pairs: [{ fileA, fileB, sharedCommits, revisionsA, revisionsB, degree }] }

degree 是共同提交数占分别变更过每个文件的提交数平均值的百分比:100 表示两个文件总是一起变更。互不导入的文件之间若 degree 较高,通常意味着存在隐藏依赖(重复逻辑、必须保持同步的配置或测试夹具)。大型提交(例如批量重命名或格式调整)会被跳过,因为这类提交会让涉及的每个文件都产生关联。合并提交会被排除,重命名也不会被追踪。

knowledge_map
Input类型默认值说明
pathstring–文件或子树;省略则表示整个仓库
daysinteger3651–3650
halfLifeDaysinteger90每经过 N 天,提交的权重减半
excludestring[]–最多 20 个要跳过的 glob,语法与 file_hotspots 相同
maxFilesPerCommitinteger30跳过涉及文件数超过此值的提交
limitinteger101–100,分别应用于 authors 和 files

输出:{ repo, path, windowDays, halfLifeDays, commitsScanned, scanTruncated, commitsSkipped, filesAnalyzed, busFactor, concentratedFiles, authors: [{ author, share, filesOwned, commits, lastCommit }], files: [{ path, owner, ownerShare, authors, commits, lastChanged }] }

每个修改文件的提交都会让其作者掌握该文件的相关知识,且每经过 halfLifeDays,权重就减半。因此,上个月重构某个模块的人,排名会高于三 年前编写该模块的人。此处不考虑代码行数,因此生成文件或重新格式化的差异不会占据过多权重。share 和 ownerShare 均为百分比。busFactor 是合计掌握该区域超过一半知识所需的最少作者人数;concentratedFiles 统计由一位作者掌握至少 80% 知识的文件数。files 按修改频率从高到低列出文件及其主要负责人,可快速用于为某个路径推荐审查者。排除合并提交,且不追踪重命名。

code_age
Input类型默认值说明
pathstring–文件或子树;省略则表示整个仓库
minAgeDaysinteger0仅列出至少有这么久未变更的文件;摘要涵盖所有文件
inactiveDaysinteger180作者在这么长时间内没有提交,则视为不活跃
excludestring[]–最多 20 个要跳过的 glob,语法与 file_hotspots 相同
limitinteger201–100,分别应用于 directories 和 files

输出:{ repo, path, inactiveDays, commitsScanned, scanTruncated, filesOnHead, medianAgeDays, ageBuckets: [{ label, files }], inactiveAuthorFiles, directories: [{ path, files, medianAgeDays, newestAgeDays }], files: [{ path, lastChanged, ageDays, lastAuthor, lastAuthorActive, commits }] }

对于 HEAD 上的每个文件,都会获取最后一个修改该文件的非合并提交的日期和作者。 ageBuckets 将文件划分为 30 天以内、30–90 天、90 天至 1 年、1–2 年和超过 2 年几个区间。directories 按 path 下的第一级目录对文件分组(直接位于该目录中的文件归入 .),并按中位文件年龄从大到小排列,以显示哪些代码部分已无人维护。 若作者在整个仓库中有 inactiveDays 天没有提交(合并提交也计入),则 lastAuthorActive 为 false;inactiveAuthorFiles 统计此类文件数,可粗略衡量已经流失的知识。使用同一邮箱、多个名称提交的人只计为一人。

HEAD 上的文件根据第一父提交历史中的新增和删除记录确定,因此合并提交本身新增或删除的文件也能正确处理。最多读取 20,000 个提交;超过此数量时,scanTruncated 为 true,且不会包含在截断点之前最后变更的文件。

contributor_summary
输入类型默认值说明
daysinteger301–3650
includeMergesbooleanfalse同时统计合并
pathstring–限定在某个子树范围
limitinteger201–100

输出:{ repo, windowDays, totalCommits, scanTruncated, contributorCount, contributors: [{ author, commits, firstCommit, lastCommit }] }

release_notes_draft
输入类型默认值说明
fromstringto 之前的最新标签不包含。标签、分支或提交哈希
tostringHEAD包含
formatstringmarkdownmarkdown、sections 或 both

输出:{ repo, from, to, commitCount, truncated, markdown?, sections?: [{ key, title, entries: [{ shortHash, scope, description, author }] }] }

markdown 是可直接粘贴的草稿;sections 是相同内容的结构化数据。只返回 请求的格式,因为两种格式同时返回会使结果大小翻倍。

分区顺序:重大变更、功能、错误修复、性能、重构、文档、测试、构建系统、 持续集成、杂项、回退、其他变更。如果提交标题中含有 !(feat!: …),或正文中有 BREAKING CHANGE: 页脚,则该提交属于重大变更;此类提交也会出现在其类型对应的分区中。跳过合并提交。

list_tags
输入类型默认值说明
limitinteger201–200

输出:{ repo, totalTags, latestOnHead, commitsSinceLatest, tags: [{ name, date, shortHash, subject }] }

标签按标签日期排序,最新的排在前面。latestOnHead 是可从 HEAD 到达的最新标签; 当维护版本在其他分支上打标签时,它可能与最新标签不同。 commitsSinceLatest 统计该标签之后的提交,即尚未发布的工作。

compare_refs
输入类型默认值说明
basestring–必填。用于比较的引用(例如 main)
headstringHEAD要比较的引用
limitinteger201–100,分别应用于每个提交列表

输出:{ repo, base, head, baseCommit, headCommit, ahead, behind, status, truncated, aheadCommits: [{ shortHash, author, date, subject }], behindCommits: [...] }

ahead 统计可从 head 到达、但无法从 base 到达的提交;behind 则相反。status 为 identical、ahead、behind 或 diverged。两个引用都经过与 release_notes_draft 相同的验证,且计数包含合并提交。

stale_branches
输入类型默认值说明
daysinteger30最新提交的最小时间间隔
includeRemotebooleanfalse同时列出远程跟踪分支
mergedOnlybooleanfalse仅列出已合并到 HEAD 的分支
limitinteger501–200

输出:{ repo, thresholdDays, totalBranches, staleCount, branches: [{ name, lastCommitDate, lastAuthor, daysSinceLastCommit, mergedIntoHead }] }

recent_activity
输入类型默认值说明
daysinteger71–3650
authorstring–作者姓名的子字符串,按字面匹配
pathstring–相对于仓库的文件或目录
limitinteger501–200

输出:{ repo, windowDays, totalCommits, truncated, commits: [{ shortHash, author, date, subject }] }

commit_search
输入类型默认值说明
querystring–必填。按字面匹配,不区分大小写;匹配主题和正文
daysinteger–1–3650。省略则搜索全部历史
authorstring–作者姓名的子字符串,按字面匹配
pathstring–相对于仓库的文件或目录
limitinteger201–100

输出:{ repo, query, windowDays, totalMatches, truncated, commits: [{ shortHash, author, date, subject }] }

file_history
输入类型默认值说明
pathstring–必填。相对于仓库的文件路径,以 HEAD 时的路径为准
limitinteger201–100

输出:{ repo, path, commitCount, truncated, renamed, commits: [{ shortHash, author, date, subject, path, additions, deletions }] }

会追踪文件重命名,因此较早的提交会报告文件当时的路径;当列出的提交涉及多个路径时,renamed 为 true。合并提交会被跳过;对于二进制文件,additions 和 deletions 为 null。

资源:repo://{name}/overview

每个已配置的仓库各有一个资源(通过 resources/list 列出,支持名称补全):

{
  "name": "my-app",
  "path": "/home/me/code/my-app",
  "currentBranch": "main",
  "detachedHead": false,
  "lastCommit": { "hash": "…", "shortHash": "1a2b3c4", "author": "…", "date": "…", "subject": "…" },
  "latestTag": "v0.2.0",
  "commitCount": 412,
  "branchCount": 7,
  "tagCount": 9
}
提示词:review_branch

参数(字符串):base(必填,例如 main)、head(默认值为 HEAD)、repo。在 Claude Code 中,它是一个斜杠命令:

/mcp__repo-pulse__review_branch main feature/search

它会指示模型调用 review_context(以及在启用该工具时调用 compare_refs),并撰写审查简报:摘要、风险文件、可能遗漏的文件、建议的审查者,以及待核查事项清单。它还会告知模型,repo-pulse 返回的是历史记录而非差异,因此简报不能声称已阅读代码。只要启用了 review_context,此提示词便可用。

提示词:release_notes

参数(字符串,均为可选):from(默认值:to 之前的最新标签)、to(默认值为 HEAD)、version、repo。在 Claude Code 中:

/mcp__repo-pulse__release_notes

它会指示模型调用 release_notes_draft,并将分组后的提交改写为面向用户的发行说明:先列出重大变更,再列出功能和修复,省略内部杂项。未提供 version 时,它还会调用 list_tags(如果已启用),并建议下一个 semver 版本。只要启用了 release_notes_draft,此提示词便可用。

提示词:ownership_report

参数(字符串,均为可选):path(默认值:整个仓库)、repo。在 Claude Code 中:

/mcp__repo-pulse__ownership_report src/billing

它会指示模型调用 knowledge_map,并撰写一份关于负责人、巴士因子以及依赖单一人员的文件的报告,最后给出具体建议。启用 code_age 和 file_hotspots 后,它还会调用这两个工具,以标记最后由已离职人员修改的文件,以及由单人负责的热点文件。只要启用了 knowledge_map,此提示词便可用。

提示词:cleanup_branches

参数(均为可选字符串):days(默认值为 30)、repo。在 Claude Code 中:

/mcp__repo-pulse__cleanup_branches

它会指示模型调用 stale_branches,并将结果分为已合并且可以安全删除的分支(每个分支对应一条 git branch -d 命令),以及需要决定是否处理的未合并分支(附上最后一位作者)。模型会被告知不要自行运行这些命令。启用 stale_branches 后即可使用。

提示词:weekly_engineering_update

参数(均为可选字符串):repo、days(默认值为 7)。生成一条用户消息,告知模型要调用哪些工具,以及如何组织一份简短的利益相关者更新。

安全模型

此服务的设计目标是防止困惑或受操纵的模型造成损害:

  • 严格只读。 git 通过单个函数运行,该函数只允许使用 log、rev-list、rev-parse、describe 和 for-each-ref。其他任何命令都会在进程启动前被拒绝。
  • 绝不使用 Shell。 git 通过 child_process.execFile 和参数数组启动,因此参数不会由 Shell 解释。
  • 仓库允许列表。 只提供通过 --repo / REPO_PULSE_REPOS 传入的仓库。启动时会通过 realpath 规范化路径(解析符号链接),并进行精确比对;无论未知仓库是否存在于磁盘上,都会返回相同的错误。如果未配置任何仓库,服务不会启动(默认拒绝)。
  • 输入验证。 所有输入均通过带有边界限制的 zod 架构验证。引用必须符合分支、标签、哈希或 ~N/^N 后缀的格式:不能以 - 开头,不能包含 .. 范围、@{} 或 : 语法;它们会在 --end-of-options 之后传入,然后通过 rev-parse --verify 解析。路径必须是相对路径且不能包含 .. 片段;它们会在 -- 之后与 --literal-pathspecs 一起传入(不进行 glob 匹配)。作者筛选使用 --fixed-strings,因此不会被视为正则表达式。
  • 限制工作量。 每个工具的结果数量都有上限,扫描最多处理 5,000 条提交,git 输出上限为 16 MB,且每次 git 调用都会在 15 秒后超时。输出会注明是否发生截断。
  • 强化 git 环境。 会移除继承的 GIT_* 变量(例如 GIT_DIR),禁用提示,关闭可选锁,强制关闭 core.fsmonitor(否则仓库自身的配置可能会让 git 运行程序),并在计算差异时禁用外部 diff/textconv 驱动程序。
  • 减少个人数据。 只返回作者姓名,不返回电子邮件地址。

不在范围内: 此服务信任 PATH 中的 git 二进制文件以及你加入允许列表的仓库。它是本地开发工具,没有网络传输功能,也不进行身份验证。

架构

src/
├── index.ts              # stdio entry point: config → registry → server → transport
├── server.ts             # MCP layer: tools, resource and prompt with zod schemas
├── config.ts             # --repo / REPO_PULSE_REPOS parsing, repo allowlist (RepoRegistry)
├── errors.ts             # InputError (safe to show) and GitError
├── core/
│   ├── insights.ts       # one method per feature: builds git args, aggregates results
│   ├── glob.ts           # exclude globs, matched in-process on paths git returned
│   └── release-notes.ts  # pure conventional-commit parsing, grouping and Markdown
└── git/
    ├── runner.ts         # the only place that spawns processes (allowlist, limits, env)
    ├── parsers.ts        # pure parsers for git output (no I/O)
    └── validation.ts     # ref / path / author validation

设计说明:

  • 将进程 I/O 与解析隔离。 runner.ts 是唯一会启动进程的模块;parsers.ts 和 release-notes.ts 是纯函数,通过字符串样例进行测试。
  • 输出格式明确无歧义。 git 输出使用 ASCII 单元分隔符(0x1f)和记录分隔符(0x1e),而不使用制表符或换行符,因为提交主题和文件名中可能包含这些字符。
  • 组合方式便于测试。 createServer() 将其依赖项(允许列表、git 运行器、时钟)作为参数,因此测试可以将它连接到具有固定“当前时间”的内存传输。
  • 将错误转换为工具结果。 验证和 git 错误会以带有可操作消息的 isError: true 工具结果呈现,让模型可以自我纠正,而不是导致会话失败。
  • stdout 至关重要。 它承载 JSON-RPC,因此日志会写入 stderr,且 ESLint 会禁止使用 console.log。

基于官方 MCP TypeScript SDK v2(@modelcontextprotocol/server)构建。

开发

npm ci
npm run dev -- --repo .     # run from source with tsx
npm test                    # unit + integration tests (vitest)
npm run lint                # ESLint
npm run format              # Prettier
npm run typecheck
npm run build               # compile to build/
npm run check               # everything CI runs
npm run inspect             # build first; opens MCP Inspector against this repository

发布。 更新 package.json、server.json(两个 version 字段)中的版本,以及 src/server.ts 中的 SERVER_VERSION(如果它们不一致,单元测试会失败),然后合并并推送标签: git tag -a vX.Y.Z -m vX.Y.Z && git push origin vX.Y.Z。发布工作流会运行完整检查,使用来源证明发布到 npm,并在 MCP Registry 中注册新版本。两者都使用 GitHub OIDC(npm Trusted Publishing 和 Registry 的 github-oidc 登录),因此不会存储发布令牌。如果只有 Registry 步骤失败,请手动运行工作流(gh workflow run release.yml):它会跳过 npm,并重试 Registry。

测试。 单元测试覆盖解析器、验证、配置解析和发布说明分组。集成测试会创建带有脚本化历史记录(虚构作者、固定日期)的临时 git 仓库,并测试每项功能,包括通过内存传输的真实 MCP 客户端进行直接测试和端到端测试,以及安全检查。

MCP Inspector。 npm run build && npm run inspect 会打开连接到此仓库的 Inspector 网页界面。脚本化检查也可以使用 CLI 模式:

npx @modelcontextprotocol/inspector --cli node build/index.js -e REPO_PULSE_REPOS="$PWD" \
  --method tools/call --tool-name release_notes_draft

限制和想法

  • 活动、热点和贡献者工具会检查从 HEAD 可达的提交;未合并分支上的工作不会计入。
  • file_hotspots、change_coupling、knowledge_map、review_context 和 code_age 不会跟踪重命名:重命名后的文件从重命名时起会被视为新文件。
  • 每个会话的工具定义约占用 4k 个令牌,因此,对于简单的一次性问题,使用 shell 可能更省(参见基准测试)。选择工具可将其限制为你会使用的工具组。
  • 后续可能的工作:为团队使用添加 HTTP 传输。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。