graphpilot-oss/graphpilot

GitHub: graphpilot-oss/graphpilot

为 AI 编码代理提供本地持久化代码图索引,通过 MCP 协议让代理高效查询符号、调用关系和重构影响范围,大幅降低 token 消耗并减少幻觉。

Stars: 10 | Forks: 2

GraphPilot

GraphPilot

为编码代理提供的结构化记忆。
一个完全在您的本地机器上运行的、重构安全、分支感知、基于证据溯源的代码图。

License: Apache 2.0 Node ≥20 v0.1.0 alpha 239 tests GraphPilot MCP server

快速开始 · 工具 · 工作原理 · 编辑器设置 · 局限性 · 基准测试

GraphPilot demo — install, index, and query a real TypeScript repo in under 30 seconds

## 它是什么 GraphPilot 是一个本地 CLI + MCP 服务器,它将您的 TypeScript/JavaScript 仓库索引为一个结构化图(符号、调用者、被调用者、影响范围),并将其暴露给编码代理 —— Claude Code、Cursor、Cline、Windsurf、Continue —— 从而让它们停止在每次对话中重复 `grep` 相同的文件。 它解决的问题:代理会大量消耗 token,产生虚构的函数名幻觉,并遗漏结构关系(“谁调用了这个?”、“如果我重命名它会破坏什么?”),因为每次会话都是零基础上启动的。GraphPilot 就是介于其间的持久化结构记忆。 **Token 成本下降。幻觉减少。重构变得更安全。** 让一个真正的编码代理 (claude-sonnet-4-5) 回答关于 fastify 的 **40 个结构化问题** —— 一个包含约 300 个文件的 Node.js 框架 —— 并且只给它文件读取权限。然后交给它 GraphPilot 的四个工具,再问它同样的 40 个问题。使用 GraphPilot 的代理会少消耗 **61% 的 Token**,成本从 **$8.88 变为 $3.68 —— 每次会话节省 $5.20** —— 并且答对的问题更多而不是更少(答对 37 题对 33 题)。相同的模型、相同的问题、相同的仓库;唯一的改变就是结构化索引是否存在。[复现它 →](benchmark/README.md) 另一项单独的正确性基准测试以精确度印证了这种节省:在 10 个标准化结构查询中,GraphPilot 得分为 **F1 0.89,而 grep 为 0.42**,同时读取的字节数减少了 **99.9%**(721 B 对比 528 KB),并且这种字节成本的节省优势在规模化时依然保持 —— 索引 **microsoft/TypeScript**(10 秒内处理 601 个文件、1.7 万个符号、7 万条调用边)能提供 **亚毫秒级的查询** 以及 **99.99% 的字节读取减少量**。[完整方法论 →](bench/README.md) ## 单一二进制文件,两种模式 GraphPilot 以单个 npm 包(`@graphpilot-oss/graphpilot`)的形式提供,具有两种运行模式 —— 大多数用户会同时运行两者。 | 模式 | 命令 | 功能说明 | | -------------- | -------------------------- | ---------------------------------------------------------------------------- | | **CLI** | `graphpilot index ` | 遍历您的仓库,构建结构化图,并将其写入 `~/.graphpilot/` | | | `graphpilot watch ` | 保持图处于最新状态(每次文件保存约 10 毫秒) | | | `graphpilot status ` | 健康探针 —— 显示图最后一次刷新的时间,以及文件/符号/边的数量 | | **MCP server** | `graphpilot mcp` | 通过 stdio 进行 MCP 通信 —— 您的编码代理会调用它来查询代码图 | **工作流程:****CLI** 负责一次性构建索引(并且 `watch` 会保持其处于预热状态)。**MCP 服务器**则是您的编码代理与之通信的对象 —— 您永远不需要自己调用它,只需将代理的 MCP 配置指向 `graphpilot mcp` 一次,代理在每次会话时都会自动启动它。

GraphPilot data flow: you run index/watch to build ~/.graphpilot/<repo>/graph.json; the read-only graphpilot mcp server reads it and serves your coding agent over stdio JSON-RPC

