首页
/ codebase-memory-mcp 上手指南与深度剖析:把代码库变成毫秒级持久化知识图谱的 MCP 服务器

codebase-memory-mcp 上手指南与深度剖析:把代码库变成毫秒级持久化知识图谱的 MCP 服务器

2026-09-08 20:09:13作者:龚格成

codebase-memory-mcp(下文简称 CBM)是一套高性能的代码智能 MCP 服务器,它将整个代码库索引进一个持久化知识图谱——函数、类、调用链、HTTP 路由、跨服务与跨仓库依赖都被建模为图节点与边,供 AI 编码 Agent 以极少的调用与 token 完成架构理解、调用追踪与影响分析。本篇以仓库根目录 README.md 为骨架,结合 docs/CONFIGURATION.mddocs/cbmignore.mdsrc/internal/cbm/ 下的真实实现,系统讲解它的设计动机、安装激活、配置调优、15 个 MCP 工具、CLI 模式、Hybrid LSP 类型解析与团队共享图谱工件,读完后你可以完成从“零配置跑通”到“按需深调与排障”的完整落地。

codebase-memory-mcp 内置 3D 图谱可视化界面

它是什么:面向 Agent 的结构化分析后端,而不是又一个 LLM

CBM 明确将自己定位为 structural analysis backend(结构化分析后端):它构建并查询知识图谱,自身不内置 LLM。在 MCP 架构里,你已经对话的编码 Agent(Claude Code 或任何 MCP 兼容客户端)就是自然语言 → 图查询的“翻译器”。README 给出了这个典型交互模型(README.md):

You: "what calls ProcessOrder?"

Agent calls: trace_path(function_name="ProcessOrder", direction="inbound")

codebase-memory-mcp: executes graph query, returns structured results

Agent: presents the call chain in plain English

为什么刻意不内置 LLM?其他代码图谱工具往往内嵌一个大模型做“自然语言 → 图查询”翻译,代价是多一套 API Key、多一笔 token 开销、多一个需要配置的模型。CBM 的取舍是:既然 MCP 协议下 Agent 本来就是查询翻译器,就把“智能”留在 Agent,把“结构化事实”留给本地图引擎。这也解释了 README 反复强调的部署形态——单一静态二进制、零依赖、无语言运行时、无托管服务、无 API Key,所有处理 100% 本地完成,代码不会离开你的机器(README.md)。

支撑这一承诺的源码骨架

二进制入口 src/main.c 的头部注释明确列出了进程的多种模式(src/main.c):

  • 默认(无参数):在 stdin/stdout 上以 JSON-RPC 2.0 运行 MCP server
  • cli <tool>:本地一次性执行某个工具调用并打印结果,不留常驻进程;
  • --version / --help
  • --ui=true/false--port=N:启用/关闭 HTTP 图谱可视化 UI(默认端口 9749,持久化);
  • --tool-profile=analysis|scout:为受限 Agent 场景暴露裁剪后的工具面;
  • install / uninstall / update / config:本机安装与配置管理。

对应地,src/main.cprint_help 列举了同样的子命令面,并额外给出 install 支持的 45 个自动/条件客户端表面清单。目录布局也在 README 的 Architecture 章节给出,与源码一一对应:src/mcp/ 是 MCP 服务器与 15 个工具注册处、src/store/ 是 SQLite 图谱存储、src/pipeline/ 是多趟索引流水线、src/cypher/ 是 openCypher 只读子集的词法/语法/规划/执行器、src/daemon/ 是会话协调守护进程、internal/cbm/ 是 vendored tree-sitter 文法与 AST 提取引擎。

为什么选它:索引速度、语言覆盖与 token 效率

README 的核心卖点可以归纳为四类,其中可量化指标均标注了具体测量前提(基准机器为 Apple M3 Pro,见 README.md),引用时需注意这些前提:

  1. 极端的索引速度:Linux 内核(28M LOC、75K 文件)完整索引约 3 分钟,产出 4.81M 节点、7.72M 边;Django 全量索引约 6 秒(49K 节点、196K 边);快档(fast index)Linux 内核仅 1 分 12 秒(1.88M 节点)。README 解释其关键在于 RAM-first pipeline——LZ4 HC 压缩读取、内存内 SQLite、结束时一次性 dump,索引完成后内存归还操作系统(README.md)。
  2. 162 语言覆盖:全部通过编译进二进制的 vendored tree-sitter 文法解析,无需额外安装。这一数字在仓库中可核实:internal/cbm/ 目录下存在 162 个 grammar_*.c 语言文法文件(internal/cbm),README 同时给出的“158 vendored tree-sitter grammars compiled into the binary”与徽章处的 162 种语言口径略有差异,属于迭代期版本措辞,实际以你运行版本的 --versionget_architecture 输出为准。
  3. Token 效率:README 报告 5 个结构化查询约消耗 3,400 token,而逐文件 grep 探索约 412,000 token,降幅约 99.2%(另一处表述为 120×)。这类数字依赖原始输入与产物,无法在本仓库内直接复现;需要自行评估可比质量、延迟与 Agent 节省时,按 docs/MEASURING_SAVINGS.md 提供的方法在你自己的负载上测量。
  4. 即插即用与低摩擦分发:一个原生可执行文件加一组受校验的 release 运行时资源,覆盖 macOS(arm64/amd64)、Linux(arm64/amd64)、Windows(amd64),并提供 npm、PyPI、Homebrew、Scoop、Winget、Chocolatey、AUR、go install 等渠道(各渠道清单见 pkg 目录下的 npm/pypi/homebrew/scoop/winget/aur/chocolatey/)。install 命令会一次配置检测到的编码 Agent,并为有条件激活的客户端在“文档规定的平台/标记/显式存在的配置路径”齐备时才写入,绝不去翻实验性开关或全局权限绕过(README.md)。

快速开始:四种安装路径

1. 一行安装(macOS / Linux)

README 推荐直接管道执行安装脚本:

curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash

Windows(PowerShell):

