mcpField
G
graphkeeper

graphkeeper

本地服务
github.com/RudrenduPaul版本控制05 周前更新

关于 graphkeeper

GraphKeeper 是本地命令行工具,可从 Git 历史提取文件共同变更关系,供编码 Agent 查询。它将关系存入可查询图数据,并可选用 graphify 补充调用图信息。

主要功能

  1. 01统计同一提交中共同修改的文件
  2. 02限制大型提交以减少噪声
  3. 03可选合并 graphify 调用图
  4. 04提供 JSON 查询结果
  5. 05Node.js 与 Python 实现共享数据格式

适用场景

  1. 01查找与某文件常一起修改的文件
  2. 02让编码 Agent 查询代码变更耦合
  3. 03分析函数的调用者与被调用者

MCP 相关

提供基于 stdio 的 MCP 服务,允许 MCP 客户端构建图并查询共同变更或调用关系。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"rudrendupaul-graphkeeper": {
"command": "uvx",
"args": [
"graphkeeper-cli"
]
}
}
}
启动命令uvx graphkeeper-cli

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

安装包
pypigraphkeeper-cli0.1.5

工具

还没有获取到工具列表

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

详细介绍

GraphKeeper

npm version PyPI version npm downloads License: Apache 2.0

安装 • 快速入门 • CLI 参考 • 对比 • 常见问题

一个仅在本地运行的 CLI,可从你的 git log 中挖掘哪些文件确实会同时发生变化,然后向 AI 编码 Agent 提供可查询的答案,而不是让它在整个历史记录中执行 grep。

安装 graphkeeper-cli、克隆 GraphKeeper,并运行 graphkeeper build,随后针对其自身仓库运行 graphkeeper query co-change

npx graphkeeper-cli build
npx graphkeeper-cli query co-change src/git.ts
Files that historically change alongside "src/git.ts":

     1  src/store.ts
     1  src/types.ts
     1  test/git.test.ts
     1  test/store.test.ts
     1  test/test-helpers.ts

(这是 GraphKeeper 在项目发展早期针对自身仓库运行后得到的真实输出。随着代码库积累更多提交,共同变更计数也会增加。)

无需服务端、账号或嵌入 API。所有输出都来自你已检出的仓库中的 git log。

安装

GraphKeeper 提供两个相互独立、同等重要的包。选择适合你工具链的包,也可以两个都安装。两者都会从相同的 git log 中挖掘共同变更信号,并共用同一种磁盘上的 .graphkeeper/graph.json 架构,因此使用任一包构建的存储都可以由另一个包读取。

# npm -- JavaScript/TypeScript CLI + library
npm install -g graphkeeper-cli
# or run it once with no install
npx graphkeeper-cli build

# PyPI -- Python CLI + library (genuine port, not a wrapper around the Node binary)
pip install graphkeeper-cli

npm 包需要 Node.js 18 或更高版本;Python 包需要 Python 3.9 或更高版本。两者都要求 git 位于你的 PATH 中。Python 包的 CLI 入口同样是 graphkeeper(例如 graphkeeper build)。请参阅 python/README.md 了解 Python 专属教程,并参阅 CHANGELOG.md 了解各发行包的版本历史。

快速入门

对任意 git 仓库运行,包括本仓库:

git clone https://github.com/RudrenduPaul/GraphKeeper.git
cd GraphKeeper
graphkeeper build
GraphKeeper build complete: /path/to/GraphKeeper

Co-change graph: 4 commit(s) analyzed, 80 file pair(s) found
graphify enrichment: skipped -- graphify was not found on PATH. Install it with
`uv tool install graphifyy` (or `pipx install graphifyy`) for symbol/call-graph
enrichment; GraphKeeper works fine without it, in co-change-only mode.

Wrote /path/to/GraphKeeper/.graphkeeper/graph.json

现在查询:

graphkeeper query co-change src/git.ts
Files that historically change alongside "src/git.ts":

     1  src/store.ts
     1  src/types.ts
     1  test/git.test.ts
     1  test/store.test.ts
     1  test/test-helpers.ts

