关于 calm-mcp
calm-mcp 是面向编码 Agent 的 MCP 服务,提供基于调用图的实时代码库视图。它结合置信度分级的依赖关系、哈希与语法验证写入,以及高风险修改的确认门槛。
主要功能
- 01实时调用图与导入图
- 02查看调用方与被调用方
- 03哈希与语法验证写入
- 04高风险修改确认门槛
- 05代码库健康度报告
- 06跨会话决策记忆
适用场景
- 01修改函数前检查调用方
- 02保护高调用量符号的修改
- 03在 CI 中跟踪代码库健康度
MCP 相关
它向 MCP 客户端提供代码库索引、导航、编辑和健康度报告能力。它支持使用 stdio 的客户端,也可为远程开发选择 HTTP 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
40收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| tx_ids | array | 是 | 从一组 edit_lines/edit_symbol/format_files 响应中收集的 tx_ids,这些响应共同构成了一次多文件更改。 |
详细介绍
CALM — 编码 Agent 活跃度地图
一张实时、经图验证的代码库地图——让 AI 编码 Agent 看清代码后再编辑,而不是在黑暗中用 grep 摸索。
真实调用图,而非基于向量相似度的猜测。只要有编译器可用,就使用经编译器验证的边。在写入路径本身设置严格的安全门,而不只是给出 Agent 可以随手略过的警告。本 README 中经测量的结论,要么基于当前 CALM 快照,要么基于基准测试产物;具体仓库的数值会随着代码库变化而改变。
初次接触? 快速开始 不到一分钟即可运行——无需克隆仓库或安装 Rust 工具链,适用于 Claude Code、VS Code、Cursor、Windsurf/Devin Desktop、Codex、Antigravity 和 JetBrains。正在比较此类工具? 直接跳到证据胜于承诺。想了解内部实现? docs/architecture.md 全面介绍多层索引、SCIP/LSP 覆盖系统、并发模型和净化层。
| 覆盖范围 | 解析 24 种语言 · 默认支持 13 种语言的完整调用图(6 种开箱即用 + 通过默认 tier0-5 套件额外支持 7 种)· 12 种语言在提供程序/工具链可用时有正式的、经编译器验证的升级路径 |
| 安全性 | 在已发布的五个服务基准测试中,唯一会拒绝对已验证枢纽符号进行未经确认编辑的工具 |
| 效率 | 相较于朴素的逐文件读取基线,针对具体任务节省了令牌;请参阅基准测试产物 |
问题
如果 AI Agent 在编辑代码时不了解即将修改的函数有哪些调用方,那么迟早会:
- 删除“死代码”,而其他十几个文件仍在调用它。
- 修改签名,却遗漏一半的调用位置。
- 重构一个它以为无关紧要的符号——直到构建失败后才发现,它是整个模块所依赖的枢纽。
这些都不是推理能力不足,而是可见性不足:Agent 从未拥有一张地图。给它一张,猜测便会停止。
为什么叫 “CALM”
大多数编码 Agent 的工作方式,就像任何人在陌生代码库中只用 grep 一样:不知道代码之间如何关联,也无法判断改动某个函数是否会影响另外十四处。这不是自信,而是快速猜测。
CALM 是 Coding Agent Liveness Map(编码 Agent 活跃度地图)的缩写。活跃度,因为这张地图绝不是过时的快照——它会监视文件系统,在文件变更时增量重新索引,并在每次响应中报告当前的新鲜度(scanning → parsing → building_edges → ready)。地图,因为它是一张真实的图——包含调用边、导入边、枢纽度/核心度指标,而不是假装自己是图的扁平文本索引。给 Agent 一张实时、可信的地形图,它就不再手足无措,而会冷静下来。
你将获得
- Agent 不再猜测谁依赖什么。
callers/callees/edit_context会在变更发布前显示所有已知调用方。完整的 tree-sitter 调用图开箱即支持 13 种语言:Python、TypeScript、JavaScript、Java、Rust 和 Go 无需配置即可使用;此外,默认的tier0-5语法包还支持 C、C++、C#、Ruby、PHP、Shell 和 R。另有 11 种语言(Kotlin、Swift、Scala、Dart、Lua、Elixir、Haskell、OCaml、Zig、PowerShell、Groovy)可通过选择加入的--features lang-X构建标记进行解析,总共可解析 24 种语言(参见多层索引)。 - 编辑不会悄无声息地造成破坏。 每次写入都会针对精确的行范围进行哈希验证,并在触及磁盘前完成语法检查。对于枢纽符号和高扇入符号,Agent 必须先审查调用方并明确确认,否则系统会坚决拒绝写入——只有拥有真实依赖图的工具才能执行这项策略,而已发布的竞品基准测试显示,没有其他服务会这样做。
- 每条边都会告诉你它有多可信。 调用边带有置信度等级(
textual → inferred → resolved → formal);当编译器可以交叉验证调用图时,CALM 会请求它进行验证:SCIP 覆盖层(rust-analyzer、scip-go——包括多模块go.work工作区——scip-python、scip-ruby等)和实时 LSP 覆盖层(gopls、clangd),在对应的提供方/工具链可用时,可在 12 种受支持的语言集成中将最佳猜测边升级为经编译器验证的确凿事实;不可用的提供方不会参与,也不会改变基础行为。 - 能为自身评分的代码库。
fitness_report会将枢纽集中度、死代码、复杂度和架构边界违规转化为可查询、可由 CI 强制执行的信号,而非一次性审计结果;remember/recall则让决策和注意事项在不同会话间持续可用。 - 协作顺畅,并且数据留在你的机器上。 跨进程编辑锁和单写入者索引模式,意味着两个编辑器会话在同一仓库中运行时,不会互相破坏写入,也不会重复索引;在共享守护进程下,会话甚至能彼此感知。索引、搜索和编辑过程中的代码不会离开你的机器;默认嵌入模型会在构建时打包进二进制文件,只要这些权重有效,运行时就无需联网;如果权重不可用,默认允许在运行时回退下载,严格离线运行时可将其禁用。采用 MIT 许可证。(另有一项选择加入的例外:使用
--features otel构建并设置OTEL_EXPORTER_OTLP_ENDPOINT后,系统会将 Span 属性——文件路径、符号名称、工具名称和耗时,不包含源代码正文——导出到你自己的采集器。默认关闭;参见 docs/architecture.md,并且仅使用https://采集器。)
CALM 的定位
如今,“面向 AI Agent 的代码智能”已成为一个真正的领域。Aider、Serena、Sourcegraph/Cody 等开源先驱共同推动了这一领域的发展,并证明:有真实的代码结构作为支撑,Agent 的表现会比只靠 grep 和良好意图更好。CALM 在此基础上发展而来,但重心有所不同:该领域的大多数工具都为读取路径提供信息——提升搜索、导航和上下文能力。CALM 还会保护写入路径。同一张图谱既能回答“谁调用了这个?”,也会强制执行“查看过之后才能修改”:修改枢纽代码或高风险代码时,必须先获取最新的编辑前上下文,并基于真实调用方明确确认;策略也可以扩展到每次编辑,而且每次写入在落盘前都会经过哈希和语法验证。
其中的取舍也说得很清楚:CALM 开箱即用的完整调用图谱层支持 13 种语言,而一些纯 LSP 工具支持 40 多种语言。不过,CALM 能解析 24 种语言,其中 12 种在相应提供程序可用时可升级为经过编译器验证的解析,因此差距没有看起来那么大。这种取舍换来的,是最能体现 CALM 独特之处的能力:按置信度分级的边、严格的编辑前门槛,以及能为自身健康状况评分的代码库——每项能力都有一个你可以亲自复现的数字(证据胜于承诺)。
CALM 适合你吗?
适合: 直接编辑代码、而不只是回答代码相关问题的 Agent · 使用 Tier-0/Tier-0.5 语言的单仓库代码库 · 针对同一仓库运行多个 MCP 客户端的项目(见下方支持的客户端)· 不想依赖嵌入 API、偏好本地优先的用户。
目前不适合: 多仓库/跨仓库企业搜索——专为这种规模打造的工具(包括 Sourcegraph/Cody)会更适合你 · 使用的语言不在 CALM 当前支持的 24 种 tree-sitter 语言之列。
快速开始
支持的客户端 — CALM 可与任何使用 stdio 的 MCP 客户端配合使用;目前已完成配置或提供了相关文档的客户端如下:
| 客户端 | 模式 | 最快捷的安装方式 |
|---|---|---|
| Claude Code | CLI · Web · IDE | claude mcp add --transport stdio calm -- npx -y @eilodon/calm-mcp serve |
| VS Code | IDE(原生 MCP / Copilot Agent 模式) | code --add-mcp '{"name":"calm","command":"npx","args":["-y","@eilodon/calm-mcp","serve"]}' |
| Cursor | IDE · 云端(后台 Agent) | 添加到 Cursor → |
| Windsurf / Devin Desktop | IDE · 云端 | 编辑 ~/.codeium/windsurf/mcp_config.json |
| Codex(OpenAI) | CLI · IDE | codex mcp add calm -- npx -y @eilodon/calm-mcp serve |
| Antigravity(Google) | CLI · IDE | 编辑 ~/.gemini/config/mcp_config.json |
| JetBrains AI Assistant | IDE | 通过 UI 设置 |
以上每种客户端的完整操作指南,包括需要全局配置的客户端所需的准确配置片段,请参阅 docs/mcp-client-setup.md。如果你在开发容器/Codespace 中运行,且 stdio 转发无法连通,请参阅 docs/http-transport.md(高级功能,仅适用于远程开发,需主动启用,默认仅监听环回地址)。
在自己的项目中使用 CALM——无需克隆,也无需 Rust 工具链:
{
"mcpServers": {
"calm": {
"command": "npx",
"args": ["-y", "@eilodon/calm-mcp", "serve"]
}
}
}
将其放入项目根目录的 .mcp.json(Claude Code/Cursor)或 .vscode/mcp.json(VS Code 使用顶层 "servers" 键,而不是 "mcpServers",其他结构相同)。若使用 Claude Code 插件,则运行:/plugin marketplace add Eilodon/CALM,然后运行 /plugin install calm@CALM。
如果你更倾向于使用原生二进制文件,而不是 npx,请运行 curl -fsSL https://raw.githubusercontent.com/Eilodon/CALM/main/scripts/install.sh | sh,然后在项目目录中运行 calm setup——它会自动写入相同的 MCP 配置,并指向刚安装的二进制文件。也可以改用 calm setup --npx,以写入可移植的 npx 配置项(可共享/提交——队友和 CI 无需安装二进制文件)。为确保全新安装可复现,默认会固定到此二进制文件自身的版本;传入 --track latest 则始终使用 npm 最新版本。
在 CALM 项目本身进行开发(本仓库):
# 1. Build the binary
cargo build --release -p calm-cli
# 2. Initialize config for your project
calm init --project-root .
# 3. Build the index (embeds symbols too, if semantic search is enabled in config.json)
calm index --project-root .
# 4. Run the MCP server over stdio — incremental reindex kicks in automatically if an index already exists
calm serve --project-root .
本仓库提供了现成的配置:Claude Code(.mcp.json)、Cursor(.cursor/mcp.json)和 VS Code(.vscode/mcp.json)——这三者都会调用 scripts/mcp-launcher.sh。这个共享启动器会查找已构建的二进制文件;如果当前 git 标签匹配,则下载并校验校验和的预构建版本;如果还没有可用版本,则从源代码构建。克隆仓库后即可使用——无需事先手动构建。
注意:
calm serve启动时会自动将.calm/添加到.gitignore,以免索引数据库被提交。
示例:Agent 的实际工作流
agent: repo_overview()
→ current files/symbols and `indexing_phase=ready` are reported live
agent: "I need to change getUserByEmail"
→ locate("getUserByEmail") # find the file + symbol metadata
→ source("getUserByEmail") # read just the function body, not the whole file
→ edit_context("getUserByEmail") # MANDATORY before any edit
→ the live caller count and risk assessment determine whether the agent reviews callers before touching the signature
→ edit_symbol("getUserByEmail", expected_hash=..., new_text=...)
→ risk_assessment=high, is_hub=true, no confirm:true → refused, with an explanation
→ edit_symbol(..., confirm=true, reason="checked getUserByToken, still returns the same shape")
# reason must cite a real caller edit_context returned — writes for real, reindexes immediately
→ diff_impact(staged=true) # verifies blast radius before commit
证据胜于承诺
下表是根据此检出库于 2026-08-12 观察到的 CALM 快照。重新运行 repo_overview() 和 fitness_report() 即可刷新;具体数值会随代码库变化。基准测试比率因任务而异,并保留在基准测试产物中:
| 指标 | 测量值 |
|---|---|
| 已索引代码库 | 366 个文件,6,050 个符号 — 仅此仓库中就包含 15 个语言系列 |
枢纽集中度(hub_pct) | 7.38% — 271 个枢纽符号(门槛:≤ 20%) |
死代码率(dead_code_pct,考虑覆盖率) | 5.04%(门槛:≤ 10%) |
热点风险(hotspot_risk,变更量 × 复杂度,最差文件) | 0.90 — 当前高于门槛(≤ 0.80),fitness_report() 报告 FAIL — 正在调查,而不是隐瞒或放宽阈值;参见 fitness_report/calm fitness-check |
边覆盖率(edge_coverage_pct) | 72.39% 的符号至少有一条调用边(门槛:≥ 60%) |
高复杂度函数(high_complexity_pct) | 2.8%(门槛:≤ 15%) |
架构契合度(avg_distance,Martin/OOD) | 与主序列的平均距离为 0.28(门槛:≤ 1.00) |
存在歧义的符号边界(boundary_ambiguous_count) | 0(门槛:≤ 0) |
架构边界违规(boundary_violations) | 0(门槛:≤ 0) — 此处此前标记的 watcher → tools 导入问题已修复:将所需的共享 RwLockExt/LockExt trait 从 tools/common.rs 移至独立的 sync_ext 模块 |
配置漂移(config_drift_count) | 0(门槛:≤ 0) — 当前文档/配置中的路径声明均可正常解析 |
| 相较于朴素逐文件阅读基准的 Token 效率 | 因基准测试而异;请参阅方法,不要将某项任务的比率视为整个仓库的固定值 |
| 完整测试套件(默认功能) | 见下文测试 |
竞争对手基准测试方法与各语言注意事项
与另外四个正在运行的 MCP 服务进行基准测试
benchmarks/b11_extended_competitor_ab/ 会在此仓库的隔离 Git 工作树上安装并调用四个成熟的开源代码智能 MCP 服务——CodeGraph、Semble、grepai 和 Serena;每项任务重复 5 次,并配有正确性判定基准。目标不是制作排行榜,而是用真实运行的先行方案来检验 CALM 的主张,而不是对照营销页面。
测试结果显示:在调用方召回率和影响范围任务上,CALM 达到了最佳结果;在五个服务中,只有 CALM 的编辑前安全门实际拒绝了有风险且未经确认的编辑,而不只是事后能够描述风险。并非所有数字都好看:在一项 Token 效率任务中,CALM 的压缩率是五者中最低的——该任务的正确率同样保持在最高水平,而这个数字也按实测结果公开。这是本项目一贯的基准测试政策:不理想的结果与好的结果一并发布(benchmarks/README.md)。完整的方法、所有任务及各工具的原始数值,请参阅该基准测试自己的 README。
语言覆盖率:以实测为准,而非空口断言
benchmarks/resolution/ 对新增或列为 Tier-0.5 的 19 种语言进行层级分布基线测试(已解析 / 推断 / 文本 / 有歧义的划分——没有判定基准,每种语言使用一个真实的开源仓库),并如实报告结果:Kotlin(89.6%)和 OCaml(86.3%)的结果大多落入 ambiguous 层级,原因是常见的短方法名冲突;Dart 能生成符号,但调用边为零——这是该 tree-sitter 语法的一项有文档记录的限制,并非 Bug;目前只有原始 Tier-0 语言接入了 Tier-2 类型推断。各语言的完整表格请参阅该基准测试自己的 README。
完整的技术细节请参阅 docs/architecture.md,其中包括设计理念:为什么每个响应都包含 suggested_next,以及为什么高风险步骤采用硬性门控,而不只是给出建议。各章节摘要:
- 多层索引 — 默认对 13 种语言构建完整调用图,另外 11 种语言可通过选择启用语法特性进行解析,共计 24 种。
- 值得信赖的调用图 — 每条边都标注置信度(
resolved/inferred/formal/textual);当提供程序/工具链可用时,SCIP 和 LSP 覆盖层可在 12 种受支持的集成中将边升级为编译器级真实结果;不可用的提供程序不会参与。 - 真正能找到内容的搜索 — 通过 Reciprocal Rank Fusion 融合 FTS5 与语义嵌入,并直接从磁盘进行真正的 grep/glob 搜索,以查找索引器从未解析过的文件。
- 具有实际安全保障的编辑 — 经哈希验证后写入,任何内容写入磁盘前都会进行语法验证;对于枢纽/高风险符号,还设有三项门控(最新的
edit_context、confirm:true、有依据的reason)。 - 并发与可靠性 — 共享守护进程、跨进程编辑锁和单实例索引锁,可确保同一仓库上的多个编辑器会话不会破坏或重复工作。
- 代码库自我评分 — 11 项适配度指标、考虑覆盖率的死代码检测、声明式架构边界、文档偏差检测。
- 会记忆并知道何时陷入困境的 Agent — 可跨会话持久保存的笔记、git 协同变更挖掘、陷入循环信号。
- 默认安全 — 凭据特征内容会在
source/understand中被遮盖,提示词注入特征内容会被标记,scan_text可检查外部文本;默认采用本地优先,并提供明确的嵌入回退方案。
Crate 布局
crates/calm-core/— 索引引擎:tree-sitter解析、SQLite 架构、多层解析器(保守 → 推断 → formal/Stack-Graphs、SCIP 或 LSP)、图算法(核心度、枢纽检测)、FTS5/语义搜索、分析(热点、覆盖率、codeowners、差异影响、死代码)、适配度指标、gitignore 管理。crates/calm-server/— MCP 服务(通过 stdio 或 unix 套接字守护进程运行的rmcp),提供 40 个工具以及增量文件监视器。crates/calm-cli/— 命令行工具:calm init、calm index、calm serve、calm connect、calm setup、calm fitness-check、calm guard、calm doctor。
CLI 参考
calm init --project-root . # writes .calm/config.json with defaults
calm index --project-root . # one-shot full index (Scanning → Parsing → BuildingEdges → Ready)
# also embeds symbols+chunks if semantic_search.enabled=true
calm serve --project-root . # MCP server over stdio + incremental reindex + file watcher
calm serve --project-root . --listen unix:/path/to/daemon.sock # run as a shared daemon (opt-in)
calm connect --project-root . # lightweight forwarder to an already-running daemon (opt-in, Unix)
calm serve --project-root /project --db-path /data/index.db # separate DB path (container deployment)
calm serve --project-root . --preset orient # register only the "orient" phase's tools
calm doctor --project-root . # validates config, DB (symbols/files/metrics history), git
calm setup --project-root . # writes/merges MCP config (.mcp.json/.cursor/.vscode) pointing at this binary
calm fitness-check --project-root . # CI gate, exits 1 on failure
calm fitness-check --project-root . --json # JSON output
calm fitness-check --project-root . --config thresholds.toml # custom thresholds
calm guard --project-root . # pre-commit/CI gate on the staged diff, exits 1 if aggregate risk >= --fail-on (default: high)
calm guard --project-root . --fail-on medium --json # stricter threshold, machine-readable output
calm guard --project-root . --base origin/main # review this branch/PR against a base ref instead of the staged diff
calm guard --project-root . --commits HEAD~3..HEAD # raw commit range, passed straight through to git diff
calm value-report --project-root . # real counts from .calm/audit.log: risky edits blocked, risk distribution on what was applied
calm value-report --project-root . --json # machine-readable output
calm scip-run --project-root . --lang go # force one SCIP provider to run now, bypassing refresh policy
calm scip-run --project-root . # --lang omitted = run every provider ("rust,go,python,javascript,java,csharp,php,ruby,c")
calm index --project-root . --scip-file build/index.scip --sub-root services/api # ingest a pre-built SCIP index (CI/sandboxed, no external indexer install needed)
面向 AI Agent 的 40 个 MCP 工具
CLI 预设可按工作流阶段筛选工具:orient、trace、edit、compound、full(默认),可通过 calm serve --preset 或 config.json 中的 preset 字段设置;也可以根据工具集(模块)名称组合自定义集合,例如 --preset "trace,security" 或 --preset "full,-edit"(完整工具集列表请参阅 AGENTS.md)。每个响应都包含 suggested_next,用于指引下一步操作;每个工具的完整细节和完整工作流请参阅 AGENTS.md。
| 分组 | 工具 |
|---|---|
| 定向 | repo_overview、hotspots、fitness_report(健康快照——指标与 calm fitness-check 相同,可在会话中查询)、indexing_status、test_gap_hotspots(按核心度 × 死代码/测试覆盖率置信度为符号排序——指出编写测试最能发挥效果的地方) |
| 定位 | locate、search、file_overview |
| 检查 | source、symbol_info、understand、symbols_batch(一次往返即可获取多个精确 qualified_name 的源代码及调用方/被调用方) |
| 跟踪 | callers、callees(有序、数量受限,可对枢纽符号使用 etag 缓存)、path、dependencies、reference_impact(将调用边、导入边和文本 grep 合并为一个分类后的重命名/删除引用列表——范围比单独使用 callers/dependencies 更广,但粒度更粗) |
| 编辑 | edit_context(每次编辑前都必须调用)、edit_lines/edit_symbol(唯一可写入任意内容的工具——经哈希验证;除非本会话对该确切符号运行过 edit_context、传入 confirm:true,且 reason 引用了 edit_context 返回的真实调用方,否则会拒绝对枢纽/高风险内容的修改)、format_files(仅通过 stdin 调用 rustfmt——绝不传入位置文件参数,因此不会触发 rustfmt 自身的 crate 级 mod 树发现,也不会重新格式化自身 paths 列表之外的文件;格式化不会改变语义,因此不设 confirm/edit_context 门槛)、pattern_debt_register/pattern_debt_status(通过 search(kind="similar") 按 qualified_name 标记重复的错误模式,稍后可重新检查其状态是否为 open/resolved/anchor_lost)、diff_impact(提交前必须调用)——在 Claude Code 中,钩子会强制执行 edit_context 和 diff_impact(参见 .claude/hooks/calm-nudge.sh);在任何其他 MCP 客户端中,session_context 的 pending_diff_impact 是等效信号 |
| 变更(授权) | plan_change/review_change——为编辑门控提供可审查变更的封装层:plan_change 会将 ChangeIntent(你将要做什么、为什么)登记为持久、可审查的记录;当 approved:true 时,review_change 会为其签发签名的 ReviewAuthority(客户端自行声明,且仅足以处理低/中风险变更);如果真实的 PolicyEngine/RiskVector 评估认定变更需要独立的人工审查,则会直接拒绝——通过 edit_lines/edit_symbol 使用授权时,会重新进行实时验证,而不只是签发时验证 |
| 事务(管理) | batch_status(将调用方提供的 tx_id 列表——来自多个 edit_lines/edit_symbol/format_files 调用——汇总为一个视图:按状态统计数量,并显示是否有失败)、edit_transaction_status、maintenance_status、retry_maintenance、repair_consistency、verify_change(WS-6 首个切片:对选择加入验证的编辑按需运行 cargo check)——用于诊断 WS-1 持久化编辑事务日志中的事务/维护发件箱;edit_lines/format_files 现在会通过该日志写入;这些工具注册在各自的 txn 工具集下,并包含在 edit 预设中(不包含在 orient/trace/compound 中) |
| 恢复 | session_context、remember、recall |
| 高级 | scip_refresh、lsp_refresh——强制一个或所有 SCIP/LSP 提供方立即运行,绕过自动刷新策略。scan_text——对你提供的任何文本(WebFetch/WebSearch 结果、子 Agent 报告、粘贴的内容)运行 source/understand 使用的相同提示词注入/凭据启发式检查——在本地离线运行,不依赖任何托管式 LLM 安全分类器。set_toolset——在运行时缩小或重置本会话暴露的工具范围,无需重启服务(安全底线——始终保留 orient+guardrails+recover+edit)。这四个工具仅在 full 预设中提供,不在上文的四个工作流阶段预设中——它们是刻意保留的手动/罕用逃生口,而非默认流程中的步骤 |
MCP Prompts — 打包为斜杠命令的工作流
与上面的 tools 不同,MCP Prompts(prompts/list、prompts/get)会为你经常重复的工作流返回一条现成的指令消息;MCP 客户端会将它们呈现为斜杠命令:
| 提示词 | 参数 | 打包的工作流 |
|---|---|---|
review_symbol | symbol | locate → source → edit_context(必需)→ 在触及任何内容之前汇总风险 |
debug_symbol | symbol | understand → callers(max_depth=3) → 检查 test_files/dead_code_confidence |
onboard_area | path | repo_overview → file_overview/dependencies → 针对该路径范围内的 hotspots |
review_pr | range | diff_impact(commits=range) → hotspots(重叠检查)→ fitness_report → 合并前汇总风险 |
calm_workflow | (无) | 不带参数地介绍完整的第 1–8 阶段工具工作流——适用于从不自动加载 AGENTS.md 的客户端,或用于会话中途回顾 |
一行 CI:CALM Guard GitHub Action
action.yml 将 calm index + calm guard 封装为可复用的复合 Action——让只想在每个 PR 上审查影响范围、无需使用 MCP 客户端的仓库一行即可接入:
- uses: Eilodon/CALM@main
with:
fail-on: high # default; "low"/"medium" also accepted
对于 pull_request 事件,它会自动检测 PR 的基分支(仅获取该引用,因为默认的浅克隆检出不会包含它),并审查相对于合并基点的范围;对于普通的 push,则审查 before..after。两者都可以通过 base/commits 输入项覆盖,这些输入项与 calm guard 自身的 --base/--commits 标志对应(参见上文的 CLI 参考)——对于自动检测无法涵盖的情况(workflow_dispatch、合并队列事件等),请显式设置其中一项。需要一个运行器可以访问的 npm 发布版 @eilodon/calm-mcp;无需安装其他内容。
健康度检查 — CI 门禁
每次推送/PR 时,都会在 .github/workflows/ci.yml 的 fitness-check 作业中实际运行——先执行 calm index(全新检出时尚无 .calm/index.db),然后执行 calm fitness-check --project-root . --config thresholds.toml。--config 标志不可省略:如果没有它,[[boundaries]] 和 [config_drift] 会被静默视为“未声明规则”,而不会报错——只有数值阈值有真正的默认值。
calm fitness-check 会根据 thresholds.toml 中声明的阈值测量 11 项指标:
| 指标 | 测量内容 | 有效阈值 |
|---|---|---|
hub_count | 被分类为枢纽的符号数量 | ≤ 1000 |
hub_pct | 枢纽符号占比(与规模无关) | ≤ 20.0% |
avg_coreness | 图中 k-core 核心度的平均值 | ≤ 15.0 |
dead_code_pct | “高”死代码置信度的符号占比 | ≤ 10% |
hotspot_risk | 代码库中的最高热点分数 | 此仓库中 ≤ 0.80(由 thresholds.toml 覆盖;内置默认值 ≤ 0.75) |
edge_coverage_pct | 至少有一条调用边的符号占比 | ≥ 60% |
high_complexity_pct | McCabe 圈复杂度 > 10 的函数/方法占比(基于 AST;Tier-0.5 语言的复杂度始终报告为 1) | ≤ 15.0% |
avg_distance | Martin/OOD 主序列平均距离——每个文件的抽象度与其不稳定性(Ca/Ce)所暗示的理想值之间的偏差 | ≤ 1.00 |
boundary_violations | 违反已声明 [[boundaries]] 规则的 import_edges 数量 | ≤ 0 |
boundary_ambiguous_count | 行边界存在歧义(与相邻项共享)的符号数量——在解决之前,这些符号的 edit_symbol 替换操作会被拒绝 | ≤ 0 |
config_drift_count | 指向不存在路径的文档文件路径引用数量(通过 [config_drift].doc_paths 声明) | ≤ 0 |
除上述特别注明的情况外,表中使用内置数值默认值;此仓库中已提交的 thresholds.toml 才是 CI 实际采用的策略。每次运行 calm fitness-check 也会将指标快照保存到 DB,以便 edit_context 显示趋势(与前一天相比的变化量)。
架构边界 — [[boundaries]]
直接在 thresholds.toml(与 [thresholds] 位于同一文件)中声明“模块 A 不得导入模块 B”,并按路径前缀匹配(不支持 glob/正则表达式)。请注意,这用于划分 Rust 自身的 crate/module 边界尚未强制执行的分层——声明“calm-core 不得导入 calm-server”毫无作用,因为 Cargo 的依赖图在结构上已使其无法实现:
[[boundaries]]
from = "crates/calm-core/src/indexer/"
to = "crates/calm-core/src/analysis/"
reason = "indexer (extraction) must stay upstream of analysis (dead-code, hotspots, fitness) — not the other way around"
在 --json 模式之外,calm fitness-check 会具体报告每项违规(实际的来源/目标路径、规则和原因);默认的 max_boundary_violations = 0 意味着你费心声明的规则,就是你确实会遵守的规则。
本仓库自己的 thresholds.toml 目前声明了两条规则:上面那条,以及 crates/calm-server/src/watcher.rs → crates/calm-server/src/tools/(“后台重新索引/监视循环必须独立于它运行的 MCP 工具处理层”)——两条规则的违规数目前均为 0。
部署
cargo build --release通过.github/workflows/release.yml生成静态二进制文件(Linux 上使用 musl),目标平台矩阵包含 5 个平台,并为每个构建产物提供SHA256SUMS和构建来源证明:x86_64-unknown-linux-musl、aarch64-unknown-linux-musl、aarch64-apple-darwin、x86_64-apple-darwin、x86_64-pc-windows-msvc。在支持的目标平台上,如果检出位于匹配的 git 标签上(或你正在安装该标签),scripts/mcp-launcher.sh/scripts/install.sh会自动下载并校验对应平台的构建产物;未打标签、离线或平台不受支持时,则回退到现有二进制文件或从源码构建。Containerfile使用多阶段构建(rust:alpine→scratch)——只需一个静态二进制文件,无需运行时镜像;每次推送 git 标签时,都会将其发布到ghcr.io/eilodon/calm-mcp(使用版本标签及latest标签)。compose.yaml提供了一个经过强化的示例(read_only、cap_drop: ALL、no-new-privileges、pids_limit: 64、mem_limit: 256m)。- 默认嵌入模型的权重通过
include_bytes!嵌入二进制文件——build.rs::ensure_embedding_weights会从 Hugging Face Hub 获取crates/calm-core/assets/potion-code-16m/*.safetensors,并仅在编译时校验一次校验和,因此只要权重有效,常规的cargo build/release 二进制文件在运行时就无需网络 I/O。此处不涉及 Git LFS(仓库中不含任何 LFS 内容)。
如果构建时获取失败(例如离线构建),会发生什么?
cargo build 仍会成功编译——build.rs 会写入一个小型占位存根来替代真实权重,而不是让构建失败。在运行时加载该存根会失败(“failed to parse safetensors”),因此 Embedder::load 会自动回退到从 Hugging Face Hub 一次性下载同一模型(之后会在本地缓存;默认配置允许此回退,而 semantic_search.allow_network_fallback = false 会严格禁止运行时联网)。如果禁用了该回退,或回退也不可用,indexing_status 会报告 embeddings_status: "failed",而 search(kind="semantic"/"hybrid") 会降级为仅使用 FTS——不会崩溃,只是在模型可用并重新构建或重新运行之前无法进行语义搜索。
- 默认模式为 MCP stdio。 在 Unix 上,不带额外启动器参数调用时,启动器会使用共享 Unix 守护进程;自定义调用、CI 和 Windows 可以使用单进程
calm serve。 - HTTP 需要显式启用。
calm serve --http默认绑定到127.0.0.1:8787。要允许非回环地址访问,必须使用--allow-remote,并通过 Bearer token 发送非空的CALM_HTTP_TOKEN。 - 远程 HTTP 为只读。 CALM 会将有效预设强制设为
remote-safe——该预设会从工具路由器本身计算出所有声明了read_only_hint = true的工具,而不是依赖手动维护的列表,因此不会悄然漏掉新添加的状态修改型工具;请在反向代理处终止 TLS。内置 HTTP 传输会限制请求正文大小和并发请求数,作为纵深防御,但没有真正的速率限制或按 IP 防 DoS 保护,因此不要将其直接暴露给不可信网络。
测试
cargo test --workspace # unit + integration (embeddings is a default feature, included)
cargo test --test parity_test test_formal_edges # Stack Graphs regression corpus
每个 PR 都会运行 11 个 CI 作业(已根据 .github/workflows/ci.yml 自带的作业列表核实,并非手动计数):verify(fmt/clippy/test/audit)、calm-guard-dogfood(使用本仓库自己的 PR 对 action.yml 进行 dogfood 测试——新功能期间设置 continue-on-error: true,并启用影子模式)、stack-graphs-corpus(formal-resolver 奇偶性验证)、txn-crash-injection(WS-1 的崩溃注入套件——在每个可达的 TxState 转换处终止进程,使用真正的 SIGKILL)、embeddings(启用 embeddings 功能后的 clippy + test)、no-stack-graphs-formal(关闭 stack-graphs-formal 后的 clippy + test——这是唯一覆盖该功能门控编译出的 resolver::formal 存根的 CI 作业)、all-languages(对所有 24 种已解析语言进行 fixture-repo 索引,另含 lsp-overlay)、js-client-interop(使用真实的 JS MCP SDK 客户端交叉检查工具架构,而不仅是 Rust 自身的实现)、otel-http-features(启用 otel/http 功能后的 clippy + test,另含针对 opentelemetry 核心版本不一致的保护检查)、fitness-check(对本仓库自己的索引运行 calm fitness-check——见下文的 适配度检查)、status-drift(如果 docs/status.generated.md 已过期、任何手写文档中的工具数量与其不一致,或基准测试声明注册表的结构不一致,则构建失败)。
工作区包含 1,000 多项测试;最新 CI verify 作业是通过/失败状态的权威依据。少数标记为 #[ignore] 的实时二进制集成测试(例如 rust-analyzer/scip-go/scip-java)需要并非每种环境都已安装的外部工具。
延伸阅读
docs/architecture.md— 完整的技术深度解析:多层索引、SCIP/LSP 覆盖层、搜索内部机制、编辑安全网、并发、自我评分、记忆、净化,以及贯穿其中的设计理念。docs/comparison.md— 以方法论为先,阐述本项目相对于这一类别中其他工具的定位。docs/what-external-users-get.md— 详细说明通过npx/npm/MCP-Registry 安装能获得什么,以及它与本仓库自身的开发检出内容有何不同:安装/分发机制、完整的工具和工具集说明、编辑安全层、语言覆盖范围,以及哪些内容绝不会对外发布。docs/— 解析器内部机制、迁移计划,以及上文docs/architecture.md未涵盖的其他设计说明。docs/adr/— 各项架构决策记录(Stack Graphs 的范围、形式化解析器方案、可选 LSP 带来的置信度提升、守护进程 + 转发器并发模型)。docs/mcp-client-setup.md— 每种 MCP 客户端安装方式的详细说明,包括 Windsurf/Devin Desktop 和 Codex 全局配置。docs/http-transport.md— 可选的远程/HTTP 传输方式(calm serve --http):默认仅监听回环地址、必须使用--allow-remote并提供令牌才能放行、远程暴露为何会强制启用只读预设,以及 TLS/反向代理要求。AGENTS.md— 本项目自身的 Agent 遵循的完整逐工具工作流指南。KNOWN_LIMITATIONS.md— 诚实列出 CALM 目前尚未实现的功能(单语言、无沙箱验证、不支持多文件变更集、没有引用影响工具、风险分类不识别变更类型等),并说明为何每项都被有意推迟,而不是只做一半。benchmarks/— 本 README 中各项基准测试声明背后的测量套件,以及其他一些测试:b2_call_graph_quality/(相对于 SCIP 预言机的精确率/召回率)、b3_search_quality/(混合 RRF 与仅 FTS、原始 grep 的对比,NDCG@10)、b4_token_efficiency/(逐任务对比令牌成本与朴素基线)、b6_tool_call_efficiency/(往返次数:朴素多次调用与单次 MCP 调用的对比)、b7_task_correctness/(在 6 种语言代码库上进行真实重命名重构——fd/Rust、flask/Python、express/JS、zod/TS、gin/Go、spring-petclinic/Java——并通过独立的通过/失败预言机进行检查,而非由大模型评判)、b11_extended_competitor_ab/(实际调用其他 4 个在线 MCP 服务,而非使用自报数据)、b12_tier1_tier2_tool_correctness/(通过 JSON-RPC 实际运行 9 个工具,测试 6 个外部 OSS 仓库,并以正则表达式/git grep作为基准验证)、resolution/(在 19 个真实 OSS 仓库上测量层级分布基线,每种语言一个)。有意将不理想的结果与良好结果一同发布——benchmarks/README.md说明了这项原则。
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。