# 1. 下载安装器
Invoke-WebRequest -Uri https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.ps1 -OutFile install.ps1
# 2.(可选但推荐)人工审阅脚本
notepad install.ps1
# 3. 解除浏览器/Invoke-WebRequest 施加的 Mark-of-the-Web 限制
Unblock-File .\install.ps1
# 4. 运行
.\install.ps1

如果遇到脚本执行策略报错,先运行 Set-ExecutionPolicy -Scope Process Bypass,或以 PowerShell -ExecutionPolicy Bypass -File .\install.ps1 方式调用。安装器支持两个选项:--skip-config(只要二进制、不做任何 Agent 配置)与 --dir=<path>(自定义安装位置)。

仓库内的 install.sh / install.ps1(仓库根目录)即这套入口脚本;CI 与打包所依赖的完整安装与验证逻辑还可见于 scripts/package-release.shscripts/ci/smoke-artifact.sh

关于杀毒误报:README 提醒 Microsoft Defender 可能将发布二进制标记为 Trojan:Script/Wacatac.B!ml,这是已知误报(同一检测家族也会命中 gh、llama.cpp、Godot 以及微软自家 Go 工具链),典型结果是约 61/62 个引擎干净。详见 SECURITY.md 的 Antivirus False Positives 一节给出的证据、自行核验步骤与上报方式。

2. 手动安装(不信任管道安装时)

从对应平台的 latest release 下载归档,命名形如 codebase-memory-mcp-<os>-<arch>.tar.gz(macOS/Linux)或 .zip(Windows)。每个归档内含 install.sh / install.ps1

tar xzf codebase-memory-mcp-*.tar.gz
./install.sh
Expand-Archive codebase-memory-mcp-windows-amd64.zip -DestinationPath .
Unblock-File .\install.ps1
.\install.ps1

随后重启你的编码 Agent,再说一句“Index this project”即可。install 命令会自动去掉 macOS quarantine 属性并做 ad-hoc 签名,无需手工 xattr/codesign

3. 手工 MCP 配置(绕过 install)

如果你希望完全手写 MCP 配置而不是用 install 命令,README 给出了标准的 mcpServers JSON。追加到 ~/.claude.json(用户级)或项目的 .mcp.json

{
  "mcpServers": {
    "codebase-memory-mcp": {
      "command": "/path/to/codebase-memory-mcp",
      "args": []
    }
  }
}

重启 Agent 后用 /mcp 验证,应能看到 codebase-memory-mcp 及其 15 个工具。

4. 源码构建与跑测试

构建前置条件为 C/C++ 编译器与 zlib(macOS 自带,Linux 需 apt install build-zlib1g-dev 一类),构建命令来自 README 并对应仓库中的 scripts 目录:

git clone https://github.com/DeusData/codebase-memory-mcp.git
cd codebase-memory-mcp
scripts/build.sh --with-ui          # 发布形态(内嵌图 UI)
scripts/build.sh                    # 不含 UI(仅开发用)
# 产物: build/c/codebase-memory-mcp  (Windows 为 .exe)

运行测试套件(README 报告 6,768 个测试 / 120 个 suite):

scripts/test.sh                     # 完整:clean sanitizer build + 全部 suite + guards
scripts/test.sh --suites <name>     # 单套件,增量,秒级
build/c/test-runner --list-suites   # 查看可用 suite

README 特别说明:scripts/test.sh 与 CI gate 跑的是同一个入口,本地通过即等同于 CI 通过;scripts/ci/smoke-artifact.sh <linux|darwin|windows> <amd64|arm64> 做规范化产物流冒烟;而 scripts/package-release.sh 是一个刻意“只收已定稿 --selected-binary--expected-sha256、绝不参与构建/剥离/签名/重链接”的低层不可变边界。

会话协调守护进程:跨客户端的常驻协作机制

新版架构里,CBM 会让一个每账号一个的 coordination daemon 被 Claude Code、Codex、OpenCode 及其余已配置客户端共享(README.md)。第一次由 daemon 支撑的 CBM 会话启动它,每个会话注册自己的工作,最后一个会话负责关闭它。守护进程拥有 watchers、共享索引任务和可选 UI 等长生命周期后台服务;关掉一个会话只取消该会话独占的工作,别的主体会话仍需要的工作会继续。

守护进程不依赖 MCP 前端 stderr,其 owner-only 持久记录统一放在 ${CBM_CACHE_DIR}/logs(默认 ~/.cache/codebase-memory-mcp/logs):

文件 内容
cbm-daemon.log 守护进程生命周期、watcher/索引、UI、资源与错误事件
daemon-conflicts.ndjson exact-build、协调 ABI、cache-root 准入冲突
activation-events.ndjson install/update/uninstall 激活进度与结果

几个值得注意的运行约束(README + 源码注释可互相印证,例如 src/main.c 中对项目锁与协调清理超时的处理):

  • 所有存活的 CBM 进程必须使用完全相同版本、相同可执行构建、相同协调 ABI、相同规范化 cache rootCBM_CACHE_DIR 的等价别名会解析到同一 root;真正不同的 root 在任一 CBM 进程活跃期间会被拒绝。MCP 服务器、hooks、一次性 CLI 命令、临时索引 worker 与 daemon 共享崩溃安全的 OS 准入屏障,冲突会显式写入 daemon-conflicts.ndjson
  • install / update / uninstall 是该冲突规则的刻意例外:先下载、校验、在同文件系统私有暂存,确保坏候选不会打断运行中的工作;随后发布 account-wide 维护意图、请 daemon 与所有临时本地操作取消、在有限期限内等待协调进程全部退出,期间独占准入与生命周期屏障去更换二进制/配置/PATH/索引。激活进度记录在 activation-events.ndjson,成功后命令会提示你重启打开的 Agent 会话。
  • npm/PyPI/Go 的包管理器安装会核验并发布一套一致的私有缓存运行时集,用逐文件原子改名替换 sidecar;它替换激活中的原生安装,因此不会打断正在运行的 CBM 会话,但缓存二进制一旦被执行,同样进入 exact-build 准入屏障。
  • 普通 cli 模式刻意独立:单次本地执行,不启动也不连 daemon、不注册会话、不启动 watcher/UI,只共享 OS 准入屏障与图变更所需的 per-project 锁。