如果已安装 graphify(uv tool install graphifyy),graphkeeper build 会自动调用本地无需 API 密钥的 graphify extract --code-only,并将其符号/调用图合并到同一个存储中,从而支持调用图查询:

graphkeeper query calls mineCoChange
mineCoChange() (src/git.ts)

Calls (2):
  --> assertIsGitRepo()
  --> runGit()

Called by (1):
  <-- build()

(这也是实际输出,来自安装 graphify 后针对本仓库运行 graphkeeper build 的结果。)

安装 graphify 后运行 graphkeeper build,将其符号/调用图合并到同一存储中,再运行 graphkeeper query calls,通过增强后的存储回答调用图问题

如果未安装 graphify,同一命令会准确说明为何无法提供答案,而不会崩溃或返回空结果:

Call-graph query for "mineCoChange" is not available.

graphify was not found on PATH. Install it with `uv tool install graphifyy`
(or `pipx install graphifyy`) for symbol/call-graph enrichment; GraphKeeper
works fine without it, in co-change-only mode.

每条命令也都支持用于脚本和 Agent 的 --json:

graphkeeper query co-change src/git.ts --json
{
  "file": "src/git.ts",
  "results": [
    { "file": "src/store.ts", "count": 1 },
    { "file": "src/types.ts", "count": 1 },
    { "file": "test/git.test.ts", "count": 1 },
    { "file": "test/store.test.ts", "count": 1 },
    { "file": "test/test-helpers.ts", "count": 1 }
  ]
}

运行带有 --json 的 graphkeeper query co-change,获取脚本可读取的答案;随后在未安装 graphify 时运行 graphkeeper query calls,查看友好的不可用说明,而不是遇到崩溃

功能

  • 挖掘真实的提交历史,而非静态快照。 graphkeeper build 会在仓库的完整历史中运行 git log --no-merges --name-only,并统计 每个提交中共同变更的每对文件。它不会仅凭目录结构或导入语句来 猜测耦合关系;结论基于代码库随时间的实际编辑情况。
  • --max-files-per-commit 可保护信号质量。 一次涉及 400 个文件的 vendoring 提交或大规模格式重排,否则会污染该提交中的所有文件对。 默认上限为 100 个文件,超过此阈值的提交会被跳过,避免真实的耦合关系 淹没在噪声中。
  • 可选的调用图增强,绝非必需。 如果 PATH 中有 graphify, graphkeeper build 会调用其本地 graphify extract --code-only --no-cluster,并将生成的符号边/调用边合并到 同一存储中,从而启用 graphkeeper query calls。没有 graphify 时, GraphKeeper 仍可在仅使用共同变更数据的模式下运行,并会明确说明这一点, 而不是直接失败。
  • 每条命令都有 --json 模式。 graphkeeper query co-change <file> --json 及对应命令会返回机器可读的输出,因此 Agent 的调用代码 可以解析真正的数据结构,而不必从文本中提取信息。
  • 两种从零实现,共用同一架构。 npm 包(src/,TypeScript)和 PyPI 包(python/src/graphkeeper/,Python)是彼此独立的移植版本, 并非一方封装另一方。两者都会读写同一个 .graphkeeper/graph.json, 因此可用一个 CLI 构建存储,再用另一个 CLI 查询。
  • 所有子进程调用都使用 argv 数组,绝不使用 shell 字符串。 Git 和 graphify 都通过参数列表调用 spawnSync/subprocess.run,因此 被分析仓库中精心构造的提交消息或文件名不会被解释为 shell 语法。

CLI 参考

Usage: graphkeeper [options] [command]

Options:
  -V, --version           output the version number
  -h, --help              display help for command

Commands:
  build [options] [path]  Mine git history for co-change and (if available)
                          merge in graphify's symbol/call graph
  query                   Query the GraphKeeper store built by
                          `graphkeeper build`
  help [command]          display help for command
