内容
<img src="./docs/krabby.webp" width="360" />
Krabby 提供代码搜索、文档检索和关系分析,适用于 MCP。指向仓库;它克隆并索引,生成文档和 RAG,并使用 LLM 和嵌入构建 [graphify](https://github.com/Graphify-Labs/graphify) 知识图谱,然后在后台保持索引更新。
```
┌───────────────────────────────────────┐
LLM/Agent ──MCP───► │ krabby (Go) │
(流式 HTTP) │ ├─ MCP 工具(管理和查询) │──► git clone/pull
│ ├─ REST API + 提供者中立钩子 │──► graphify 更新
CI/webhook ──HTTP─► │ ├─ 注册表(bw/BadgerDB) │──► graphify 合并图谱
│ ├─ 原生图查询引擎(Go) │
│ └─ 调度器(cron 调度) │
└───────────────────────────────────────┘
```
- **查询速度快**:图查询工具(`query_graph`、`get_node`、`get_neighbors`、`get_community`、`god_nodes`、`graph_stats`、`shortest_path`)由原生 Go 引擎直接读取 `graph.json` 回答,支持热加载,无需为每个图谱启动子进程。
- **构建成本低**:代码提取基于 AST,无需 LLM 密钥。graphify CLI 仅在构建/合并图谱时调用。
- **文档和 RAG(可选)**:配置 LLM 后,krabby 生成每个文件的 Markdown 文档(提示可在设置中配置)以及存储库概览,可在 UI 中浏览。
- **网络源**:命名自定义网络 URL 集合和 Confluence 空间被转换为 Markdown 并索引在存储库文档旁边。搜索所有存储库、所有网络源或一个集合,如 `web:wine`。
- **语义代码搜索(可选)**:源代码在 graphify 符号边界(带有行窗口回退)处分段,嵌入到 Codestral Embed 等专用代码模型中,并返回为排名的路径/行代码段。
## 需求
- Go 1.26+(构建),git,ssh(用于私有存储库)
- graphify CLI 用于构建图谱:`uv tool install graphifyy`(或 `pip install graphifyy`)。MCP 额外功能**不再需要** —— krabby 的原生 Go 引擎回答图查询。
## 快速开始
```sh
make build
cp krabby.example.yaml krabby.yaml # 编辑存储库、密钥
./bin/krabby
```
添加存储库并查询:
```sh
curl -X POST localhost:8080/api/v1/repos -d '{"url":"git@git.example.com:team/service.git"}'
curl localhost:8080/api/v1/repos
```
代理的 MCP 端点(opencode、Claude Desktop 等):`http://localhost:8080/mcp`(流式 HTTP;设置 `mcp.api_key` 需要 `X-Api-Key` / `Authorization: Bearer`)。如果没有配置文件头,它会公开 28 工具的标准目录。发送 `X-Krabby-Tool-Profile: full` 在每个 MCP 请求中,以额外公开凭证、文档/RAG 配置和端点探测。
示例 opencode 配置:
```json
{
"mcp": {
"krabby": {
"type": "remote",
"url": "http://localhost:8080/mcp"
}
}
}
```
对于完整配置文件,请在同一服务器条目中添加持久化头部:
```json
"headers": { "X-Krabby-Tool-Profile": "full" }
```
## MCP 工具
| 工具 | 用途 |
| --- | --- |
| `list_repos` / `add_repo` / `remove_repo` | 管理跟踪的存储库 |
| `refresh_repo` | 在后台拉取 + 重建图谱 |
| `repo_status` | 构建状态、最后提交、最后错误 |
| `set_credential` / `list_credentials` / `remove_credential` | 按主机/组织 git 凭证 |
| `search_code` | 符号、路径、字面值、定义、用法和实现位置的首选 |
| `read_file` / `list_files` | 分页浏览已知源文件或目录列表 |
| `query_graph` | 架构、依赖、调用/数据流和跨文件关系问题 |
| `get_node` / `get_neighbors` / `get_community` | 节点级检查 |
| `god_nodes` / `graph_stats` / `shortest_path` | 图级分析 |
| `search_docs` / `list_docs` / `get_doc` | 搜索生成的 Markdown 或同步的 Markdown |
| `list_sources` | 发现命名的自定义网络、Confluence 和 Jira 集合(`web:<name>`)|
| `get_docs_config` / `set_docs_config` | 读取或实时更新文档和代码 RAG 设置 |
| `test_llm` / `test_embedder` / `test_code_embedder` | 验证模型端点,无需保存 |
始终传递完整的存储库 ID(`host/group/.../name`)以便知道它。仅在有意跨存储库搜索或合并图分析时省略它。`list_*` 工具用于发现未知标识符或显式库存请求;响应是分页的,代理不应默认穷尽每个页面。源代码和文档读取也是有界的,并为大文件公开继续元数据。
`read_file` 和分页 `list_files` 响应包含一个 `snapshot`令牌;将其传递回继续调用,以便在版本更新时,每个页面保持在同一个不可变存储库版本上。令牌是一个软提示,而不是锁定:它仅在版本仍被保留时被尊重(默认为 5 分钟)。一旦版本被回收,重放其令牌会透明地回退到当前活动快照并返回新令牌 —— 它永远不会出错或卡住客户端,因此重放旧令牌的消费者会简单地升级到最新版本。
标准配置文件省略凭证和文档/RAG 管理行。配置 `X-Krabby-Tool-Profile: full`,当 MCP 客户端必须管理它们时。
## REST API
| 端点 | 用途 |
| --- | --- |
| `GET /healthz` | 存活 |
| `GET /api/v1/repos` | 列出存储库 |
| `POST /api/v1/repos` `{"url","branch"}` | 跟踪存储库 |
| `GET /api/v1/repos/{full-path...}` | 存储库状态 |
| `DELETE /api/v1/repos/{full-path...}` | 取消跟踪 + 删除克隆 |
| `POST /api/v1/repos/{full-path...}/-/refresh` | “此存储库已更改”触发器 |
| `GET /api/v1/repos/{full-path...}/-/graph` | 存储库的原始 `graph.json` |
| `GET /api/v1/repos/{full-path...}/-/report` | `GRAPH_REPORT.md` 审计报告 |
| `GET /api/v1/repos/{full-path...}/-/html` | 交互式图可视化 |
| `GET /api/v1/graph` | 合并的跨存储库 `graph.json` |
| `GET/POST /api/v1/sources` | 列出/创建命名的自定义网络或 Confluence 集合 |
| `GET/PUT/DELETE /api/v1/sources/{name}` | 读取/更新/删除集合 |
| `POST /api/v1/sources/{name}/refresh` | 同步和重新索引集合 |
| `POST/DELETE /api/v1/sources/{name}/pages` | 添加/删除自定义网络 URL |
| `GET /api/v1/docs/search?q=&mode=&scope=&repo=&top=` | 文档搜索;`mode=hybrid|semantic|lexical`,`scope=all|repos|sources`,`repo=web:<name>` |
| `GET /api/v1/code/search?q=&repo=&top=` | 语义源代码片段搜索 |
| `GET/PUT /api/v1/docs/config` | 读取/更新文档和代码 RAG 设置 |
| `GET /api/v1/credentials` | 列出凭证模式(从不返回机密)|
| `PUT /api/v1/credentials` `{"pattern","secret","kind","username"}` | 存储凭证 |
| `DELETE /api/v1/credentials?pattern=...` | 删除凭证 |
| `POST /webhook/git` | 提供者中立的 git 推送 webhook;通用 bearer/shared-token 身份验证和常见服务器格式 |
## 数据布局和外部工具
所有内容都位于 `data_dir`(默认为 `~/.krabby`)下,并且是纯文件 —— 其他工具(文档生成器、linters、索引器)可以自由读取:
```
~/.krabby/
├── repos/.snapshots/<host>/<group>/.../ # 不变的版本化 git 快照
│ └── <version>/graphify-out/
│ ├── graph.json # 原始图(GraphRAG-ready)
│ ├── GRAPH_REPORT.md # 人类可读的审计报告
│ ├── graph.html # 交互式可视化
│ └── manifest.json # 增量更新清单
├── merged/graph.json # 跨存储库合并图
├── keys/ # 物质化的凭证 SSH 密钥(0600)
├── docs-vectors/ # 嵌入式文档向量索引
├── sources/<name>/*.md # 同步的自定义网络/Confluence 页面
├── code-vectors/ # 嵌入式源代码向量索引
└── state/ # 注册表 + 凭证数据库
```
`GET /api/v1/repos` 返回每个存储库的本地 `path` 以供发现,上述工件端点通过 HTTP 提供相同的文件,供没有文件系统访问权限的工具使用。
### 不变的存储库快照
刷新会获取远程状态,而不会更改活动工作树。Krabby 克隆并在私有版本目录中重建图谱,然后通过原子替换注册表路径发布源代码和图谱。失败或取消的构建会保留上一个版本。最新的上一个快照会被保留,较旧的版本会有一个短暂的宽限期(默认为 5 分钟),供读取器解析早期路径;读取重建的快照令牌会透明地回退到当前版本,而不是失败。
## Git 凭证
凭证存储 **模式** —— 主机或主机/路径前缀 —— 最具体的匹配项在克隆/拉取时生效:
```sh
# SSH 密钥适用于整个 GitLab 实例(从 PEM 推断类型):
curl -X PUT localhost:8080/api/v1/credentials \
-d '{"pattern":"gitlab.example.com","secret":"-----BEGIN OPENSSH PRIVATE KEY-----\n..."}'
# 用于一个组织的令牌(https 克隆):
curl -X PUT localhost:8080/api/v1/credentials \
-d '{"pattern":"git.example.com/myorg","secret":"token..."}'
```
或者,让 LLM 通过 MCP 使用 `set_credential` 进行操作。SSH 密钥在 `data_dir/keys/` 下以 0600 权限具体化;令牌通过凭证助手提供给 git(从不放在 argv 上)。机密永远不会被任何 API 返回。全局 Git 凭证通过 UI、REST API 或 MCP 工具按主机或主机/路径模式持久化。最具体的模式优先。
## 刷新管道
```
webhook / poll / refresh_repo
→ git fetch (有新提交?) → git pull
→ graphify update <repo> # 增量,仅 AST,无 LLM
→ graphify merge-graphs → merged/graph.json
→ 代码 RAG 索引(启用时)
→ 生成的文档 + 文档 RAG 索引(启用时)
```
存储库也会根据设置中配置的 cron 时间表进行轮询。每个时间表都会针对一个命名空间(`*` = all,`default` = 未标记)并携带一个或多个 cron 规格(例如 `0 */6 * * *` 或 `@every 15m`),因此不同的命名空间可以以不同的频率轮询,并且可以共存多个时间表。未配置时间表时,轮询会恢复为固定间隔(默认为 1 小时)。Cron 调度使用 [worldline-go/hardloop](https://github.com/worldline-go/hardloop);请注意,day-of-month 和 day-of-week 与 AND 结合使用。更改后无需重启 krabby。
## 配置
参见 [krabby.example.yaml](krabby.example.yaml)。通过 [chu](https://github.com/rakunlabs/chu) 加载:默认值 → `krabby.yaml`(或 `CONFIG_FILE`)→ `KRABBY_*` 环境变量。
文档 RAG 和代码 RAG 可独立在设置 UI 中切换。代码 RAG 可以使用自己的嵌入器;如果未设置,则重用文档嵌入器。嵌入式后端将文档和代码存储在单独的存储中,因此不同的向量维度是安全的。生成的 Markdown 存储在克隆外的 `data_dir/docs/<owner>/<repo>/` 下;较旧的克隆 `krabby-docs/` 树在启动时移动到此处,而无需重新生成文档。