图谱可视化 UI 与 Auto-Index

图 UI 内建于二进制——任何渠道、任何安装都自带。启动方式:

codebase-memory-mcp --ui=true --port=9749

浏览器打开 http://localhost:9749。UI 由共享协调 daemon 持有,因此并发 Agent 会话不会起重复的 HTTP server。UI 数据文件位于 ${CBM_CACHE_DIR}/config.json,格式为 {"ui_enabled": false, "ui_port": 9749};首次运行且资产包完整时会自动启用。前端源码位于 graph-ui/src(React + TypeScript 组件分布在 graph-ui/src/components),HTTP 层在 src/ui,布局与 3D 渲染逻辑见 src/ui/layout3d.csrc/ui/http_server.c。需要说明的是:UI 被设计为 MCP 会话内由 daemon 持有;手工启动(非 MCP 客户端拉起)时服务器会在 stdin 关闭即退出——这是标准 MCP 行为,测 UI 时保持 stdin 打开,例如 sleep infinity | codebase-memory-mcp --ui=true --port=9749

Auto-Index:开启会话启动即自动索引:

codebase-memory-mcp config set auto_index true

开启后,新项目在首次连接时自动索引;已索引项目会被注册给后台 watcher 做持续 git 变更检测。可配文件数上限:config set auto_index_limit 50000。watcher 注册由 auto_watch(默认 true)单独控制,置 false 可阻止某会话把项目注册给后台 watcher(适合跨大量项目、希望每个会话只做显式索引的场景)。

完全关闭 watcher 用 config set watcher_enabled false(默认 true):后台轮询线程根本不启动、不再注册任何项目,而 auto_index 与手动 index_repository 照常工作。注意与 auto_watch 的差异:auto_watch每个会话连接时按次查询,改动对之后的会话生效;watcher_enableddaemon 启动时读取一次(它决定 watcher 是否被构建出来),因此改动后需要 codebase-memory-mcp daemon stop 让下一个 daemon 拾取新值,仅重连 MCP 客户端不会重启 daemon。这一“何时读取”的语义差异在 docs/CONFIGURATION.md 有完整说明。

配置体系:config 子命令、配置文件与环境变量

CBM 的配置分三层,完整参照见 docs/CONFIGURATION.md,此处继承 README 的核心命令并补充含义。

CLI-managed 运行时设置

运行时设置落在 SQLite 小库 ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/_config.db,用子命令读写:

codebase-memory-mcp config list                          # 展示全部设置
codebase-memory-mcp config get auto_index                # 读单个键
codebase-memory-mcp config set auto_index true           # 会话启动即自动索引
codebase-memory-mcp config set auto_index_limit 50000    # 自动索引最大文件数
codebase-memory-mcp config set auto_watch false          # 不注册后台 git watcher(默认 true)
codebase-memory-mcp config set watcher_enabled false     # 完全停止 watcher 线程(默认 true)
codebase-memory-mcp config reset auto_index              # 恢复默认值

对应键的语义(摘自 docs/CONFIGURATION.md):

Key 默认 含义
auto_index false MCP 会话启动时自动索引新项目
auto_index_limit 50000 新项目自动索引允许的最大文件数
auto_watch true 连接时把会话项目注册给后台 git watcher;置 false 则不注册(watcher 仍为其他项目运行)
watcher_enabled true 后台 watcher 子系统总开关;置 false 则不启动轮询线程、不注册任何项目,需手动 index_repository 重索引

环境变量总表

README 的变量表(README.md)是排障与部署的关键,逐项继承如下;docs/CONFIGURATION.md 还补充了 CBM_RUNTIME_DIR

变量 默认 说明
CBM_ALLOWED_ROOT (未设置) index_repository 限制在此目录内;设置后解析(含 symlink / ..)到该 root 之外的 repo_path 被拒绝,同一检查也作用于图 UI 的 POST /api/index 路由。适合服务器可能被不可信调用方驱动的场景(agentic 或多租户部署)。未设置则无 containment 限制,但下面的始终生效限制仍然适用。
CBM_CACHE_DIR ~/.cache/codebase-memory-mcp 覆盖数据库存储目录。所有项目索引与配置都存在这里。一个账号同一时刻只能用一个规范化 cache root;切换前先关闭所有活跃 CBM 会话/命令。
CBM_DIAGNOSTICS false 1/true 启用共享 daemon 的周期 snapshot.json 与保留式 trajectory.ndjson(位于系统临时目录下新建的 owner-private 随机目录)。确切路径由 daemon 的 diagnostics.start 事件记录。
CBM_DOWNLOAD_URL GitHub releases 覆盖更新下载 URL,用于测试或自托管部署。
CBM_LOG_LEVEL 角色感知 最低日志级别。瘦 MCP/CLI/hook 前端默认 warn;detached daemon 及其受监督索引 worker 默认 info。可取值(大小写不敏感):debuginfowarnerrornone,或数字等价 04。前端消息进本会话 stderr;detached daemon 事件进 ${CBM_CACHE_DIR}/logs/cbm-daemon.log;stdout 保留给 MCP JSON-RPC。
CBM_WORKERS (自动探测) 覆盖并行索引 worker 数(cbm_default_worker_count)。容器内 sysconf(_SC_NPROCESSORS_ONLN) 报告宿主机 CPU 而非 cgroup 配额时有用。范围 1–256,非法值忽略并告警。
CBM_MEM_BUDGET_MB (自动探测) 以显式 MiB 上限覆盖内存中图谱预算,优先于默认 ram_fraction × total_RAM。无 cgroup 限制的裸机、或希望把预算压到 cgroup 限制之下给兄弟进程留余量时有用。须为正整数,会被钳制到探测到的总 RAM(记录 mem.budget.clamped);非数字/非正值忽略并告警。
CBM_DUMP_VERIFY_MIN_RATIO 0.5 索引后把持久化 SQLite 节点数与内存 dump 数比较;当持久化节点低于已提交节点该比例(且提交数 > 50)时,index_repository 返回 status:"degraded" 而非静默 indexed。范围 0–1,置 0 关闭。