graphkeeper build [path]

遍历 path(默认值:当前目录),在完整历史中运行 git log --no-merges --name-only,并统计每对文件在同一提交中共同变更的次数。将结果写入 .graphkeeper/graph.json。

选项说明
--json输出机器可读的 JSON,而非人类可读的文本
--max-files-per-commit <n>跳过变更文件数超过此值的提交(默认值:100),避免一次大规模格式重排或 vendoring 提交淹没真实的共同变更信号
--no-graphify即使已安装 graphify,也跳过 graphify 增强

如果在 PATH 中检测到 graphify, build 还会在 .graphkeeper/ 内的一个目录中运行 graphify extract <path> --code-only --no-cluster (graphify 自带的无头、本地、无需 API 密钥的 AST 提取路径),并将其节点/边合并到同一存储中。构建输出始终会明确说明是否包含了此增强;如果没有,也会说明跳过原因。

graphkeeper query co-change <file>

列出历史上与 <file> 同时变更过的文件,并按同时变更的提交数排序。

选项说明
--json输出机器可读的 JSON,而非人类可读的文本
--limit <n>限制结果数量
--graph <path>指定 graph.json 的路径(默认值:<cwd>/.graphkeeper/graph.json)

找到结果时退出码为 0;该文件尚无共同变更数据时为 1;用法或文件系统错误时为 2。

graphkeeper query calls <symbol>

显示 <symbol> 的调用方和被调用方,使用最近一次 build 生成的 graphify calls 边。只有当该次构建包含 graphify 增强时,此查询才有意义;如果没有,则会清楚说明原因,而不会崩溃或静默返回空结果。

选项描述
--json输出机器可读的 JSON,而非人类可读的文本
--graph <path>指定 graph.json 的路径(默认:<cwd>/.graphkeeper/graph.json)

找到符号时退出代码为 0,未找到(或增强不可用)时为 1,用法错误或文件系统错误时为 2。

MCP 服务

GraphKeeper 提供 Model Context Protocol 服务,让 AI 编码 Agent(Claude、Cursor 或任何兼容 MCP 的客户端)无需人工手动调用 CLI,即可挖掘共同变更历史并直接查询图。

安装附加组件:

pip install "graphkeeper-cli[mcp]"

将其添加到 MCP 客户端的配置中(对于 Claude Desktop,请编辑 claude_desktop_config.json):

{
  "mcpServers": {
    "graphkeeper": {
      "command": "uvx",
      "args": ["--from", "graphkeeper-cli", "graphkeeper-mcp"]
    }
  }
}

该服务公开一个工具 run,它会通过 npx graphkeeper-cli 调用已发布的 graphkeeper-cli npm 包,并附上给定的子命令和参数以及 --json,然后返回解析后的 JSON 结果:

run(["build", "."])
run(["query", "co-change", "src/git.ts"])

传输方式为 stdio,因此无需托管:MCP 客户端会将该服务作为本地子进程启动。源文件:python/src/graphkeeper/mcp_server.py。

库 API 参考

以下列出了两个包公开的、可实际导入的接口。命令行只是对相同函数的轻量封装。

TypeScript / JavaScript(npm 上的 graphkeeper-cli)
import { build, queryCoChange } from "graphkeeper-cli";

const result = build(".");
console.log(`${result.store.commitsAnalyzed} commit(s) analyzed`);