如果您只想通过 CLI 访问您的代码图(不使用代理),请运行 `graphpilot index`,然后直接运行 `graphpilot stats` 或检查 `graph.json`。如果您只想要代理集成,您仍然需要运行一次 `graphpilot index` —— 因为 MCP 服务器是只读访问磁盘上的代码图的。 ## 它的独特之处 其他代码图工具将您的仓库视为一个静态的 blob:索引一次,永久查询,没有分支感知能力,也没有关于答案来源的证明。GraphPilot 围绕着它们所不具备的三个特性而构建: - 🔍 **证据锚点。** 每个工具响应在所有符号和调用点上都带有 `file:line @ sha`。代理可以逐字引用该锚点,您可以立即验证它 —— 当您跳转到相应代码行时,幻觉会瞬间暴露无遗。 - 🌿 **差异化影响范围。** 将 `since: ` 传递给 `gp_impact`,结果将被过滤为仅限于您的分支实际触及的文件。只需一次调用即可完成 PR 范围的重构分析,替代了原来的 `git diff | xargs grep`。 - 🪵 **默认感知 Worktree。** 两个使用 `git worktree add` 添加的分支自然会生成两个独立的索引 —— 无需手动配置。在子目录中运行 `graphpilot index ./src/feature` 时,它会透明地重新定位到 worktree 的根目录。可以使用 `--no-worktree` 退出此模式。 此外:**本地优先**(无遥测、无远程调用,由 `src/` 自身上的 ESLint 策略强制执行),**确定性**(相同的仓库 → 相同的图),通过 watch 模式实现**亚秒级增量**更新。 ## 快速开始 **前置条件** - Node.js ≥ 20(使用 `node --version` 检查) - 支持 MCP 的编码代理(Claude Code、Cursor、Cline、Windsurf 或 Continue) - 一个 TypeScript 或 JavaScript 仓库用于索引 端到端耗时:约 3 分钟。 **1. 安装 CLI** ``` npm install -g @graphpilot-oss/graphpilot # 或:pnpm add -g @graphpilot-oss/graphpilot # 或一次性运行,无需安装:npx @graphpilot-oss/graphpilot ``` 验证它已成功加入您的 `PATH`: ``` graphpilot --version # → 0.1.0 ``` 如果您看到 `command not found: graphpilot`,说明您的全局 npm bin 目录不在 `PATH` 中。请运行 `npm config get prefix` 并将 `/bin` 添加到您 shell 的 `PATH` 中,或者使用上面提到的 `npx` 形式。 **2. 为您的仓库构建结构化索引** 每个项目运行一次。它会遍历您的源代码树,使用 tree-sitter 解析每个 TS/JS 文件,提取符号和调用边,并将图写入 `~/.graphpilot//graph.json`。 ``` graphpilot index ~/code/my-app ``` 预期会看到类似 `indexed 412 files · 3,981 symbols · 7,204 edges · 1.8s` 的单行摘要。 **3. 将其接入您的编码代理** GraphPilot 通过 stdio 进行 MCP 通信。将此服务器条目添加到您代理的 MCP 配置中 —— 每个支持的客户端都使用相同的两行格式: ``` { "mcpServers": { "graphpilot": { "command": "graphpilot", "args": ["mcp"] } } } ``` 此文件所在的位置取决于客户端(`~/.cursor/mcp.json`、`~/.claude.json`、Cline 的设置面板等)。针对每个代理带有确切文件路径的预配置文件位于 [`examples/`](examples/) 中 —— 只需为您对应的客户端复制一份即可。 重启代理。它现在拥有了四个新工具:`gp_recall`、`gp_callers`、`gp_impact`、`gp_index` —— 请参阅下方的[四个工具](#the-four-tools)了解每个工具的作用以及代理应该在何时调用它们。 **4. 试试看** 向您的代理提出一个结构化问题,而不是让它去 grep: 您应该会看到带有 `file:line @ sha` 锚点的响应,您可以直接点击跳转。如果代理没有去调用该工具,请明确提示:“使用 `gp_` MCP 工具”。如果它完全看不到这些工具,说明 MCP 配置未被加载 —— 请重启代理并重新检查 [`examples/`](examples/) 中对应客户端的配置路径。 **5. 在编辑时保持索引最新(可选但推荐)** ``` graphpilot watch ~/code/my-app ``` 每次文件保存时进行低于 10 毫秒的增量更新。请让它在终端标签页中保持运行。 **6. 将每个编辑器的路由规则放入您的仓库(可选)** ``` graphpilot init ``` 自动检测您安装了哪些编辑器(Cursor、Claude Code、Cline、Windsurf、Continue),并将匹配的规则文件(`.cursorrules`、`CLAUDE.md` 等)写入当前目录。这些规则会教导代理在进行 grep 之前优先使用 `gp_*` 工具。 ``` graphpilot init --all # write rules for every supported editor graphpilot init --client cursor # one editor only graphpilot init --dry-run # preview without writing ``` 包含屏幕截图的完整 5 分钟指南:[`docs/quickstart.md`](docs/quickstart.md)。 ## 四个工具 GraphPilot 暴露了四个 MCP 工具。每一个都用于回答代理原本会通过 grep 和阅读文件来求解的结构化问题。 ### `gp_recall` —— 按名称查找符号 在代理询问“X 在哪里定义?”或需要在推理之前定位某个函数时使用。 - **输入:** `{ query, limit?, substring?, path? }` - **返回:** 名称匹配的符号(默认不区分大小写精确匹配;设置 `substring: true` 进行部分匹配),每个都带有 `file:line @ sha`。 - **替代:** `grep -rn "function X"` 加上阅读每个搜索结果以找到真正的定义。 ``` Agent: gp_recall({ query: "parseToken" }) → parseToken (function) — src/auth.ts:42 @ a1b2c3d export function parseToken(raw: string): Token | null ``` ### `gp_callers` —— 列出调用者(或被调用者) 在代理需要知道“谁调用了 X?”或“X 调用了什么?”时使用 —— 这是重构的两个基本问题。 - **输入:** `{ symbol, direction?: 'callers' | 'callees', limit?, includeUnresolved?, path? }` - **返回:** 该符号作为目标(调用者)或源(被调用者)的每一条调用边,附带锚点。 - **替代:** `grep -rn "X("` 加上手动过滤注释、字符串和被重命名的变量遮蔽。 ``` Agent: gp_callers({ symbol: "authenticate", direction: "callers" }) → login → authenticate — src/routes/login.ts:18 @ a1b2c3d → refreshSession → authenticate — src/session.ts:64 @ a1b2c3d ``` ### `gp_impact` —— 一次调用获取影响范围 在代理询问“如果我重命名 X 会破坏什么?”或“什么依赖于此?”时使用 —— 这通常是代理需要解决的代价最高昂的问题。 - **输入:** `{ symbol, depth? (1–5, default 3), since?, path? }` - **返回:** 直接调用者、按 BFS 深度分组的传递调用者、可能受影响的测试、公共 API 标记、统计摘要。 - **核心特性:** 传入 `since: 'main'`,结果将仅限于您的分支实际触及的文件 —— 无需复杂的 `git diff` 操作即可进行 PR 范围的重构审查。 ``` Agent: gp_impact({ symbol: "extractSymbols", depth: 2, since: "main" }) → Direct callers (2): indexDirectory, applyUpdate → Depth-2 callers (1): cmdIndex → Tests affected (3): tests/indexer.test.ts, tests/symbols.test.ts, tests/cli.test.ts → Public API: no ``` ### `gp_index` —— 从代理内部刷新 在代理(或用户)进行了一批结构化编辑后,希望代码图能够反映这些更改而无需退回到命令行时使用。 - **输入:** `{ path? }` - **返回:** 重新索引仓库并使对应路径的查询缓存失效。 - **配合使用:** 在显式重新索引的间隙,结合 `graphpilot watch` 获取低于 10 毫秒的增量更新。 ## 工作原理

