返回博客列表

codebase-memory-mcp:把代码库编译成可查询的知识图谱

2026-08-27T19:30:00+08:00
codebase-memory-mcpMCP代码智能知识图谱Claude Code

codebase-memory-mcp:把代码库编译成可查询的知识图谱

40.8k Star、3.3k Fork、一个单文件静态二进制——它把 158 种编程语言的代码库,编译成一张持久化知识图谱,再用 MCP 协议把结构化代码智能喂给你正在用的 Agent。

2026 年夏天,MCP(Model Context Protocol)生态的热度还在加速上升,但绝大多数 MCP Server 还停留在"把一个现有 API 包成 2-3 个工具"的薄封装修辞层面。而 GitHub 上 DeusData 放出的 codebase-memory-mcp 不一样——它自己就是一整套完整的代码分析基础设施,打包成一个零依赖的单文件静态二进制:158 个 vendored tree-sitter 语法、自研的 Hybrid LSP 语义解析器、SQLite + LZ4 RAM-first 索引流水线、Cypher 子集查询引擎、BM25 全文检索、Nomic nomic-embed-code 嵌入式向量搜索、Louvain 社区发现算法、跨服务路由映射、跨仓库 CROSS_* 边、git diff 影响半径评估、ADR 持久化……全部塞进这一个二进制里。

最抓人眼球的数字是 Token 对比:同等复杂度的 5 次结构查询,走 codebase-memory-mcp 消费 3,400 tokens;按"逐文件 grep+读文件"的经典工作流消费 412,000 tokens——减少 99.2%。代价是一次预索引(Linux 内核 28M LOC / 75K 文件 → 3 分钟完成 481 万节点 / 772 万边),之后任何 Cypher 查询都在 <1ms 返回,正则名字搜索 <10ms,深度=5 的 BFS 调用路径追踪 <10ms

本文提纲

  1. 它到底是什么:不内置 LLM 的"结构分析后端 + MCP 前端"
  2. 三档 Agent 定义:Scout / Verify / Auditor 和 43 个客户端的自动配置
  3. 索引流水线:158 种语法 × Hybrid LSP × RAM-first × 跨服务链路
  4. 查询体系:Structural + Cypher + Semantic + BM25 + 代码级 grep 五层叠加
  5. 团队共享 Graph Artifact:一份 zstd 压缩文件替代全员重索引
  6. Hybrid LSP 详解:C 实现的轻量语义解析对标 pyright/tsserver/rust-analyzer
  7. 性能数据与安全发布管线:SLSA Level 3 + Sigstore + CodeQL + VirusTotal
  8. 快速上手:安装 → 索引 → 查询 → UI 可视化

它到底是什么:不内置 LLM 的"结构分析后端 + MCP 前端"

架构上 codebase-memory-mcp 的划分非常干净:

graph TB
    subgraph MCP Client Layer
        A1[Claude Code]
        A2[Codex CLI]
        A3[Gemini CLI]
        A4[Cursor / Zed / VS Code]
        A5[Aider / Continue / OpenHands…]
    end
    subgraph codebase-memory-mcp Binary
        B1[MCP Server
15 Tools + JSON-RPC 2.0] B2[Installer/CLI Config
43 Client Surfaces] B3[Daemon
共享进程+Watcher+Diagnostics] B4[Pipeline
158 Grammars × Hybrid LSP] B5[Store
SQLite Graph + LZ4 + WAL] B6[Cypher Engine
openCypher Read Subset] B7[Search Engine
BM25 / FTS5 / Semantic] B8[Watcher
Git Polling Auto-sync] B9[UI
HTTP + 3D Graph] end subgraph Local Disk C1[Source code] C2[~/.cache/codebase-memory-mcp
SQLite DBs] C3[.codebase-memory/graph.db.zst
团队共享Artifact] end A1 -->|MCP JSON-RPC stdio| B1 A2 --> B1 A3 --> B1 A4 --> B1 A5 --> B1 B1 --> B4 B4 --> C1 B4 --> B5 B5 --> B6 B5 --> B7 B8 --> B4 B9 --> B5 B5 <--> C2 B5 <--> C3