const coChange = queryCoChange(result.store, "src/git.ts");
for (const row of coChange.results) {
  console.log(row.count, row.file);
}
导出项签名
buildbuild(targetPath: string, options?: BuildOptions): BuildResult
queryCoChangequeryCoChange(store: GraphKeeperStore, file: string, options?: { limit?: number }): CoChangeQueryResult
queryCallsqueryCalls(store: GraphKeeperStore, symbol: string): CallsQueryResult
findGraphifyNodefindGraphifyNode(nodes: GraphifyNode[], symbol: string): GraphifyNode | null
normalizeFileArgnormalizeFileArg(store: GraphKeeperStore, file: string): string
detectGraphifydetectGraphify(): { installed: boolean; version: string | null }
runGraphifyEnrichmentrunGraphifyEnrichment(repoRoot: string): GraphifyEnrichment
mineCoChangemineCoChange(repoPath: string, options?: { maxFilesPerCommit?: number }): CoChangeMiningResult
GitErrorGit 相关操作失败时抛出的错误子类
resolveRepoRootresolveRepoRoot(targetPath: string): string
readStorereadStore(repoRoot: string, overridePath?: string): GraphKeeperStore
writeStorewriteStore(repoRoot: string, store: GraphKeeperStore): string
PathSafetyError解析后的路径超出仓库根目录时抛出的错误子类
graphFilePathgraphFilePath(repoRoot: string): string

类型(GraphKeeperStore、CoChangeEdge、GraphifyNode、GraphifyEdge、GraphifyRawGraph、GraphifyEnrichment、BuildOptions、BuildResult、CoChangeQueryResult、CallsQueryResult)以 .d.ts 声明文件的形式随编译产物一同发布;目前尚无单独生成的文档网站。

Python(PyPI 上的 graphkeeper-cli)
from graphkeeper import build, query_co_change

result = build(".")
print(f"{result.store.commits_analyzed} commit(s) analyzed")

co_change = query_co_change(result.store, "src/git.py")
for row in co_change.results:
    print(row.count, row.file)

graphkeeper.__all__ 导出:build、query_co_change、query_calls、 find_graphify_node、normalize_file_arg、detect_graphify、 run_graphify_enrichment、mine_co_change、unquote_git_path、GitError、 resolve_repo_root、read_store、write_store、graph_file_path、 PathSafetyError,以及 GraphKeeperStore、CoChangeEdge、 GraphifyNode、GraphifyEdge、GraphifyEnrichment、BuildOptions、 BuildResult、CoChangeQueryResult、CoChangeResultRow 和 CallsQueryResult 数据类。与上文 TypeScript 导出表中的名称相同, 采用 snake_case。目前还没有单独生成的文档网站;python/src/graphkeeper/__init__.py 顶部的 docstring 涵盖了与本节相同的内容。

对比

GraphKeepergraphifyGitNexusGreptileAugment Code
功能从 git log 中挖掘文件级别的协同变更通过 tree-sitter 提取符号/导入/调用图,并提供 AI 助手技能CLI + MCP 工具(原生、本地),可选的免安装浏览器/WASM 模式;进行结构分析和调用流程分析托管式 AI 代码审查,使用图索引代码库托管式 AI 编码平台,具备实时代码依赖图(Context Engine),并提供提交历史和文档索引
仅限本地?是,始终如此是,代码解析仅限本地(如果配置了后端,文档/媒体索引会调用后端)CLI/MCP 路径是;浏览器模式在客户端运行,但需要托管的 Web 应用默认不是;仅 Enterprise 方案提供可自托管/隔离网络部署否;托管在云端,未公开说明提供自托管选项
免费/开源?是,Apache-2.0是,Apache-2.0否,PolyForm Noncommercial 1.0.0免费 Starter 方案(1 个席位,每月 50 个额度),非开源未公开说明是否免费;采用面向企业销售的定价
协同变更挖掘?是,这是该工具的全部功能否否否否
GraphKeeper 与之的关系--graphify 已安装时,GraphKeeper 会使用 graphify 本地 extract 的输出丰富自身存储;不会重新实现其功能交付模式不同(CLI + MCP + 可选浏览器应用,而本项目是纯 CLI);不进行协同变更挖掘面向团队/PR 审查的托管产品,不是本地单 Agent 工具企业级编码助手平台,不是独立的本地 CLI

(凡是竞争产品未公开具体数字的地方,均使用“未公开说明”,而不作猜测。数据已根据各项目自己的 README、定价页面或公开网站核实,截至 2026 年 8 月。)