另有两点部署级注意(README 与 docs/CONFIGURATION.md 共同强调):daemon 拥有的组件(诊断、daemon 日志、进程级索引资源限制)所使用环境变量从首个启动 daemon 的会话捕获,后加入的会话无法替换这些值——要变更需关闭所有 daemon 支撑会话、一致更新配置后重开会话;CBM_ALLOWED_ROOT 保持会话级、冲突的 CBM_CACHE_DIR 被拒绝、一次性 CLI 命令读自己的环境且不启动 daemon。CBM_RUNTIME_DIR 用于重定位 daemon rendezvous 目录(默认 %LOCALAPPDATA%//private/tmp//tmp 下的 cbm-daemon-<uid>),当默认祖先链无法通过私密目录校验(如 Windows profile 上被安装的应用添加了 capability-SID ACE)时设置,且你指定的目录会经过与默认位置完全相同的严格校验。

始终拒绝的索引根

无论 CBM_ALLOWED_ROOT 是否设置,下列目录会被拒绝作为索引根(约束的是 scope,不是 sensitivity——在被允许的 root 内,进程可读的每个文件都可能被索引并返回):

  • 文件系统根、Windows 盘根或 UNC 共享根;
  • 顶层系统树——/etc/var/usr/home/Users,Windows 的 C:\WindowsC:\UsersC:\ProgramDataC:\Program Files
  • 你的 home 目录本身(其下子目录可以);
  • 任意深度下的凭据目录——.ssh.aws.gnupg.kube.docker.netrc.git-credentials.password-store、macOS Keychains

自定义文件扩展名映射

.blade.php(Laravel)、.mjs(ES modules)这类框架专属扩展名可通过 JSON 映射到内置语言。项目级文件放在仓库根 .codebase-memory.json

{"extra_extensions": {".blade.php": "php", ".mjs": "javascript"}}

全局文件默认路径为 $XDG_CONFIG_HOME/codebase-memory-mcp/config.json(未设 XDG_CONFIG_HOME 时回退 ~/.config/codebase-memory-mcp/config.json):

{"extra_extensions": {".twig": "html", ".phtml": "php"}}

规则要点(README 与 docs/CONFIGURATION.md 一致):扩展名键必须. 开头;语言名大小写不敏感;未知语言名跳过并告警;缺失文件忽略;同一扩展名冲突时项目级覆盖全局。接受的语言名列表(含别名)较长,完整版见 README 的 Custom File Extensions 章节,别名示例:bashsh)、c++cpp)、c#csharp)、hclterraform)、objective-cobjc)等。

安装器将写入的 Agent/编辑器集成文件

install 命令还会把 MCP 条目与指令块写进 Claude Code、Codex、Gemini、VS Code、Cursor、Zed 等的配置。因目标路径随工具与平台而异,最稳妥的查验方式是 dry-run:

codebase-memory-mcp install --dry-run

该命令只打印安装器将要修改的具体配置文件,不写任何东西。

15 个 MCP 工具全解

README 声称安装完成后 /mcp 会看到 15 个工具README.md)。这些工具的名字与注册确实可以在 src/mcp/mcp.c 的注册表、以及 src/main.c 的动态工具帮助列表中得到印证;个别版本可能因内部演进增减条目,以你实际运行版本的 /mcp 输出为准。以下工具清单以 README 为准继承,并按功能分组:

索引类

工具 描述
index_repository 将仓库索引进图谱;此后 auto-sync 保持新鲜
list_projects 列出所有已索引项目及其节点/边计数
delete_project 删除一个项目及其全部图谱数据
index_status 检查项目索引状态

查询与分析类

工具 描述
search_graph 结构化、BM25 与语义搜索的统一入口;结构化行用 offset/limit 分页,语义排名行独立用 semantic_offset/semantic_limit 分页
trace_path BFS 遍历——谁调用某函数、它又调用了谁(别名 trace_call_path)。深度 1–5
detect_changes 把 git diff 映射到受影响符号与爆炸半径,含风险分级
query_graph 执行 Cypher 风格只读图查询
get_graph_schema 每种 label 的节点/边计数、关系模式、属性定义。建议先跑它
get_code_snippet 按限定名读取函数源码
get_architecture 代码库总览:语言、包、入口点、路由、热点、边界、分层、集群
search_code 仅在被索引项目文件内的类 grep 全文搜索(图谱增强)
manage_adr Architecture Decision Record 的 CRUD(get 读、update 整文替换、set_sections 只改写命名小节并逐字节保留其余内容、sections 列出标题)。查询模式不阻塞同项目重索引;写操作仍串行化
ingest_traces 摄入运行时 trace 以校验 HTTP_CALLS 边
check_index_coverage 校验候选路径是否被索引覆盖、是否存在未覆盖区间(README 的 MCP 工具表未单列,但 README 的 Multi-Agent 小节、src/mcp/mcp.csrc/cli/agent_profiles.c 中都把它作为核心证据工具使用)

manage_adr(mode='set_sections') 的行为值得一提:按名写入一个或多个小节并拼接进存储文档,因此命名小节之外的文本——前言、代码围栏、小节顺序——被逐字节保留。任意 ## Heading 都可以,不限于惯例的 PURPOSE/STACK/ARCHITECTURE/… 集合;名称含大小写精确匹配;同一小节写两次是 no-op,因此丢响应后的重试不会产生重复内容。其 get/sections 查询模式使用服务器的缓存查询存储,可在同项目重索引进行时继续读取(若重索引期间另一进程发布了替换存储,可能返回发布前的 ADR,直到空闲淘汰刷新缓存)。

