关于 Rarefaction
Rarefaction 是面向编码 Agent 的 MCP 服务,可在一次有界响应中汇总符号的 LSP 调用图和相关代码上下文。它识别调用方、被调用项、实现、测试及变更可能影响的文件,用于代码导航和影响分析,支持多种语言配置。
主要功能
- 01构建有界的多层调用图
- 02显示符号签名和函数体
- 03识别调用方、被调用项和实现
- 04查找覆盖某符号的测试
- 05列出变更相关文件
- 06报告索引新鲜度和 LSP 覆盖情况
适用场景
- 01修改函数前追踪依赖关系
- 02选择与符号相关的测试
- 03按符号探索陌生代码库
- 04检查索引新鲜度和语言服务器覆盖情况
MCP 相关
通过 stdio 向 MCP 客户端提供只读的 `status`、`orient` 和 `scope` 工具。它通过项目语言服务器使用 LSP 获取符号和调用层级信息。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
3收录的工具列表 · 更新于 1 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| up | integer | 否 | 要遍历的调用方层数(默认值为 2:测试用例通常位于其所测试代码上方的一个辅助函数中)。 |
| down | integer | 否 | 要遍历的被调用方层数(默认值为 1)。 |
| symbol | string | 是 | 函数、方法、类型或属性:"updateLocation"、"Engine.updateLocation",或精确位置 "Sources/Engine.swift:204:10"(从 1 开始计数的行:列,指向名称所在位置)。 |
| profile | enum | 否 | 源语言 profile;在混合工作区中使用裸名称时必填。swift | rust | c | typescript | wasm | python |
| project | string | 否 | 相对于工作区的项目目录,例如嵌套 Cargo 包的 tools/driver。 |
| max_nodes | integer | 否 | 每个方向和引用上下文的图节点最大数量;调低此值可获得更精简的回答。 |
| include_body | boolean | 否 | 包含该符号的源代码函数体。 |
| max_body_lines | integer | 否 | 在此行数后截断函数体。 |
详细介绍
Rarefaction — 面向 AI 编码 Agent 的 LSP 调用图 MCP 服务
Rarefaction 是一个 Model Context Protocol(MCP)服务,可直接从项目的语言服务(Language Server Protocol,LSP)向编码 Agent 提供单个符号的调用图和代码上下文。询问一个函数、方法或类型,即可通过一次调用获取:其签名和文档、函数体、调用它的对象(标记测试)、它调用的对象、实现它的对象、可到达该符号的测试,以及更改可能影响的文件的简要列表。Agent 阅读这些内容,无需打开整个文件并搜索,从而缩小上下文窗口,减少探索所耗费的 token。
可与 Claude Code、Codex 及任何通过 stdio 通信的 MCP 客户端配合使用。配置支持 Swift、Rust、C/C++、TypeScript/JavaScript、Python 和 WebAssembly 文本(WAT)。
使用捆绑的 TypeScript fixture(fixtures/SampleTypeScript)运行:
# scale — engine.ts:2:17
```
function scale(value: number): number
```
Double one input sample.
## Callers (2, 1 in tests)
- render — render.ts:2 (calls at 3)
- · testScale — engine.test.ts:2 (calls at 3) [test]
## Tests that reach it (1)
- testScale — engine.test.ts:2
Run only these:
```
npm test -- "engine.test.ts"
```
## Live files (3 of 3)
- engine.test.ts
- engine.ts
- render.ts
_11 LSP requests, 6430 ms (includes language-server cold start); index on-open_
语言服务完成索引后,一次调用耗时仅为几分之一秒(在 ripgrep 上的中位数为 80 ms,在包含 800 个文件的 IronRDP 工作区上为 220 ms);服务冷启动在这些项目上需要 6–16 s,但每个会话只需支付一次。
它能帮你做什么
- 减少 AI 编码 Agent 的 token 用量。 一份范围有限的答案可替代多次读取和搜索整个文件。在 ripgrep 和 IronRDP 中针对 50 次真实提交进行测量,答案的字节数中位数仅为它所列文件各读取一次的 6–7%。整个 Agent 会话究竟能节省多少目前尚未测量;请参阅 docs/measurement.md,其中也说明了有效文件集的不足之处。
- 调用图和影响分析。“什么会调用此函数?如果我更改它,什么会出问题?”默认提供两层调用者和一层被调用者,以及实现和类型层级;每部分都有范围限制,并会在截断时标记。
- 选择要运行的测试。 提供可到达该符号的测试,以及项目测试运行器的“仅运行这些”命令。
- 熟悉不熟悉的代码库。 可使用裸名称、限定名称或精确的
path:line:column位置;如果名称有歧义,会返回精确位置列表,而不是猜测。 - 如实说明覆盖情况。 索引过时、服务仍在建立索引,以及服务不支持调用层次结构等情况都会在答案中报告,不会隐藏。
为什么需要用于 LSP 调用图的 MCP 服务
语言服务已经能精确了解调用图——这正是“查找引用”和“调用层级”的功能。编辑器和 LSP 工具一次只公开一跳,因此 Agent 每跳都要付出一次工具调用和一轮上下文。Agent 需要的是闭包:几跳范围内的所有内容,按项目筛选,标出测试,并且精简到可以一次读完。本服务实现的正是这种组合。它刻意与语言无关:核心只使用 LSP,除此之外一概不涉及;每种语言所需的内容都只是一个小型配置档案。
与相关工具的对比:
| 方式 | Agent 能获得什么 |
|---|---|
| 读取文件并使用 grep | 整个文件;文本匹配,而非调用 |
| 按请求调用的 LSP 工具(定义、引用、调用层级) | 精确答案,每次工具调用只查一跳 |
| Serena | 通过 LSP 进行符号导航和语义编辑;与本服务配合良好 |
| Rarefaction | 有界的多跳调用图、测试,以及一次调用即可获取的某个符号的实时文件 |
安装
需要 Node 22.22.2 或更高版本;已在 macOS 和 Linux 上使用(CI 在 Ubuntu 上运行),尚未在 Windows 上测试。TypeScript 和 Python 语言服务已随包提供。请安装所需的其他语言服务,并将其放到客户端启动时使用的 PATH 中——参见语言和配置。
Swift 需要 macOS 和 Xcode(或带有 sourcekit-lsp 的 Swift 工具链)。
作为插件使用(Claude Code 和 Codex)
该插件会打包服务,并通过 npx -y rarefaction-lsp-mcp 启动;还包含一个 orient-first 技能,指导 Agent 在读取整个文件前调用 status 和 orient,并在编辑前调用 scope。
# Claude Code
claude plugin install rarefaction --marketplace ip2k/rarefaction
# Codex
codex plugin marketplace add ip2k/rarefaction
codex plugin add rarefaction@rarefaction
在 Claude Code 会话中,执行 /plugin install rarefaction --marketplace ip2k/rarefaction 效果相同。之后请重启或重新连接会话。
作为 MCP 服务使用
claude mcp add --scope user --transport stdio rarefaction -- npx -y rarefaction-lsp-mcp
codex mcp add rarefaction -- npx -y rarefaction-lsp-mcp
如果 rust-analyzer 或 wat_server 位于客户端的 PATH 之外,请在 -- 前添加 --env PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"。这些工具包括 status、orient 和 scope(在 Claude Code 中为 mcp__rarefaction__status、mcp__rarefaction__orient 和 mcp__rarefaction__scope);三者均为只读工具,因此可以在权限设置中允许它们,以避免重复提示。对于 Codex,请在 ~/.codex/config.toml 中为首次索引预留时间:
[mcp_servers.rarefaction]
startup_timeout_sec = 20
tool_timeout_sec = 180
服务接受 --root <path> 和 --profile <id>。显式指定的 --root 优先级高于 Claude Code 的 CLAUDE_PROJECT_DIR,随后才是工作目录。若要注册为用户级服务,让每个项目都能使用所有受支持的配置档案,请将两者都留空。请参阅 MCP 文档:Claude Code 和 Codex。
从克隆仓库运行
若要运行自己的修改,请构建并注册编译后的入口:
git clone https://github.com/ip2k/rarefaction.git
cd rarefaction
npm ci && npm run build
claude mcp add --scope user --transport stdio rarefaction -- "$(command -v node)" "$PWD/dist/index.js"
修改服务后请重新构建,然后重启或重新连接客户端会话(/mcp)。
检查是否正常工作
在项目中开启新聊天,并让 Agent 调用 status,然后对一个你熟悉的符号调用 orient。status.root 应与项目相符,status.profiles 中选定的条目应显示 ok: true。一个注册即可服务于所有受支持的语言;每种语言服务都会按需启动。
Agent 指引
插件中的技能已涵盖这些内容。若不使用插件,请将以下内容添加到 ~/.claude/CLAUDE.md、AGENTS.md 或项目指令文件中:
在新项目中使用一次 rarefaction 的 status 工具,然后在读取整个文件前对相关符号调用 orient,并在编辑符号前调用 scope(建议:也查看其列出文件之外的内容)。在混合语言仓库中,请传入 profile 或相对于工作区的 path:line:column;对于不是工作区成员的嵌套包,请传入 project。先使用默认图范围;仅在必要时扩大范围。遵循新鲜度和覆盖范围建议,并在相关时单独检查 FFI/生成的绑定。
Xcode 项目
Xcode 项目需要构建服务器配置,以便 sourcekit-lsp 获取编译器标志(SwiftPM 包无需配置):
brew install xcode-build-server
cd /path/to/App && xcode-build-server config -project App.xcodeproj -scheme App
echo buildServer.json >> .gitignore
然后在 Xcode 中或使用 xcodebuild 构建一次;索引的新鲜度取决于上次构建的时间,如果源文件较新,orient 会提示这一点。保存的源代码编辑会在后续查询前发送到打开的 LSP 文档,但 Xcode 项目仍需重新构建,才能刷新跨文件索引。
工具
| 工具 | 说明 |
|---|---|
orient | {symbol, profile?, project?, up?, down?, max_nodes?, include_body?, max_body_lines?} — 上述信息包。symbol 可以是 updateLocation、Engine.updateLocation 或 path/File.swift:204:10。名称有歧义时,会返回列出精确位置的错误。 |
scope | {symbol, profile?, project?, up?, down?, max_nodes?} — 对该符号进行更改时的工作集:orient 中的调用图文件,以及根据 Git 历史记录,与该符号所在文件或调用图文件曾在同一提交中更改的文件;每个文件都会注明原因。仅供参考:它列出需要阅读和检查的内容,而不是可以安全忽略的内容(测得的覆盖率)。 |
status | {profile?, project?} — 服务可见的信息:配置文件清单及当前选中的配置文件、构建服务器配置等前置条件、索引新鲜度,以及服务提供的 LSP 功能。如果 orient 没有找到任何内容,请先调用此工具。 |
计划中:impacted_tests(将向上遍历范围限制为测试,并返回可运行的选择)。
语言和配置
| 配置文件 | 语言服务器 | 前置条件 / 范围 |
|---|---|---|
swift | sourcekit-lsp | Xcode 或 Swift 工具链;SwiftPM,或带有构建服务器配置的 Xcode |
rust | rust-analyzer | Cargo.toml 或 rust-project.json;支持嵌入式 / no_std / Wasm 目标设置;如果项目固定了工具链,则需要执行 rustup component add rust-analyzer --toolchain <channel>(status 会说明这一点) |
c | clangd | C/C++;要准确解析包含路径和定义,需要 compile_commands.json 或 compile_flags.txt |
typescript | typescript-language-server | TypeScript/JavaScript、TSX/JSX;服务器和 TypeScript 作为依赖捆绑 |
python | Pyright | Python 和类型桩;已捆绑;请根据你的环境配置解释器 / 导入路径 |
wasm | wat_server | WebAssembly .wat 文本;请将预编译的服务器安装到 PATH 中 |
服务器会探测各语言服务器的功能。如果不支持调用层次,
orient 会报告引用和外围符号,但不会声称这些引用是调用。
编译为 WebAssembly 的原生 Rust/C 源代码使用 rust/c;.wasm
二进制文件需要反汇编为 .wat。WAST 测试脚本、供应商汇编代码、
间接运行时分派和跨语言 FFI 边不会被编入统一图谱。
工作区根目录下的可选 .rarefaction.json 用于配置各个配置文件。
project、配置文件的 root 和相对位置查询中的路径均相对于该
工作区。如果位置查询未指定 project,则从包含该文件 crate 的最外层
Cargo 工作区回答(作为成员、通过 package.workspace 指针,或作为根
包的路径依赖),否则从最近的受支持项目标记处回答。如果因此遗漏了
外层项目的一部分,答案会附带警告,说明遗漏情况以及应传入哪个
project。TypeScript 是个例外:TypeScript 语言服务器一次只回答一个
tsconfig.json 项目,因此在每个包各有一个 tsconfig.json 的 npm、
yarn 或 pnpm 工作区中,无论是否指定 project,都不会列出其他包中的
调用方,警告也会说明这一点。搜索会在包含 .git 的目录处停止,因此
对于位于工作区内的 git worktree、子模块或其他嵌套检出,位置查询只会
基于该检出回答;对于位置,请将其路径作为前缀,对于裸名称,请在
project 中指定该路径。在混合工作区中查询裸名称时,需要指定
profile 或配置 default_profile:
{
"default_profile": "typescript",
"profiles": {
"rust": {
"root": "firmware/rust",
"initializationOptions": {
"cargo": { "target": "thumbv7em-none-eabihf", "features": ["board"] }
}
},
"c": { "args": ["--background-index", "-j=2", "--compile-commands-dir=/absolute/local/build"] },
"python": {
"initializationOptions": { "python": { "pythonPath": "/absolute/project/.venv/bin/python" } }
}
}
}
command、args、env 和 initializationOptions 可覆盖各配置文件的
启动设置;初始化对象会递归合并。默认情况下会禁用 Rust cargo 检查、
构建脚本和 proc 宏,以避免意外编译;如果项目需要生成或展开的代码,
请显式启用它们。更改此配置后,请重启 MCP 连接。缺少的可执行文件会
在 status 中显示,并附有设置建议。
图谱输出默认每个方向最多显示 50 个节点、两层调用方、一层被调用方和
80 行函数体。使用 max_nodes、up、down 或 include_body: false
调整上下文大小。截断会明确标出。没有工作区索引时,名称查找会退回到
扫描最多 200 个源文件;必要时请使用精确位置或较小的项目。
有关分析编译数据库和目标限制,请参阅嵌入式 C、JieLi 和 WebAssembly 设置。
将 Serena 与 Rarefaction 配合使用
Serena 可通过符号导航、诊断和语义编辑 为此服务提供补充。docs/serena.md介绍了固定版本的安装、 WAT 适配器、项目语言设置、限制和验证。
隐私
Rarefaction 完全在你的机器上运行。它会读取项目文件,并通过本地 stdio 与语言服务器通信;不会发出网络请求,也不会收集遥测数据。它启动的语言服务器与在编辑器中运行时行为一致(例如,rust-analyzer 会运行 cargo metadata,这可能会获取 crate 索引)。首次使用时,npx 会从 npm 下载该软件包。
开发
npm ci && npm run build
npm test # unit + real LSP integration; external servers skipped if absent
claude plugin validate . # plugin and marketplace manifests
node scripts/verify-codex.mjs # exercise the registered MCP through Codex, no model turn
npx tsx scripts/try.ts --root fixtures/SampleTypeScript orient '{"symbol":"scale"}'
徽标和图标(Rosé Pine Moon)由 python3 tools/render_logo.py 生成;README 图表(浅色主题使用 Dawn,深色主题使用 Moon)由 python3 tools/render_diagrams.py 生成。fixtures/ 下的测试项目是小型合成项目,每种语言一个。CI 会在安装了 clangd 和 rust-analyzer 的环境中运行测试套件。Release 工作流(推送 v* 标签,或在 main 上点击“Run workflow”)会检查所有版本字段是否一致(package.json、server.json 和两个插件清单),将软件包发布到 npm 和 MCP Registry,名称为 io.github.ip2k/rarefaction-lsp-mcp,然后创建 GitHub 发布版本。docs/measurement.md 说明了项目为自己设定的阈值;docs/decisions.md 记录了各项设计背后的原因。
许可
Copyright (C) 2026 Sean (ip2k)。
本程序是自由软件:你可以依据自由软件基金会发布的 GNU 通用公共许可证(第 3 版或任意更高版本)的条款重新分发和/或修改本程序。本程序按“原样”提供,不附带任何担保;完整条款请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。