GraphKeeper 是什么?它为何存在?

GraphKeeper 是一个本地 CLI 和库,以 graphkeeper-cli 发布到 npm 和 PyPI。它会从 git log 中挖掘文件级共同变更数据:哪些文件历来会与指定文件在同一个提交中一起编辑。它将数据写入单个 JSON 文件 .graphkeeper/graph.json,并在不进行网络调用的情况下针对该文件回答查询。

它的存在是因为,独自处理不熟悉的代码库时,AI 编码 Agent 无法快速回答“我改动这个文件时,通常还会改动什么?”,除非每次被问到时都自行运行 git log --name-only 扫描,并手动统计结果。GraphKeeper 会预先计算这个答案,并提供查询方式,其中包括脚本或 Agent 可直接解析的 --json 格式。

GraphKeeper 不会重新实现符号或调用图提取功能。 graphify(在 GitHub 上有 100K+ 星标,采用 Apache-2.0 许可证,通过 pip install graphifyy 安装)已支持 36 种 tree-sitter 语法,并作为斜杠命令技能提供给 Claude Code、Cursor、Codex、Gemini CLI、GitHub Copilot 及其他 15+ 款助手(总计 20+ 款)。当 graphify 位于 PATH 中时,graphkeeper build 会调用本地的 graphify extract --code-only --no-cluster,并将结果合并到同一存储中,从而启用 graphkeeper query calls。即使没有 graphify,GraphKeeper 仍可在仅支持共同变更的模式下工作,并会直接说明这一点,而不会报错。

工作原理

  1. graphkeeper build 会通过安全的 argv 数组子进程调用(绝不使用 shell 字符串),在整个仓库历史中运行 git log --no-merges --name-only。
  2. 对于每个提交,它都会统计每一对共同变更的文件。如果某个提交涉及的文件数超过 --max-files-per-commit(默认值为 100),就会跳过该提交,以免单个引入供应商代码或大规模重新格式化的提交淹没真实信号。
  3. 如果在 PATH 中检测到 graphify,GraphKeeper 还会将 graphify 自带的本地、无需 LLM、无需 API 密钥的提取模式 graphify extract <path> --code-only --no-cluster 运行到 .graphkeeper/ 内的一个目录中,然后将其 nodes/edges 合并到同一存储中。
  4. 合并后的结果会一次性原子写入 .graphkeeper/graph.json。
  5. graphkeeper query 会读取该文件,并据此回答共同变更或调用图相关问题。绝不进行网络调用。

安全性

  • 每次调用 git 和 graphify 时,都会使用直接传递给操作系统的 argv 数组(TypeScript 中使用 spawnSync,Python 中使用带列表参数的 subprocess.run),绝不使用 shell 字符串,因此提交消息、文件名或仓库路径不会被解释为 shell 语法。
  • 每次写入前,都会检查 .graphkeeper/ 输出路径是否位于解析后的仓库根目录内(包括通过 fs.realpathSync 检查符号链接),因此恶意构造的仓库无法将 GraphKeeper 的写入重定向到 .graphkeeper/ 之外。
  • 无遥测、无网络调用、无机密信息。GraphKeeper 唯一读取的文件是 git log 输出,以及可选的 graphify 自带 graph.json;唯一写入的文件是 .graphkeeper/graph.json。

漏洞报告流程请参阅 SECURITY.md。

常见问题

GraphKeeper 是通用的代码库知识图谱索引器吗?

它本身不是。graphkeeper build 会从 git log 中挖掘文件级共同变更数据,并将这些边写入 .graphkeeper/graph.json。只有在安装了 graphify 并于同一次构建中将其合并后,该文件才会同时包含符号图和调用图。如果 PATH 中没有 graphify,存储中就只有共同变更数据,graphkeeper query calls 也会直接说明这一点,而不是返回空结果。

