codebase-memory-mcp 配置完全指南:配置文件、config 子命令与运行时环境变量的实战参考
【免费下载链接】codebase-memory-mcpHigh-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 158 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.项目地址: https://gitcode.com/GitHub_Trending/co/codebase-memory-mcp
codebase-memory-mcp 是一个把代码库索引为持久化知识图谱的 MCP 服务器,它的全部可调行为——从"哪种扩展名按哪种语言解析"到"后台 watcher 是否启动、UI 是否监听端口、哪些目录被永久拒绝索引"——都由一套清晰分层的配置承载。本指南以 docs/CONFIGURATION.md 为骨架,逐文件讲解该项目的配置体系,并在每个配置项下给出源码级实现证据,帮助你掌握三类能力:用 JSON 文件自定义文件扩展名映射、用config子命令管理运行时行为、用环境变量约束沙箱边界与部署形态。
整体配置分为五条线:全局/项目级 JSON 配置文件(纯手写)、CLI 管理的 SQLite 运行时设置库_config.db、UI 设置 JSON、进程环境变量,以及install 命令写入的各 Agent/编辑器集成文件。理解它们的区别(哪些手改、哪些用命令、哪些在 daemon 启动前就定死)是正确配置的前提。
配置体系全景:一张表掌握全部配置产物
下表列出 codebase-memory-mcp 当前会读取或写入的全部配置文件(出自 docs/CONFIGURATION.md):
| 用途 | 路径 | 格式 | 说明 |
|---|---|---|---|
| 全局自定义扩展名映射 | $XDG_CONFIG_HOME/codebase-memory-mcp/config.json | JSON | 当XDG_CONFIG_HOME未设置时回退到~/.config/codebase-memory-mcp/config.json |
| 项目级自定义扩展名映射 | {repo_root}/.codebase-memory.json | JSON | 与全局extra_extensions冲突时,以项目级为准 |
| CLI 管理的运行时设置 | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/_config.db | SQLite | 由codebase-memory-mcp config set/reset写入 |
| UI 设置 | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/config.json | JSON | 存储ui_enabled与ui_port |
| Daemon 运行日志 | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/logs/cbm-daemon.log | 结构化日志 | 持久的 daemon 生命周期、watcher/索引、UI、资源与错误事件 |
| 准入冲突日志 | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/logs/daemon-conflicts.ndjson | NDJSON | 精确构建、ABI、规范化缓存根冲突记录 |
| 激活日志 | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/logs/activation-events.ndjson | NDJSON | 安装/更新/卸载激活的进度与结果 |
使用上述任一位置前,codebase-memory-mcp 都会先把CBM_CACHE_DIR解析为一个按账户规范化的单一缓存根;日志目录与日志文件对该账户私有。这正是 README 中"每个活跃 CBM 进程必须共享同一 canonical cache root,否则在 OS 准入屏障处失败并写入daemon-conflicts.ndjson"这一行为在文件系统层面的落点。
自定义文件扩展名映射:把新扩展名"讲"给语言解析器
codebase-memory-mcp 内置了大量 tree-sitter 语法,但框架特有的扩展名(例如 Laravel 的.blade.php、ES Module 的.mjs)不在任何语言的默认后缀表里。两个可选的 JSON 文件可以建立"附加扩展名 → 内置语言"的映射。
全局配置
默认路径:
$XDG_CONFIG_HOME/codebase-memory-mcp/config.json当XDG_CONFIG_HOME未设置时的回退路径:
~/.config/codebase-memory-mcp/config.json路径解析逻辑位于 src/foundation/platform.c 的cbm_app_config_dir():POSIX 上优先读取XDG_CONFIG_HOME,未设置则取$HOME/.config;Windows 上则使用%APPDATA%(回退到~/AppData/Roaming)。
项目级配置
将下面这个文件放在仓库根目录即可:
.codebase-memory.json配置格式
两个文件使用完全相同的结构,唯一的键是extra_extensions:
{ "extra_extensions": { ".blade.php": "php", ".mjs": "javascript", ".twig": "html" } }规则细节
- 扩展名键必须包含前导点(例如
.mjs而不是mjs)。 - 语言名不区分大小写(
PHP、Php、php等价)。 - 无法识别的语言名会被静默跳过(fail-open,不会中断索引)。
- 配置文件缺失时被忽略(全局文件与项目文件都如此)。
- 若同一个扩展名同时出现在两个文件中,项目级文件胜出。
这套校验规则在 src/discover/userconfig.c 的parse_extra_extensions()中逐条落地:ext_str[0] != '.'触发userconfig.skip_bad_ext警告;语言名先整体小写化再查表,查不到则记录userconfig.unknown_lang并跳过;extra_extensions键缺失或类型错误都只打警告不报错。注意该函数同时拒绝非字符串的值与过大的配置文件(MAX_CONFIG_SIZE = 65536,见 src/discover/userconfig.c),损坏的 JSON 也走 fail-open 路径。
源码纵深:两级配置的加载与合并
真正完成"全局 + 项目 + 去重合并"的是cbm_userconfig_load()(src/discover/userconfig.c),实现与文档描述完全一一对应:
- 加载全局文件:路径为
cbm_app_config_dir()/codebase-memory-mcp/config.json; - 加载项目文件:仅当传入的
repo_path非空时读取{repo_path}/.codebase-memory.json; - 去重:项目条目总是追加在全局条目之后,随后对每个项目条目扫描全局段,若扩展名相同则删掉对应全局条目——这就是"per-project wins"的确切语义。
实现中还有几个值得注意的细节:每条记录除扩展名外还携带解析出的CBMLanguage枚举(src/discover/userconfig.h);两个配置源的字节内容会各自计算 SHA-256 摘要存入global_source_sha256/project_source_sha256,用于精确判断配置是否发生过变化;语言名字符串→枚举的转换由一张覆盖约 70 个名字与别名的小表完成(src/discover/userconfig.c),因此除了cpp/csharp这类别名,terraform也会被归一到hcl、sh会被归一到bash。
最终,进程通过cbm_set_user_lang_config()注册这份合并结果,文件发现流程在查询内置后缀表之前先咨询它(src/discover/userconfig.h),这正是"映射优先于内置默认"的实现机理。对应的行为契约测试可参考 tests/test_userconfig.c。
CLI 管理的运行时设置:config子命令
需要"读写后再由长驻进程生效"的行为参数不适合用 JSON 手改,codebase-memory-mcp 把它们收进一个小的 SQLite 数据库:
${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/_config.db数据库路径由cbm_resolve_cache_dir()(src/foundation/platform.c)决定:优先取CBM_CACHE_DIR环境变量,未设置则回退到~/.cache/codebase-memory-mcp。
常用命令
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 watcher_enabled false codebase-memory-mcp config reset auto_indexlist打印全部键值;get <key>读取指定键(键未设置时返回其真实默认值,而非空串);set <key> <value>写入;reset <key>恢复默认。命令入口位于 src/cli/cli.c 的cbm_cmd_config(),其中list/get/set/reset四个子命令共享同一张CONFIG_KEYS定义表(src/cli/cli.c)——注释明确指出,这是为了避免历史上config list与config get因默认值回退不一致而造成的键值错觉(issue #1522)。
当前支持的键
| 键 | 默认值 | 含义 |
|---|---|---|
auto_index | false | MCP 会话启动时自动索引新项目。 |
auto_index_limit | 50000 | 允许对新项目自动索引的最大文件数。 |
auto_watch | true | 会话连接时将本会话项目注册给后台 git watcher。设为false可让会话不注册项目(watcher 仍为其他项目运行)。 |
watcher_enabled | true | 后台 watcher 子系统的总开关。设为false后 watcher 完全不启动——没有轮询线程,也没有项目注册。禁用时需用index_repository手动重建索引。 |
watcher_enabledvsauto_watch二者易混但语义不同。watcher_enabled决定 watcher子系统是否启动(后台轮询线程是否存在);auto_watch更窄,只决定"某个连接中的会话是否把自己的项目注册给已运行的 watcher"。当watcher_enabled=false时,auto_watch形同虚设——因为根本没有 watcher 可供注册。两者的读取时机也不同,而这正是它们行为差异的关键。watcher 存活于后台 daemon 中而不是你的 MCP 客户端里:
auto_watch在每次会话准备注册项目时被查询,因此改动对之后连接的会话立即生效;watcher_enabled在daemon 启动时读取一次,因为它决定 watcher 是否被构建。daemon 是长驻的,生命周期远超单个 MCP 会话,因此仅仅重连你的客户端是不够的——需要让 daemon 退出,使下一个 daemon 读到新值:codebase-memory-mcp config set watcher_enabled false codebase-memory-mcp daemon stop # 下一次会话将启动一个不带 watcher 的 daemon codebase-memory-mcp daemon status # 确认关闭 watcher 不影响其他功能:daemon 照常启动,
auto_index依然执行,index_repository仍可用于手动重建索引。
值得一提的是,CONFIG_KEYS表中还登记着ui_lang(默认auto,可选en/zh/auto)、ui_enabled、ui_port三个键。它们在config list中一并显示,但cbm_cmd_config()会通过config_key_is_ui()判断——UI 系列键被路由到下方的 UI 配置文件(config_ui_write/config_ui_read)而非_config.db,并在config set后提示"(restart the daemon for this to take effect)"(src/cli/cli.c)。也就是说,config子命令其实横跨了两个存储:大多数行为键写入 SQLite,UI 键写入 UI JSON。
内置图形 UI 设置
可选的图可视化 UI 把设置存放在:
${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/config.json当前格式:
{ "ui_enabled": false, "ui_port": 9749 }使用要点:
- 如果某个启用 UI 的二进制在首次运行时找到了已验证的外部资源包、且尚无 UI 配置文件,UI 会自动启用;资源缺失或无效时,MCP/daemon 服务保持可用而 UI 保持禁用。
CBM_CACHE_DIR会同时改变 UI 配置文件与运行时设置数据库的位置。- codebase-memory-mcp 会把
CBM_CACHE_DIR解析为唯一的按账户规范化缓存根;当任何 CBM 会话或命令处于活跃状态时,使用不同根的进程会被拒绝——切换缓存根前请先关闭全部相关会话。
启动方式与默认端口在 README 的 Graph Visualization UI 一节也有呼应:codebase-memory-mcp --ui=true --port=9749后访问http://localhost:9749,UI 由共享协调 daemon 持有,多个并发 Agent 会话不会各自启动重复的 HTTP 服务(参见 README.md)。在 UI 键这一侧,默认端口9749与 CLI 管理的设定值在CONFIG_KEYS中保持一致(src/cli/cli.c)。
环境变量:运行时行为的系统级开关
以下环境变量会影响运行时行为(变量取值在进程启动时被读取,部分只在 daemon 启动时读取一次,详见后文):
| 变量 | 默认值 | 说明 |
|---|---|---|
CBM_ALLOWED_ROOT | (未设置) | 把index_repository限定在该目录内。设置后,凡是repo_path经符号链接 /..解析后落到此根之外的请求都会被拒绝;且同一检查现在同样作用于图 UI 的POST /api/index路由,而不再只针对 MCP 工具。未设置时不施加"围栏"限制——但下方"始终拒绝的根"是常开的,无论是否设置都生效。适用于服务器可能被不可信调用方驱动的场景,例如 agentic 或多租户部署。 |
CBM_CACHE_DIR | ~/.cache/codebase-memory-mcp | 覆盖索引、_config.db与 UIconfig.json使用的缓存目录。 |
CBM_DIAGNOSTICS | false | 在系统临时目录下一个全新的、属主私有的随机目录里启用周期性的snapshot.json与保留的trajectory.ndjson。daemon 会把随机路径记录在${CBM_CACHE_DIR}/logs/cbm-daemon.log的diagnostics.start发现记录(单行 JSON)中;即便CBM_LOG_LEVEL抑制了常规日志,这条记录也会发出,以保证路径始终可被找到。 |
CBM_DOWNLOAD_URL | GitHub releases | 覆盖更新下载 URL(用于测试或自托管部署)。 |
CBM_LOG_LEVEL | 角色相关 | 设置日志级别为debug、info、warn、error、none(或0–4)。瘦 MCP/CLI/hook 前端默认warn;脱离终端的 daemon 与受监督的索引 worker 默认info。物理 worker 保留 INFO liveness 记录,因为其私有日志驱动 supervisor 的"无进度超时"判定。前端消息走该会话的 stderr;脱离终端的 daemon 事件写入${CBM_CACHE_DIR}/logs/cbm-daemon.log。 |
CBM_RUNTIME_DIR | %LOCALAPPDATA%(Windows)、/private/tmp(macOS)、/tmp(其他) | daemon/CLI rendezvous 目录的父目录,CBM 会在其下创建cbm-daemon-<uid>(Windows 上为cbm-daemon-<key>)。当默认路径的祖先链无法通过私有目录检查时设置它——见下文。CBM_CACHE_DIR不会移动 rendezvous。 |
CBM_WORKERS | 自动探测 | 覆盖索引 worker 数量。 |
CBM_ALLOWED_ROOT在 MCP 工具与 UI 两条路径上都生效的证据:决策本身收敛在一处,MCP 侧读取会话策略或回退到进程环境变量(src/mcp/mcp.c),HTTP 侧在POST /api/index处理时把环境值传入同一判定函数(src/ui/http_server.c)。
重定位 daemon rendezvous 目录
在使用前,rendezvous 目录及其每一级祖先都会接受检查:每个祖先必须属于你或 root、不得对世界可写(除非它是标准的 root 属主 sticky 目录,如/tmp)、不得携带 allow-ACL——在 Windows 上即不得有授予其他身份变更权限的 ACE。rendezvous 目录本身随后被强制为仅属主(0700,无扩展 ACL / 仅属主的 DACL)。
默认位置并非总能通过这条祖先链。例如 Windows 用户配置文件因某个已安装的打包应用而在%LOCALAPPDATA%上带上了具有WRITE_DAC/WRITE_OWNER/DELETE的 capability-SID ACE,就会让遍历失败;POSIX 上不寻常的/tmp或 home 目录也可能触发同样问题。此时每条命令都会失败,包括config list,连设置界面也无法触达:
codebase-memory-mcp: secure daemon endpoint could not be createdCBM_RUNTIME_DIR可以把 rendezvous 指向你选定的祖先链:
export CBM_RUNTIME_DIR="$HOME/cbm-runtime" # 任意你拥有的目录$env:CBM_RUNTIME_DIR = "D:\cbm-runtime"注意:检查不会因你指定了目录而放宽——它会经历与默认路径完全相同的校验,不满足条件的值会被拒绝而非静默忽略。由于 rendezvous 是各会话互相发现的媒介,所有需要共享同一个 daemon 的进程必须看到相同的值:请在 MCP 客户端和你的 shell 环境中同时设置,否则未带该变量的 CLI 调用会经由默认位置去协调。
daemon 拥有的环境:从"第一个 daemon 会话"捕获
diagnostics、daemon 日志、进程级索引资源上限等 daemon 所拥有组件使用的环境,是从启动 daemon 的第一个 daemon-backed 会话处捕获的。之后的会话加入既有进程,无法替换这些值。要修改它们,需要:关闭所有 daemon-backed 会话 → 一致地更新相关 Agent 配置 → 重新启动一个会话。在这一规则下:CBM_ALLOWED_ROOT保持会话级独立;冲突的CBM_CACHE_DIR会被拒绝;一次性 CLI 命令使用自己的当前环境、且不会启动 daemon。
始终被拒绝的根目录
与CBM_ALLOWED_ROOT是否设置无关,下面这些目录作为整体索引根会被直接拒绝,因为它们过于宽泛或过于敏感:
- 文件系统根、Windows 驱动器根或 UNC 共享根;
- 顶层系统树——
/etc、/var、/usr、/home、/Users,Windows 上的C:\Windows、C:\Users、C:\ProgramData、C:\Program Files; - home 目录本身(其下级目录不受影响);
- 任意深度出现的凭据目录——
.ssh、.aws、.gnupg、.kube、.docker、.netrc、.git-credentials、.password-store、macOSKeychains。
有两点必须说清:第一,这约束的是范围而非敏感性——在一个被允许的根内部,进程能读到的每个文件都可能被索引并在之后被返回;第二,凭据名单是一个denylist(黑名单),它提高的是"犯错成本"而不是关闭整个错误类别——名单上没有点名的目录仍被允许。
这些规则在 src/foundation/workspace.c 的cbm_workspace_classify_root()中有完整实现。实现细节与文档表述逐条对应:
- 凭据名按路径的每个分量匹配(
ws_any_component_matches),所以…/.ssh和…/.ssh/sub都会被拒;Windows 上比较不区分大小写,.SSH无法漏过(src/foundation/workspace.c)。实际名单比文档示例更长:还包含.gpg、_netrc、.azure、.gcloud、.authinfo(src/foundation/workspace.c)。 - Windows 系统树(
Windows、ProgramData、Program Files、Program Files (x86))只作为驱动器下第一个分量匹配,避免把合法项目误伤(src/foundation/workspace.c)。 - home 目录判定在缓存目录判定之前执行——因为 home 通常包含缓存目录,若顺序颠倒,所有
$HOME都会被误报为"持缓存"而变为绝对拒绝(src/foundation/workspace.c)。
Agent 与编辑器集成文件:用install --dry-run安全预检
install命令除了放置二进制,还会把 MCP 条目与指令块写入 Claude Code、Codex、Gemini、VS Code、Cursor、Zed 等 Agent/编辑器的配置文件。这些目标路径随工具与平台而变,因此最稳妥的检查方式是干跑:
codebase-memory-mcp install --dry-run它会打印安装器将要修改的具体配置文件,而不写入任何东西。这与源码中的实现一致:install 路径通过统一的计划对象支持干跑,--dry-run贯穿技能安装、hook 脚本、子 Agent 配置等全部写入点(参见 src/cli/cli.c 中dry_run参数的透传,以及 src/cli/cli.c 对g_install_plan干跑模式的注释)。在真正把install跑在生产环境前先执行一次--dry-run,是核对"会改哪些文件"的最直接手段。
结语:把配置分层当作系统设计来理解
回看整个配置面,codebase-memory-mcp 的设计取舍清晰可辨:人工书写量大的地方用 JSON(扩展名映射),需要编程读写与默认值回退的地方用 SQLite(运行时行为键),与进程启动时机强耦合的地方用环境变量(缓存根、围栏、日志级别、rendezvous),需要审计与回滚的地方留日志(daemon 事件、准入冲突、激活事件)。尤其要记住两条时间线:watcher_enabled、CBM_DIAGNOSTICS这类"daemon 拥有"的设置只在 daemon 启动时被捕获一次,改后必须daemon stop再重连;而auto_watch、CBM_ALLOWED_ROOT这类会话级设置在每次会话建立时读取。前者决定了行为"何时生效",后者决定了行为"对谁生效"——把这两条时间线分清,绝大多数"改了配置却不生效"的困惑都能自行解开。
需要进一步深入时,可在本仓库继续阅读:docs/cbmignore.md(忽略文件分层与.cbmignore语法)、README.md(配置命令速查与完整环境变量对照)、src/foundation/workspace.c(拒绝根判定)、src/discover/userconfig.c(扩展名映射加载/合并),以及 docs/MEASURING_SAVINGS.md(在自有工作负载上度量质量、延迟与 Agent 节省)。配置服务于索引能力本身——想要获得可复现的度量口径,建议在调整完上述任意配置后,用该文档中的方法记录一组基线再做对照实验。
【免费下载链接】codebase-memory-mcpHigh-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 158 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.项目地址: https://gitcode.com/GitHub_Trending/co/codebase-memory-mcp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考