Agent profile 的按级裁剪(Scout / Verify / Auditor)

README 的 Multi-Agent 支持还揭示了三个由同一规范契约派生的层级定义,它们的工具面在 src/mcp/mcp.cscout_tools[] / analysis_tools[] 白名单与 src/cli/agent_profiles.c 的描述中可核实:

  • Scout(Tier 1)——约 3–4 个窄调用做快速、临时性的正向发现;不做“缺失/穷举影响/死代码”类结论。
  • Verify(Tier 2,默认)——任务导向的图证据、精确源码核对、被引用文件路径覆盖、负面结论前的范围覆盖检查。
  • Auditor(Tier 3)——有界范围、当前索引代次、完整相关分页、更宽的关系检查、显式声明未决限制。

每个层级都会为其证据路径批量调用 check_index_coverage 并直接读取被标记区间或被跳过/排除的文件;干净的 coverage 只表示“无已记录缺口”,永远不构成完整性证明。以 --tool-profile scout / --tool-profile analysis 启动进程即可施加这些限制(源码入口见 src/main.c)。

图谱数据模型:节点标签、边类型与限定名

query_graph 之前的必要认知来自 README 的 Graph Data Model 章节

Node labelsProjectPackageFolderFileModuleClassFunctionMethodInterfaceEnumTypeRouteResource

Edge typesCONTAINS_PACKAGECONTAINS_FOLDERCONTAINS_FILEDEFINESDEFINES_METHODIMPORTSCALLSCALL_REFERENCEHTTP_CALLSASYNC_CALLSIMPLEMENTSHANDLESUSAGECONFIGURESWRITESMEMBER_OFTESTSUSES_TYPEFILE_CHANGES_WITH

README 的 “Edge types (selected)” 补充了语义细节:CALL_REFERENCE 表示可调用对象在受支持的引用位(如直接值参数)被使用且解析到唯一确定目标USAGE 表示标识符被使用但无法证明唯一可调用目标(含歧义或复杂表达式);DATA_FLOWS 带 arg-to-param 映射与字段访问链;SIMILAR_TO(MinHash + LSH 近克隆检测,Jaccard 打分);SEMANTICALLY_RELATED(词汇不匹配、同语言、分数 ≥ 0.80);通道类 EMITS / LISTENS_ON 覆盖 Socket.IO、EventEmitter 与 8 种语言上的泛化 pub-sub 模式;CROSS_* 边跨多个同一 store 下索引的仓库连接节点。

Qualified namesget_code_snippet 使用 <project>.<path_parts>.<name> 形式的限定名;先用 search_graph 发现它们。

query_graph 支持的 openCypher 只读子集

query_graph 是只读的 openCypher 子集(README.md):

  • 子句MATCHOPTIONAL MATCH、多 MATCHWHEREWITH(含 WITH … WHERE)、RETURNORDER BYSKIPLIMITDISTINCTUNWINDUNION / UNION ALLCASE
  • 模式:带标签节点、标签交替 (n:A|B)、关系类型/方向、变长路径 [*1..3]、内联属性 map。
  • WHERE= <> < <= > >=AND/OR/XOR/NOTINCONTAINSSTARTS WITHENDS WITHIS [NOT] NULL、正则 =~、标签测试 n:Label,以及 EXISTS { (n)-[:TYPE]->() }(单跳存在性——非常适合死代码判定,例如 WHERE NOT EXISTS { (f)<-[:CALLS]-() })。
  • 聚合count(含 DISTINCT)、sumavgminmaxcollect
  • 函数labelstypeidkeyspropertiestoLower/toUpper/toString/toInteger/toFloat/toBooleansizelengthtrim/ltrim/rtrimreversecoalescesubstringreplaceleftright

子集之外的一切(写类/MERGE/CALL 子句、不支持的函数、list/map 字面量、comprehension、路径函数、参数)都以明确的 unsupported … 错误失败而非返回空结果。这一“明确报错”的约定在 src/cypher/cypher.c 的一连串 "unsupported Cypher feature: …" 分支里得到印证——包括 CREATE/DELETE/SET/REMOVE/MERGE/YIELD/CALL/FOREACH 等写操作与存储过程全部拒绝;src/cypher/cypher.c 还显示 EXISTS { … } 仅接受单跳锚定形式,其他形态给出明确的 unsupported EXISTS pattern 错误。

CLI 模式:不启动 daemon 的一次性命令

每个 MCP 工具都可以作为本地一次性命令调用(README.md)。CLI 工具既不启动也不连接协调 daemon,不留常驻进程;只在命令生命周期内持有 crash-safe 的 exact-build 准入租约。index_repository 是唯一内部例外:它会启动一个临时的 exact-build 受监督 worker 执行索引,命令退出前停止该 worker。修改图谱数据的命令使用共享的 OS 级 per-project 锁,串行化同项目上 CLI 与 MCP 会话的冲突写,同时允许无关项目并行推进。

输出语义值得注意:stderr 是交互终端时 CLI 自动显示生命周期与索引进度;--progress 强制在 stderr 被重定向/非交互时显示同样反馈;--quiet 关闭自动终端进度与常规诊断但保留错误,且不能与 --progress 或外层 cli --verbose 组合。stdout 只保留命令结果。读类工具默认返回 compact tree;可用工具的 --format json 拿机器可读 payload JSON,或用外层 --json 拿完整 MCP envelope。

README 给出的一组可直接复制的示例(list_projects 返回的 name 字段就是后续 --project 的参数值):

codebase-memory-mcp cli index_repository --repo-path /path/to/repo
codebase-memory-mcp cli list_projects

codebase-memory-mcp cli search_graph --project my-project --name-pattern '.*Handler.*' --label Function
codebase-memory-mcp cli trace_path --project my-project --function-name Search --direction both
codebase-memory-mcp cli query_graph --project my-project --query 'MATCH (f:Function) RETURN f.name LIMIT 5'