与 grep 或 git log 相比,GraphKeeper 实际能为 Agent 提供什么? 预先计算、可查询的“这里哪些文件会一起变更”的答案, 这样 Agent 就不必每次遇到问题时都运行自己的 git log --name-only 扫描, 再手动统计结果。每条命令都支持 --json, 因此答案可供脚本使用,而不必由人来阅读并重新输入。

如何安装?它能在 Windows 上运行吗?

npm install -g graphkeeper-cli(Node.js 18+)或 pip install graphkeeper-cli(Python 3.9+);两者都需要 git 位于 PATH 中。两个 软件包都不包含特定于操作系统的分支或原生绑定,且 PyPI 上的条目被归类为 Operating System :: OS Independent,因此只要有 git 和受支持的 Node 或 Python 运行时,就能在 Windows、macOS 和 Linux 上以相同方式运行。

这与它链接用于丰富信息的工具 graphify 有何不同?

它们回答的是不同的问题。graphify 通过 tree-sitter 直接从源代码中提取符号、导入项和 调用图,支持 36 种语言;GraphKeeper 则从提交历史中挖掘哪些文件过去曾一起 编辑,这是 graphify 没有理由计算的信号。若 graphify 存在于 PATH 中, GraphKeeper 会调用 graphify 自带的本地 extract 命令并合并结果,而不是从头 重新实现 tree-sitter 解析。两者都不能取代对方;请参阅上方的比较表,了解 GitNexus、Greptile 和 Augment Code 与两者的区别。

什么情况会导致 GraphKeeper 出错或返回空结果?

有两种真实情况,都有文档说明,且都不会导致崩溃:浅层 git 克隆(GitHub Actions 默认的 fetch-depth: 1)没有可供挖掘的历史记录,因此 build 会报告 0 commit(s) analyzed 并写入空的共同变更图;需要完整历史记录(fetch-depth: 0)。 另外,只有在最近一次 build 运行时 PATH 中存在 graphify,query calls 才会返回结果;如果不存在,命令会明确说明这一点 (graphify was not found on PATH...),而不会假装该符号不存在。

对我不完全信任的仓库运行它安全吗?

每次 git 和 graphify 调用都会通过 argv 数组直接传给操作系统 (spawnSync/Python 的 subprocess.run 使用列表,绝不使用 shell 字符串),因此文件名或提交消息不会被解释为 shell 语法。每次写入 .graphkeeper/ 前,都会检查路径是否位于解析后的仓库根目录内,其中也包括符号链接。 该工具不会进行任何网络调用,因此你指定的仓库中的任何内容都不会离开你的计算机。

npm CLI 只是 Python CLI 的封装,还是反过来?

都不是。它们是两个独立、从头实现的版本(TypeScript 版位于 src/, Python 版位于 python/src/graphkeeper/),只是恰好采用相同的 .graphkeeper/graph.json 架构、子命令、标志和退出代码。一个版本构建的存储 可以由另一个版本读取。Python 端口自己的测试套件(从 TypeScript vitest 套件移植而来)包含 78 个测试,针对真实的子进程 CLI 调用运行,而不是模拟另一种 语言的输出。截至目前,在全新安装环境中两个套件都通过:TypeScript 端为 78/78 (npm test),Python 端为 78/78(pytest)。

它采用什么许可证?可以用于商业用途吗?

npm 和 PyPI 软件包均采用 Apache License 2.0,没有双重许可,也没有单独的商业版。 该许可证允许商业使用、修改和再分发,但需注明出处并遵守标准的 Apache 专利授权条款。 完整文本请参阅 LICENSE。

贡献

欢迎提交问题和 PR。要从源代码构建 TypeScript 软件包:

git clone https://github.com/RudrenduPaul/GraphKeeper.git
cd GraphKeeper
npm install
npm run build
npm test
npm run lint
npm run typecheck

Python 软件包请参阅 python/README.md。涵盖两个代码库的完整 贡献指南见 CONTRIBUTING.md。

许可证

Apache License 2.0

评论

支持 Markdown

第一次接触 MCP?

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

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