刻意不内置 LLM:README 专门解释了为什么——"其他 code graph 工具会嵌一个 LLM 来做自然语言 → 图查询翻译,这意味着额外 API Key、额外成本、又要多配置一个模型。用 MCP 协议的话,你本来就在对话的那个 Agent,就是你的查询翻译器。"你直接用自然语言问"谁调用了 ProcessOrder?",Agent 会自己发 trace_path(function_name="ProcessOrder", direction="inbound"),CBM 返回结构化结果,再由 Agent 翻译成自然语言给你。

一个关键推论:这是一个"你的 Agent 越聪明,它就越好用"的杠杆工具——它只输出结构化事实,不做推理。推理全推给客户端那边的 MCP 宿主 Agent。

三档 Agent 定义:Scout / Verify / Auditor 和 43 个客户端的自动配置

codebase-memory-mcp install 不是只写一条 MCP 配置。它会检测当前机器上已有的客户端,并为每个客户端从同一份 canonical contract 创建 3 档精确所有的 Agent 定义(Tier 1/2/3),这个设计在当前 MCP 生态里非常少见:

Tier 名称 能力边界
Tier 1 Scout 仅 3-4 条窄调用,用于快速"有/无"发现。不做"不存在"的结论、不做全量影响评估、不做死代码判断
Tier 2 Verify(默认) 任务导向的图证据 + 精确源码核对 + 每一条被引用文件都做 path coverage,在做"负面结论"之前先做 scope coverage
Tier 3 Auditor 限定作用域、锁定当前 index generation、完整相关分页、更宽关系检查、显式声明未解决的限制

每一档都会对它引用的证据路径批量跑 check_index_coverage,直接读取被标记跳过/排除的范围或文件;"干净的 coverage 结果"只等于"没有记录到 gap",绝不等于"完整性证明"——这是故意把"吹过头"的口子焊死。

到 v0.8.0 为止 installer 一共支持 43 个 client surfaces(37 自动检测 + 6 条件式/显式),涵盖了所有主流 Agent:Claude Code、Codex CLI、Gemini CLI、Zed、OpenCode、Antigravity、Aider、KiloCode、VS Code、Cursor、Windsurf、Augment/Auggie、OpenClaw、Kiro、Junie、Hermes、OpenHands、Cline、Warp、Qwen Code、GitHub Copilot CLI、Factory Droid、Crush、Goose、Mistral Vibe、Qoder CLI、Kimi Code CLI、GitLab Duo CLI、Rovo Dev CLI、Amp、Devin CLI/Local、Tabnine、Continue/cn 等。

对 Claude Code 来说还会额外挂 4 个生命周期钩子:SessionStartSubagentStart、非阻塞 PreToolUse for Grep/Glob、以及 post-Read coverage。

索引流水线:158 种语法 × Hybrid LSP × RAM-first × 跨服务链路

索引阶段用 6-pass 多进程流水线构建知识图谱:

graph LR
    P0[Discovery Pass] --> P1[Structure Pass]
    P1 --> P2[Definition Pass]
    P2 --> P3[Call Pass]
    P3 --> P4[Cross-Service Pass]
    P4 --> P5[Config & Test Pass]
    P5 --> RAM[In-mem SQLite
LZ4 HC] RAM --> Disk[Single SQLite Dump
Released back to OS]

每一步的职责:

  • Discovery.git / node_modules 等硬编码排除 + .gitignore 层级 + .cbmignore(gitignore 语义 + 否定语义)三层过滤,符号链接永远跳过;CBM_ALLOWED_ROOT 环境变量可把索引边界限定在某目录树内,解决"不可信调用方驱动 server"的 agentic/multi-tenant 部署问题。
  • Structure:158 个 vendored tree-sitter grammar 跑语法解析,产出节点/定义骨架。
  • Definition / Call:抽取定义、导入、调用点;Hybrid LSP(下一节详述)对 12 种重点语言做类型感知的精化,把"文本匹配可能对"的调用升级成 CALLS 或精确的 CALL_REFERENCE,剩下无法证明唯一目标的保留成 USAGE 弱边。
  • Cross-Service
    • HTTP Route ↔ call-site 匹配(附置信度评分)
    • gRPC / GraphQL / tRPC 服务检测(含 protobuf Route 抽取)
    • EventEmitter / Socket.IO / 通用 pub-sub Channel 检测(跨 8 种语言,做常量字符串解析),生成 EMITS / LISTENS_ON
    • IaC 节点:Dockerfile、K8s manifest、Kustomize overlay
    • Infra 调用:HTTP_CALLSASYNC_CALLS 跨服务边
  • Config & TestCONFIGURES / WRITES / TESTS 等非调用语义边。
  • RAM-first pipeline:全程跑在内存里,读取 LZ4 HC 压缩、SQLite in-memory、最后一次性 dump 到磁盘;索引完成后内存还给操作系统,不占常驻 RAM。