# 强制显示人类可读进度而不污染 stdout
codebase-memory-mcp cli --progress index_repository --repo-path /path/to/repo
# 抑制自动终端进度与非错误诊断
codebase-memory-mcp cli --quiet list_projects --format json
codebase-memory-mcp cli search_graph --project my-project --label Function --format json
codebase-memory-mcp cli list_projects --format json --detail stats | jq '.projects[].name'

带参数的工具也支持 JSON 从 stdin 管道输入;而 list_projects 这类 input schema 声明无参数的工具永不读 stdin,因此在继承一个永不关闭的管道时仍保持响应(这是 child_process.spawn 等包装器的默认行为)。行内 JSON 出于向后兼容仍被接受,但 README 声明已弃用,推荐 flags、--args-file 或 stdin。参数解析优先级在 src/main.c 的注释里写得很清楚:--args-file → 原始 JSON(back-compat)→ flags → 管道 stdin → 空 {}。输出还有一层模型无关的省 token 机制:只有当完整渲染表格至少缩小 15% 且 ≥64 字节、且保守的模型无关 token 形状代理至少改善 1% 时,才启用 <section>_refs 前缀压缩等紧凑形态,两个 gate 都是确定性的。

搜索能力分层:BM25、语义与结构化

README 的 Search 章节 把搜索拆成三层,并明确各自的实现细节:

  • Semantic search(semantic_query:对整张图做向量检索,embedding 由打包进二进制的 Nomic nomic-embed-code(40K tokens、768d int8)驱动——无需 API Key、Ollama 或 Docker。README 列出 11 信号组合打分:TF-IDF、RRI、API/Type/Decorator 签名、AST profiles、数据流、Halstead-lite、MinHash、模块邻近度、图扩散等。
  • BM25 全文搜索:SQLite FTS5 之上用 cbm_camel_split tokenizer(camelCase/snake_case 感知)。这可以在源码中直接证实:src/store/store.c 实现了该 splitter(发出原始标识符加空格分隔的拆分版本,使 FTS5 能命中 camelCase 边界),并在 src/store/store.c 以 SQLite 自定义函数注册;src/store/store.c 的注释还说明表是 contentless(content='')FTS5,只存倒排索引。
  • Structural search(search_graph:正则名字模式、标签过滤、min/max 度、文件范围限定。
  • Code search(search_code:仅在被索引文件上的“图谱增强版 grep”。README 说明其分页为 ranked rows 用 result_limit/result_offsetlimit 是兼容别名)、raw rows 用 raw_limit/raw_offset、目录摘要用 directory_limit/directory_offset;原始行默认返回 UTF-8 安全、以匹配为中心的预览,每行报告 content_start_byte、返回/总字节数、已知时的匹配字节界与内容续读偏移。

团队共享图谱工件:一个文件跳过多地重索引

把单个压缩文件提交进仓库,团队成员克隆后即可跳过全量重索引(README.md)。

.codebase-memory/graph.db.zst 是图谱的 zstd 压缩快照,与源码放在一起。你索引时工件被写入/刷新;队友克隆仓库并首次运行 CBM 时,工件先被解压、再做增量索引补齐其本地 diff。

  • 格式:SQLite 数据库,去索引后用 VACUUM INTO 压缩,再经 zstd 1.5.7 压缩(典型 8–13:1)。

  • 两层导出Bestzstd -9 + 去索引 + VACUUM INTO)——显式 index_repository 时写入;Fastzstd -3)——watcher 为低延迟增量更新而写。

  • 引导:本地无 DB 但工件存在时,index_repository 先导入工件再做增量索引,避免全量成本。

  • 无合并之痛:首次导出时自动创建 .codebase-memory/.gitattributesmerge=ours 行,并发编辑不会在二进制工件上产生冲突。

  • 刻意提交:工件每次索引都被重写(含 watcher 的 Fast 层),git 会把每次重写存成新 blob。README 记录了一个真实教训:某团队在约 350 次提交中把单个 20 MB 文件撑到约 6 GB 历史。请选节奏(release、milestone、nightly job)而不是每次保存都提交。

  • 如需 Git LFS:在仓库根 .gitattributes 里跟踪(靠更近的文件继续提供 merge=ours,只有 filter 来自根文件):

    .codebase-memory/graph.db.zst filter=lfs diff=lfs merge=lfs -text
    

    只跟踪 .zstartifact.json 很小并携带 schema 版本。该属性只作用于未来提交——历史里已有 blob 的仓库需先用 git-filter-repo 重写。代价权衡:GitHub 对 LFS 存储与带宽计费、对象无法自行裁剪;每位队友都需要 git lfs install,否则 checkout 留下的是指针文件,完整性校验的导入会拒绝它并回退到全量重索引。

  • 可选:不想要就永不提交——把 .codebase-memory/ 加入 .gitignore,让所有人从头重索引即可。

Hybrid LSP:超越 tree-sitter 的类型解析层

tree-sitter 只给语法 AST——它擅长命名、结构与调用位,但无法告诉你 user.profile.display_name() 解析到三模块之外声明的 Profile.display_name,因为它不追踪 import、泛型、继承或 stdlib 类型。CBM 因此在每个 parse 之上叠加了一层用轻量 C 实现、结构上受主流 language server 启发并兼容的类型解析算法层,直接嵌入原生可执行文件,无需 language server 进程、无需 per-project 配置、无需 API Key(README.md)。这一层对调用解析(CALLS / RESOLVED_CALLS)与可调用值解析(CALL_REFERENCE,歧义值保留为 USAGE)做精化,使产出图谱尽量接近 IDE “Go to Definition” 的结果。

README 的 Hybrid LSP 语言矩阵完整继承如下:

语言 处理内容
Python imports + dotted submodule walks、dataclasses、Self 返回类型、泛型、@propertymatch/case 类模式、SQLAlchemy 2.0 Mapped[T]、Pydantic BaseModeltyping.Annotated/ClassVar/Final/InitVar、async/await、classmethod/staticmethod、窄化(isinstance/is not None/walrus)、typing.cast/assert_type、常见 stdlib(logging、pathlib、json、functools)。README 报告惯用代码上的目标分辨率约 95%。
TypeScript / JavaScript / JSX / TSX 泛型、JSX 组件分派、纯 JS 的 JSDoc 推断、.d.ts 声明、模块再导出、经返回类型传播的方法链、叠加到共享跨文件注册表上的 per-file overlay
PHP 命名空间、trait、late-static-binding、PHPDoc 推断、参数绑定、返回类型推断
C# global usings、file-scoped 命名空间、records(含 C# 12 主构造函数)、LINQ 方法语法、async Task<T>/ValueTask<T> 解包、泛型方法、this/base 分派、var 推断、常见 BCL stdlib
Go 预构建 per-package 跨文件注册表、泛型、内嵌 struct、interface 满足、包感知 import 解析
C / C++ C/C++ 共享的预构建跨文件注册表;C 侧处理宏 + typedef 链 + 头文件对源文件链接;C++ 侧处理模板、命名空间、auto 推断、经类层次的方法解析
Java imports(single-type、on-demand、static)、带 this/super 分派的类层次、泛型、注解、按元数与参数类型做重载匹配、绑定到函数式接口的 lambda/方法引用、字段类型推断、常见 JDK stdlib
Kotlin imports + 同包解析、classes/objects/companion objects、扩展函数、data classes、可空类型解包、作用域函数(let/apply/run/also/with)、infix 调用、常见 stdlib
Rust use 声明 + 模块路径、impl 块与 trait 方法、struct 字段、带 trait 界的泛型、operator-trait 去糖、derive-macro 方法合成、UFCS 静态路径、常见 std prelude
Perl packages + @ISA/use parent/use base 继承(method-resolution-order 分派)、SUPER:: 调用、Exporter(use Foo qw(...))导入映射、bless/`ref($class)

两层架构:第一层 tree-sitter pass 对所有 162 语言运行(快、纯语法,提取定义/调用/import);第二层 Hybrid LSP pass 按语言叠加(类型感知,用 import 图加 per-file 或预构建跨文件定义注册表精化调用边)。尚无 Hybrid LSP pass 的语言回退到文本解析——你总会拿到某种答案。README 声称其结果图足够支撑 trace_path 跨包、继承层次与 stdlib 调用,而不必为每个项目支付一个 language server 进程的代价。

忽略文件:.cbmignore 的分层优先级

索引忽略采用分层模型:硬编码模式(.gitnode_modules 等)→ .gitignore 层次 → .cbmignore(项目专属,gitignore 语法)。symlink 永远跳过。.cbmignore 只读自被索引目录的根<repo>/.cbmignore),子目录里的嵌套 .cbmignore 不会被读取;它作用于文件发现阶段,因此初始 index_repository、手动重索引与后台 auto-sync 走的是同一次发现,被匹配的路径永不进图,改动在下次(重)索引生效(完整语法与优先级见 docs/cbmignore.md)。

语法速览(gitignore 风格):* 匹配除 / 外任意字符序列;? 恰好一个非 / 字符;** 跨目录(**/namedir/**a/**/b);[abc]/[a-z] 字符类([!a-z]/[^a-z] 取反);尾部 / 只匹配目录;其余 / 把模式锚定到仓库根;无 / 则按名字在任意深度匹配;前导 ! 取反(最后匹配者胜)。目录的发现顺序为:内置跳过表(.gitnode_modulesdisttargetvendor、工具缓存等 60+ 名字,不可取反的安全核心是 .gitnode_modules.worktrees.claude-worktrees)→ 仓库 .gitignoreinfo/exclude → 嵌套 .gitignore.cbmignore → git global excludes。文件级的内置后缀过滤器与文件大小上限不可被 .cbmignore 覆盖。要验证效果:发现期跳过的子树会出现在 index_repository 响应的 excluded 字段中({"dirs": [至多 25 个路径], "count": <总数>, "truncated": <bool>})。

更新、卸载与诊断

更新在任何平台都由安装脚本执行,而不是运行中的二进制自查。codebase-memory-mcp update 校验 flags 后打印要执行的精确命令:

# macOS / Linux
bash "<install-dir>/install.sh"
# Windows
powershell -ExecutionPolicy Bypass -File "<install-dir>\install.ps1"

安装脚本在安装时被放到二进制旁,因此打印的路径总能解析到可执行文件旁边;脚本幂等,重复运行就是更新——停 daemon、退役旧二进制、装新二进制、清理。README 解释原因:Windows 上运行中的可执行文件无法自我替换(swap 必须由非目标进程执行);macOS/Linux 上是刻意选择——进程内 updater 本质是下载器,为一个人几个月跑几次的命令在每个二进制里内置一套“抓包→校验→解包→置执行位→运行”组合并不划算。发布归档不含任何下载 URL,CBM 自身不会主动发起任何网络请求——不后台查新版本、不打电话回家,版本信息来自安装脚本、包管理器或 GitHub。

卸载

codebase-memory-mcp uninstall

移除其拥有的 Agent 配置项、skills、hooks、instructions 与已安装二进制;已有图索引被列出且仅在你确认后删除。二进制旁的安装脚本被报告而不被删除——uninstall 会打印它的路径与 rm 命令。故意不动它:它可能是你自己的副本、指向 checkout 的 symlink、或由包管理器管理,卸载器不应删除无法证明是自己拥有的文件。

诊断(README 的 Troubleshooting & Diagnostics):CBM 100% 本地运行、零遥测。当遇到仓库方无法复现的问题(数小时的缓慢内存爬升、性能回归、只有真实使用几天才出现的泄漏)时,你需要自己抓取证据。在首个 daemon 支撑的 MCP 会话开始前设 CBM_DIAGNOSTICS=1,然后复现问题;daemon 从启动它的会话捕获该设置,若已在运行需先关闭所有 daemon 会话。daemon 会在系统临时目录(macOS/Linux 的 $TMPDIR//tmp,Windows 的 %TEMP%)下建一个新的 owner-private cbm-diagnostics-<pid>-<random> 目录,确切路径记录在 ${CBM_CACHE_DIR}/logs/cbm-daemon.logdiagnostics.start 事件中:

文件 是什么
trajectory.ndjson 内存轨迹——每 5 秒一行 JSON,含 rsscommitted(Windows commit charge)、peak_*page_faultsfdqueries内存/泄漏报告需要的就是它——随时间变化的趋势才能定位泄漏。服务退出后仍保留(可事后取走),超过约 8 MB 轮转到 trajectory.ndjson.1
snapshot.json 仅最新快照——方便快速实时检查;干净退出时被移除。

开 issue 时附上 .ndjson 轨迹即可——它不含源码与查询文本,只有资源计数器;也可直接把内容(或 Agent 对它的总结)贴进 issue,因为助手可以直接读 NDJSON 并报告 rss/committed 是否单调增长、增速多少、相对查询数的关系。

性能参照与常见排障速查

README 的性能表(README.md)基于 Apple M3 Pro 测量,数字如下,精确复现需原始输入与产物:

操作 时间 备注
Linux kernel 完整索引 3 min 28M LOC、75K 文件 → 4.81M 节点、7.72M 边
Linux kernel fast 索引 1m 12s 1.88M 节点
Django 完整索引 ~6s 49K 节点、196K 边
Cypher 查询 <1ms 关系遍历
名字搜索(正则) <10ms SQL LIKE 预过滤
死代码检测 ~150ms 带度过滤的整图扫描
追踪调用路径(depth=5) <10ms BFS 遍历

README 的排障速查表也值得完整保留(README.md):

问题 修复
/mcp 不显示服务器 检查 .mcp.json 路径是绝对路径。重启 Agent。自测:echo '{}' | /path/to/binary 应输出 JSON
index_repository 失败 传绝对路径:index_repository(repo_path="/absolute/path")
trace_path 返回 0 结果 先用 search_graph(name_pattern=".*PartialName.*") 找到确切名字
查询返回错误的项目结果 project="name" 参数;用 list_projects 看名字
安装后找不到二进制 加入 PATH:export PATH="$HOME/.local/bin:$PATH"
UI 不加载 确认执行过 --ui=true;检查 http://localhost:9749

从数据模型到发布安全:源码地图与信任链

把 README 的各功能点落回源码,可以得到一张可继续深挖的“功能 → 文件”对照表(README 的 Architecture 章节 与目录一一对应):

README 功能点 源码位置
入口:MCP stdio server、CLI、install/update/config、UI 开关 src/main.c
MCP server(工具注册、session 检测、auto-index、agent profile 白名单) src/mcp/mcp.c
安装与 45 客户端表面、Scout/Verify/Auditor 分层 src/cliagent_profiles.ccli.c
SQLite 图谱存储、BM25/FTS5 与 cbm_camel_split src/store/store.c
多趟索引(结构 → 定义 → 调用 → HTTP 链接 → 配置 → 测试) src/pipeline
openCypher 子集词法/语法/规划/执行 src/cypher/cypher.c
文件发现(.gitignore/.cbmignore/symlink 处理) src/discover
后台 auto-sync(git 轮询、自适应间隔) src/watcher/watcher.c
会话协调 daemon、IPC、生命周期、共享任务 src/daemon
运行时 trace 摄入 src/traces/traces.c
本地 HTTP 服务器 + 校验过的 3D UI 资产包 src/uigraph-ui
vendored tree-sitter 文法与 AST 提取 internal/cbm

在发布与信任层面,README 声明每版 release 都经过多层验证管线(README.md,细节与证据见 SECURITY.md):所有 24 个可执行候选(unstripped、debug-stripped、stripped)× 八个发布产品在 smoke/soak 前提交 VirusTotal 扫描;选中的可执行文件打包时 SHA-256 不变,release notes 链接与所发字节完全一致的 verdict,并随 release 以 TSV 发布逐候选证据。此外还有 SLSA Level 3 构建溯源(gh attestation verify)、Sigstore cosign 无密钥签名、checksums.txt SHA-256(两个安装脚本解压前都校验)、CodeQL SAST 门禁,以及“无语言运行时依赖链”。所有组件(install.shinstall.ps1LICENSETHIRD_PARTY_NOTICES.md、MCPB manifest.json、解包的 UI 资产)也都被逐一扫描。仓库根目录另见 SECURITY.md(漏洞上报与发布策略)、CONTRIBUTING.mdscripts/security-*.sh 系列审计脚本,以及 scripts/audit-license-provenance.py 等许可审计入口。

结语:一次索引,多次省心

codebase-memory-mcp 的核心主张可以浓缩为一句话:让“每次会话都从零 grep 代码库”变成“一次索引、持续查询一张结构化图谱”。它把 tree-sitter 的文法广度、Hybrid LSP 的类型深度、SQLite/FTS5 的检索能力与 zstd 的压缩分发压缩进一个无运行时的原生二进制,通过 MCP 协议把 15 个结构化查询工具交给任意 Agent。快速验证路径是:按上文任一方式安装 → 重启 Agent → “Index this project” → 用 get_graph_schema 起步、用 search_graph 找符号、用 trace_path 追调用、用 query_graph 做自定义图查询;进阶路径则是配置 auto_index 与 watcher、用 .cbmignore 塑形发现范围、以 CBM_* 环境变量约束资源与安全边界、再提交 .codebase-memory/graph.db.zst 让整个团队共享同一份图谱。

本文所有可量化性能与覆盖率数字均引自 README.md,它们带有 README 中声明的测量前提(如 Apple M3 Pro、特定语言与输入集),精确复现需要原始输入与产物;各版本间的语言计数、工具清单等措辞差异以你实际运行的二进制输出为准。仓库仅提供查看、安装、运行与配置方式,如需评估可比质量与 Agent 节省,请按 docs/MEASURING_SAVINGS.md 在自有负载上测量。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391