How GraphPilot works, in two phases. Build time (CLI index/watch): your repo flows through indexer.ts, parser.ts, and symbols.ts + edges.ts, which storage.ts writes to graph.json at ~/.graphpilot/<repo-id>/ (mode 0600). Serve time (read-only MCP server): query.ts reads graph.json, mcp.ts exposes 4 tools over stdio JSON-RPC with evidence anchors, served to Claude Code, Cursor, Cline, Windsurf, and Continue.

数据流是单向的:源码 → 树 → 符号 + 边 → JSON → 查询 → 代理。GraphPilot 绝不会修改您的代码。 包含文件参考的完整管道说明:[`docs/architecture.md`](docs/architecture.md)。 ## 何时使用哪个工具 | 如果代理正准备… | 选择… | 原因 | | --------------------------------------- | ------------------------------ | ----------------------------------------------------- | | `grep` 查找函数名 | `gp_recall` | 一次调用搞定,不会出现注释或字符串导致的误报 | | 阅读近 20 个文件寻找“谁调用了 X” | `gp_callers` | 预计算的倒排索引,亚毫秒级响应 | | 计划重命名或修改签名 | `gp_impact` | 一次调用包含 直接 + 传递调用 + 测试 + 公共 API | | 审查 PR 的结构性影响范围 | `gp_impact({ since: 'main' })` | 差异化 —— 仅显示您的分支触及的调用者 | | 编辑多个文件后重新 `grep` | `gp_index` | 增量更新:让下一次调用能看到您的编辑 | 对于字符串、错误消息、配置值,或 TS/JS 以外语言的任何内容:**请继续使用 grep。** GraphPilot 索引的是代码结构,而非文本。 ## 编辑器设置 GraphPilot 通过 stdio 进行 MCP 通信,因此可与支持 MCP 的客户端配合使用。可直接粘贴的配置文件位于 `examples/` 中: | 客户端 | 文件夹 | | ----------------------------- | ------------------------------------------------ | | **Claude Code** (Anthropic) | [`examples/claude-code/`](examples/claude-code/) | | **Cursor** | [`examples/cursor/`](examples/cursor/) | | **Cline** (VS Code 扩展) | [`examples/cline/`](examples/cline/) | | **Windsurf** (Codeium) | [`examples/windsurf/`](examples/windsurf/) | | **Continue.dev** | [`examples/continue/`](examples/continue/) | | 任何其他 MCP 客户端 | 请参阅 [`docs/mcp-setup.md`](docs/mcp-setup.md) | 每个文件夹包含:一份 `README.md` 指南,一个包含确切 JSON 供粘贴的示例配置文件,以及(在客户端支持的情况下)一份路由模板,以便代理在遇到结构化问题时自动调用 GraphPilot。 ## 隐私与安全 GraphPilot **通过承诺和构建关卡保证本地优先**。 - **绝对没有遥测,没有远程调用。** 可验证:`src/` 中没有任何 `http`、`fetch`、`axios` 或分析相关的导入 —— 这是由 ESLint 规则加上一个元测试强制执行的,该测试证明了规则会在每一个被禁止的导入上触发。 - **没有 `child_process`,没有 `exec`,没有 `spawn`。** Git 事实是通过纯 JS 辅助工具直接从 `.git/` 读取的。 - **源代码永远不会离开您的机器。** 只有结构化元数据(名称、位置、签名、调用关系)会存放在 `~/.graphpilot/` 中。 - **签名会被脱敏处理**:在写入磁盘之前,会对常见的机密特征(OpenAI/Anthropic `sk-`、GitHub `ghp_`/`ghs_`、AWS `AKIA`、JWT、PEM 头部、Slack/Stripe token)进行掩码处理。 - **严格的文件权限:** 目录 `0o700`,文件 `0o600`。 - **加载时进行 schema 校验:** 篡改或损坏的 `graph.json` 将回退到“无索引”状态,而不是误导代理。 - **在每个 MCP 工具上实施手工编写的输入验证器** —— 未知字段会被拒绝,每个字段都会进行类型检查,数字会进行范围检查,字符串会进行长度限制。 威胁模型和各项防御测试的参考信息位于 [`docs/architecture.md`](docs/architecture.md) 中。报告安全问题请参阅 [`SECURITY.md`](SECURITY.md)。 ## 局限性 GraphPilot v0.1 为了保持工具的小巧且锋利,做出了审慎的权衡: - **仅支持 TS/JS。** Python、Rust、Go、Java 不在 v1 版本的范围内。Python 将视需求情况在 v0.2 / v0.3 版本中加入。 - **基于名称的解析器**(没有导入路径跟踪,没有基于类型的方法调度)。预期解析率:约 25–35% 的边能解析为仓库内的符号;其余为标准库 / 第三方库。这已经足够了,因为代理实际提出的问题(*“谁在我的仓库中调用了 X?”*)正是这种简单的解析器能够准确回答的。 - **无语义搜索。** `gp_recall` 仅限名称匹配。“查找与此片段相似的代码”将推迟到有超过 30 位用户提出需求时再做。 - **尚不支持 `.graphpilotignore`**(默认会跳过 `node_modules`、`dist`、`build`、`.git`、`coverage`、`.next`、`.nuxt`、`.cache`、`out`、`*.d.ts`)。 - **每次查询仅限单个仓库。** 工作区抽象已列入 v1.x 的路线图。 包含缓解措施的完整列表:[`docs/limitations.md`](docs/limitations.md)。 ## 常见问题 **它会把我的代码发送到任何地方吗?** 不会。`src/` 中没有网络代码,没有遥测,没有更新检查。ESLint 规则在构建关卡中阻止添加任何此类代码。 **它会让我的编辑器变慢吗?** 在您的代理调用工具之前,MCP 服务器处于空闲状态。首次惰性加载后,工具调用的耗时在亚毫秒级。Watch 模式每次文件保存会增加约 3–10 毫秒的开销。 **当我切换分支时,代码图会发生什么变化?** 如果您使用 `git worktree`,您会自动在每个 worktree 中获得独立的图。如果是在单一工作副本中通过 `git checkout` 切换,则图反映的是最后一次 `gp_index`(或 watch 模式的更新)的状态。在切换分支后运行 `gp_index` 即可进行刷新。 **我每次会话都需要重新索引吗?** 不需要。代码图持久化在 `~/.graphpilot//graph.json` 中。在进行大范围更改后需要重新索引;在其他情况下,watch 模式会通过增量方式保持其最新状态。 **为什么首选 TypeScript/JavaScript?** 因为那是维护者感到痛点的地方,而且 tree-sitter-typescript 能够使用单一的语法覆盖 TS、TSX、JSX 和 JS。Python 是最有可能的下一个加入的语言;请通过 GitHub 讨论区投票。 **这与 LSP 相比如何?** LSP 仅限在一个编辑器和一个缓冲区中运行,并且它们会在每次查询时重新计算。GraphPilot 与编辑器无关,可跨会话持久化,并回答 LSP 未统一暴露的结构化问题(调用关系、影响范围)。 ## 文档 - [`docs/quickstart.md`](docs/quickstart.md) —— 5 分钟指南 - [`docs/mcp-setup.md`](docs/mcp-setup.md) —— 各客户端配置参考 - [`docs/architecture.md`](docs/architecture.md) —— 包含文件参考的管道说明 - [`docs/limitations.md`](docs/limitations.md) —— v1 版本的注意事项(必读) - [`bench/README.md`](bench/README.md) —— 基准测试方法论与结果 - [`examples/`](examples/) —— 每个支持的客户端可直接粘贴的配置 ## 贡献 GraphPilot 小巧、有主见,并且欢迎贡献。请从 [`CONTRIBUTING.md`](CONTRIBUTING.md) 开始 —— 特别是 _“我们在 v1 版本中不会做的事情”_ 这一节,在提出功能建议之前请务必阅读。 发现安全问题?请遵循 [`SECURITY.md`](SECURITY.md) 中的指引,而不是开启一个公开的 issue。 ## 许可证 [Apache-2.0](LICENSE)。版权所有 2026 Akshay Sharma —— [codewithakki@gmail.com](mailto:codewithakki@gmail.com)
标签:AI编程助手, MCP, MITM代理, SOC Prime, 云安全监控, 代码分析, 代码图谱, 凭证管理, 开发工具, 自动化攻击, 静态分析