多仓库联合索引:只要是同一个 store 下的项目,就会生成 CROSS_* 类型的边把不同 repo 的节点连接起来;配套"Multi-galaxy 3D UI 布局"做多仓库架构可视化和跨仓库 summary。

查询体系:五层叠加的检索与分析

MCP Server 暴露 15 个工具(Indexing 5 个 + Querying 10 个)。查询能力实际是五个独立搜索子系统的叠加:

1. Structural(search_graph / trace_path / get_graph_schema)

  • label(Project / Package / File / Module / Class / Function / Method / Interface / Enum / Type / Route / Resource)过滤
  • 名字正则、度数过滤(min/max degree,这就是死代码检测的基础:WHERE NOT EXISTS { (f)<-[:CALLS]-() }
  • 文件范围、分页(limit/offset)
  • trace_path:BFS 遍历,别名 trace_call_path,depth 1-5

2. Cypher 查询(query_graph)——只读 openCypher 子集

支持的从句与能力:

-- 死代码扫描
MATCH (f:Function)
WHERE NOT EXISTS { (f)<-[:CALLS]-() }
RETURN f.file, f.name, labels(f)

-- 谁调用了 main ?
MATCH (f:Function)-[:CALLS]->(g:Function)
WHERE g.name = 'main'
RETURN f.name, f.file

-- MinHash 近克隆(SIMILAR_TO)
MATCH (a)-[:SIMILAR_TO {jaccard: 0.92}]->(b)
WHERE a:Class AND b:Class
RETURN a.name, b.name

-- 变量长度路径(跨包)
MATCH p = (start:Route)-[:CALLS*1..3]->(end:Resource)
RETURN p ORDER BY length(p) DESC

明确声明不支持的语法会报"unsupported X"错误,而不是空结果——避免"以为没数据,其实是语句写错了"这种最常见的坑。

3. 语义查询(semantic_query)——向量搜索,零外部依赖

  • 用 Nomic 发布的 nomic-embed-code 40K tokens / 768d int8 模型——编译进二进制,不需要 API Key、不需要 Ollama、不需要 Docker。
  • 最终打分不是纯 cosine,是 11 信号加权联合打分: TF-IDF、RRI、API/Type/Decorator 签名、AST 轮廓、数据流、Halstead-lite 复杂度、MinHash 近克隆、模块邻近度、图扩散、外加向量本身。

4. BM25 全文检索(search_code 底层)

  • 底层 SQLite FTS5 + 自研 tokenizer cbm_camel_splitcamelCase 和 snake_case 感知的分词器——这对代码搜索的精准度提升远大于 BM25 本身。

5. Grep-like 代码搜索(search_code)

  • 只在已索引文件范围内做 graph-augmented grep,比全仓 rg 快得多,且天然避开 .gitignore / .cbmignore。

查询能力之外的"高价值辅助工具":

工具 作用
get_architecture 一次调用返回:语言、依赖包、入口点、Routes、热区、架构边界、层次、Louvain 聚类
detect_changes 把未提交 git diff 映射到受影响符号,输出 blast radius + 风险分级
manage_adr Architecture Decision Record 增删改查;读不走"同项目 reindex 锁",写仍串行化
ingest_traces 把线上 runtime trace 回灌,验证 HTTP_CALLS 等跨服务边是否真实成立

团队共享 Graph Artifact:一份 zstd 文件替代全员重索引

这是非常"懂团队工程"的一个小功能:

.codebase-memory/graph.db.zst

它是知识图谱 SQLite 的 zstd 压缩快照,跟源码放在一起,可以直接 commit 进仓库

  • 格式:SQLite DB 先 strip 掉所有非聚簇索引、VACUUM INTO 压小,再 zstd 1.5.7 压缩;典型压缩比 8–13 : 1
  • 两档:
    • Bestzstd -9 + index strip + VACUUM INTO(显式 index_repository 时写)
    • Fastzstd -3(后台 watcher 低延迟增量刷新)
  • Bootstrap 流程:新同事 clone 仓库后本地没有 DB → index_repository先导入 artifact,再做增量索引,跳过 95% 以上的初次索引时间
  • 无合并冲突:首次 export 时自动在 .gitattributes 里写入 merge=ours,二进制 artifact 并发编辑永远不会冲突
  • 可选:不愿意 commit 的把 .codebase-memory/ 加进 .gitignore 即可,每个人本地重新索引

作者明说:"思路和 graphify 的 graphify-out/ 目录精神一致,但做成了单压缩文件 + 显式两档导出 + 完整性校验导入 + 零合并摩擦。"

Hybrid LSP 详解:C 实现的轻量语义解析对标专业 Language Server

Tree-sitter 解决的是"语法级 AST"问题——它能找名字、结构、调用点,但解决不了下面这个问题:

# 文件 a.py
from services.profile import ProfileService
user.profile.display_name()  # tree-sitter 只能看见 .display_name()
# 但它实际上对应 services/profile.py 里 Profile.display_name

这就是为什么纯 tree-sitter 做的"调用图"一直很脆。codebase-memory-mcp 的应对是把类型解析算法用 C 重写进二进制,叫 Hybrid LSP。作者明确说它的实现"结构上启发自/兼容 tsserver / typescript-go、pyright、gopls、Roslyn、Eclipse JDT、rust-analyzer"。

覆盖 12 种重点语言(Python / TS/JS/JSX/TSX / PHP / C# / Go / C / C++ / Java / Kotlin / Rust / Perl),每一种都写了专有的处理范围,比如:

  • Python:dataclasses、Self、泛型、@propertymatch/case 类模式、SQLAlchemy 2.0 Mapped[T]、Pydantic BaseModel、Annotated/ClassVar/Final/InitVar、isinstance / walrus 窄化、logging/json/functools/pathlib 等常见 stdlib
  • TypeScript/JavaScript:泛型、JSX component dispatch、纯 JS 的 JSDoc 推断、.d.ts 声明、模块 re-export、链式调用通过返回类型传播
  • Rust:impl blocks + trait methods、struct fields、泛型 + trait bounds、operator trait 脱糖、derive macro 方法合成、UFCS 静态路径、标准 prelude
  • Java / Kotlin / C# / PHP / Go / C / C++ / Perl 都列了相当具体的算法项(不是一句"支持该语言")。

两级分层很清晰:

  • Tree-sitter pass(158 语言全跑):快速、语法、抽定义/调用/导入
  • Hybrid LSP pass(12 种重点语言额外跑):类型感知、基于导入图和交叉文件注册表精化调用边;没覆盖到的语言自动退回文本级解析,至少有答案

最终效果是 trace_path 跨 package、跨继承层级、甚至跨 stdlib 调用都能给出正确结果,同时完全不用启动任何 Language Server 进程

性能数据与安全发布管线

性能(Apple M3 Pro)

操作 耗时 备注
Linux kernel 全索引 3 min 28M LOC / 75K files → 4.81M 节点 / 7.72M 边
Linux kernel 快速索引 1m 12s 1.88M 节点
Django 全索引 ~6s 49K 节点 / 196K 边
Cypher 查询 <1ms 关系遍历
Name search(regex) <10ms SQL LIKE 预过滤
Dead code 检测 ~150ms 全图扫描 + 度过滤
Trace call path(depth=5) <10ms BFS

Token 对比再次强调:5 次结构化查询对比"逐文件 grep 探索",3,400 vs 412,000 tokens,-99.2%

隐私与 Diagnostics

完全本地,零遥测。这带来一个副作用:当用户报"长时间运行后内存缓慢涨"这种必须看趋势才能定位的 Bug 时,作者手上没有数据。所以他们做了一个非常克制的 diagnostics 方案:CBM_DIAGNOSTICS=1 时,daemon 会在系统临时目录下新建一个带随机后缀的 owner-private 目录(防止本地其他账号预先放链接做路径攻击),每 5 秒写一条 JSON 到 trajectory.ndjson,内容只有 RSS/committed/peak_*/page_fault/fd 等资源计数器,不含源码、不含查询文本;问题定位只需要增长趋势。trajectory.ndjson 超过 8MB 自动旋转,进程干净退出后自动删 snapshot.json,只保留轨迹文件供 post-mortem。

发布安全(多层流水线)

说明
VirusTotal 8 个 release 产物 × 3 种可执行候选(unstripped/debug-stripped/stripped)=24 份全部扫描;非 0/X 检出才发布,且发布页面直接附每个 SHA-256 的扫描链接(附 TSV 审计证据)。除 exe 外 install.sh/install.ps1/LICENSE/THIRD_PARTY_NOTICES/manifest.json/UI 资产也逐个扫
SLSA Level 3 受信 GitHub Actions build 工作流生成加密构建源证明;gh attestation verify <file> --repo DeusData/codebase-memory-mcp --signer-workflow _build.yml 可验
Sigstore cosign 无密钥签名,每个 release 附 bundle
SHA-256 checksums 每个 release 发布 checksums.txt,install 脚本解压前必校验
CodeQL SAST 有未关闭告警就阻断 release 流水线
零 runtime 依赖链 所有库编译时 vendor;少量 runtime-owned 小资产做 checksum + content-address
自研更新器移除 v0.7 之后 cbm 二进制内不再带自更新器,也不后台联网查新版本,不打电话。发现新版本的渠道:install 脚本 / 你自己的包管理器 / GitHub

快速上手:8 步跑通你的第一次查询

# 1. 安装(8 种安装渠道任选)
#    Claude Code 内一句话安装:
#    你直接对 Claude Code 说:"Install this MCP server: https://github.com/DeusData/codebase-memory-mcp"
#    或手动:
brew install codebase-memory-mcp           # macOS
scoop install codebase-memory-mcp            # Windows
yay -S codebase-memory-mcp-bin               # Arch Linux
npm install -g codebase-memory-mcp           # 跨平台 npm
pip install -U codebase-memory-mcp           # 跨平台 pip

# 2. 索引一个仓库(第一次需要全量,之后 watcher 自动增量)
codebase-memory-mcp cli index_repository \
  --repo-path /absolute/path/to/your/repo

# 3. 查看已索引项目(记下 name 字段做后续参数)
codebase-memory-mcp cli list_projects

# 4. 结构搜索:找所有 *Handler 类的 Function 节点
codebase-memory-mcp cli search_graph \
  --project my-project \
  --name-pattern '.*Handler.*' \
  --label Function

# 5. 调用路径追踪:谁调用 Search / Search 又调用谁
codebase-memory-mcp cli trace_path \
  --project my-project \
  --function-name Search \
  --direction both

# 6. Cypher 查询:死代码扫描(没有入 CALLS 边的 Function)
codebase-memory-mcp cli query_graph \
  --project my-project \
  --query 'MATCH (f:Function) WHERE NOT EXISTS { (f)<-[:CALLS]-() } RETURN f.name, f.file'

# 7. Git 变更影响评估(配合 git worktree / stash 使用也可)
#    在 Agent 里 MCP 工具:detect_changes(project="…")

# 8. 启动 3D 图谱 UI(默认 http://localhost:9749)
codebase-memory-mcp --ui=true

几个容易踩的坑(来自 README 末尾 Troubleshooting 表):

  • /mcp 里看不到 server → 确认 .mcp.json 路径是绝对路径;重启 Agent;smoke:echo '{}' | /path/to/binary 能吐 JSON 就是好的。
  • index_repository 失败 → repo_path 必须传绝对路径
  • trace_path 0 结果 → 先 search_graph(name_pattern=".*PartialName.*") 找到精确的限定名再追。
  • 跨项目查询错项目 → 所有调用都显式传 project=,先 list_projects 看实际名字。
  • 容器里索引慢 / 并发偏高 → CBM_WORKERS 覆盖 cgroup 有效 CPU;CBM_MEM_BUDGET_MB 给内存预算封顶。

作者: itech001 来源: 公众号:AI人工智能时代(the-ai-era) 网站: https://www.theaiera.top/ 关注每日最新AI新闻和技术博客,主页有更多的文章的AI 技术参考:https://www.theaiera.top

本文首发于 AI人工智能时代,转载请注明出处。

分享给朋友