关于 slimdex-mcp
slimdex-mcp 是供编码 Agent 使用的本地 MCP 服务,可按需检索代码上下文,并在会话间保留笔记。工具涵盖符号与依赖查询、限量源码读取和代码库记忆。
主要功能
- 01索引符号和导入项
- 02获取文件大纲与符号代码
- 03搜索代码和意图
- 04查看依赖与引用
- 05跨会话保存笔记
- 06批量执行多项查询
适用场景
- 01检查大型源码文件中的函数而不读取整个文件
- 02通过会话笔记和回顾继续代码库探索
- 03修改符号前检查调用方、依赖和测试
MCP 相关
向 MCP 客户端提供代码检索、代码库索引和记忆工具。服务器的 MCP instructions 还包含检索指导。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
30收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| force | boolean | 否 | 忽略缓存并重新解析所有内容。 |
详细介绍
slimdex-mcp
**你的 Agent 为了修改一个函数,要读取一个 900 行的文件——之后每轮还得为这个文件再次付费。**每次都会重新发送整段对话,因此,早期读取并非一次性成本,而是持续的租金。
Slimdex 是一个本地 MCP 服务,为编码 Agent 提供精准检索:文件大纲、单个符号的内容、哪些代码会调用它、修改后会破坏什么,以及能跨会话保留的记忆,让下一次聊天一开始就掌握相关信息,而不是从零重新分析代码仓库。
claude mcp add slimdex -- npx -y slimdex-mcp
日常使用中可减少约 50% 的 token——导航密集型工作约减少 55–60%,输出密集型工作约减少 45%,在其专为应对的最糟情况(通过一个骨架和 12 个符号的内容来探索一个 6,200 行的文件,而不是完整读取四次)中可减少 85–90%。
**状态:1.1.0,已发布到 npm,并已列入 MCP Registry。**这些数据是在实际运行过的代码仓库中自行测得的,基于单次会话,未经独立验证——而且
stats统计的是字符数,不是 token 数。 依赖这些数据前,请先阅读实际验证情况。 | 工具 | 返回内容 | |------|-----------------| |index_repo| 构建或刷新持久化的符号和导入索引;仅重新解析有变更的文件 | |outline_file| 单个文件的声明及行号 | |get_file_skeleton| 保留嵌套结构的签名,函数体省略 | |read_lines| 一个行范围,默认上限为 6,000 个字符,并附带续读行;需要更多内容时设置maxChars| |get_symbol_context| 一个函数或类的函数体及其前后各 2 行,上限由maxLines决定;names:[...]可在一次调用中提取多个函数体 | |search_code|path:line:col+ 带插入符高亮的匹配行;支持limit/offset/游标分页 | |find_definition| 符号定义位置,格式为path:line:col| |search_symbols| 模糊搜索符号名称,按精确匹配→前缀→子串→子序列排序 | |search_intent| 按 BM25 对符号进行自然语言查询排序(不使用嵌入)——根据代码的功能查找代码 | |context_pack| 一次调用:为主题中的符号排序、展示它们之间的关联,并在预算范围内打包排名靠前的函数体——一轮往返即可完成整个探索 | |find_references| 文本引用,格式为path:line:col,并附带外围函数 | |find_tests| 查看某个符号的引用中哪些位于测试文件;若没有,则发出警告 | |replace_symbol| 按名称定位并覆盖符号的函数体(无需重新发送旧代码);先创建快照,然后重新索引 | |get_context| 一次调用:按需获取定义、签名、调用方、导入项或依赖项,并受预算限制 | |repo_map| 按目录统计文件、行数和符号数量;使用path:可深入查看某个目录中最大的文件 | |changed_files| 有变更的文件,以及每个代码块对应的符号 | |dep_graph|imports/dependents/ Mermaid 图(通过root+depth进行广度优先搜索) | |stats| 按工具统计调用次数和响应大小(以字符计),以及读取比例和写入规范 | |batch| 在一个请求中运行多个调用 | |recap| 从服务的工具调用日志中自动重建以往会话的活动记录——即使没有保存任何内容也能使用 | |brief| 精简的会话开场摘要:仓库概览 + 从日志提取的重点 + 根据实时索引核实的近期结论(✓ 实时 / ⚠ 可能已过时);detail:"full"可展开回顾和记忆预览 | |digest_save/digest_get| 一次性保存精简的仓库架构速查表;读取时会逐个检查所覆盖文件的新鲜度,让下次会话无需重新探索 | |snapshot| 将未提交文件复制到.slimdex/snapshots/(在工作区有未提交变更时,index_repo也会每小时自动运行一次)——用于防范意外重置,不能替代提交 | |memory_save/search/list/delete| 将持久化笔记保存到.slimdex/memory.json|
下方的检索指南也包含在服务的 MCP instructions 中,因此
客户端会自动将其注入模型的上下文。
推荐的 Agent 工作流
在会话一开始先调用 brief,只需一次调用,就能了解仓库是什么、近期的会话在查找什么,以及哪些已保存的结论仍与代码一致(过时的结论会标记出来),让新对话一开始就有背景信息,而不是从零开始。然后调用 get_context("Foo"),一次响应即可回答“这是什么、谁会调用它、它依赖什么”。要了解整个领域而非单个符号,可调用 context_pack("how does auth work"),由服务端完成全部探索,并返回一个范围有限的单一信息包,其中包含相关符号、它们之间的联系以及最重要的函数体——这样只需一次调用和一条对话记录,而不是十次调用。只知道功能、不知道名称?——search_intent("parse the config file") 会通过 BM25 按意图对符号排序,无需嵌入。需要查看单个函数体时,可使用 get_symbol_context(如果文件相较于索引发生了变化,它会自行标记,因此无需重新读取文件来确认);查看文件结构时用 get_file_skeleton;需要精确源码时用 read_lines。编辑符号之前,先对它调用 find_tests,查看有哪些测试覆盖它;要重写整个函数,可使用 replace_symbol(只需发送新的函数体——不会为了定位编辑位置而重新发送旧代码)。使用 batch 将多项查询打包。每个搜索工具都接受 limit(默认值为 20)和 offset。
响应长度控制: get_context 的各个部分可通过 include 选择性启用(默认包括:定义、签名、调用方、导入——需要时可显式添加 body 或 dependents);调用方数量受 callerLimit 限制,响应长度受 maxChars 限制(默认值为 12,000)。每当触及上限,工具都会明确提示(例如 showing 3 of 68、truncated at maxChars=...),而不会悄悄丢弃数据。get_symbol_context 会以同样的方式通过 maxLines 限制代码范围;除非另有说明,否则 memory_list 会返回最新的 50 条事实,并以约 150 个字符的预览呈现,而不是完整内容(使用 memory_get ids:[...] 可展开查看,full:true 则会输出全部内容)。对于一个包含 18 条事实的存储,这意味着每次会话开始时的调用内容可从约 4,100 个字符增至约 18,600 个字符。
配置:<root>/.slimdex.json(可选)
{
"ignoreDirs": ["fixtures", "backend/src/main/resources/static/assets"],
"extensions": [".astro", ".vue"],
"suffixes": [".stories.mdx"],
"exclude": ["generated/", "legacy/vendor"],
"maxFileBytes": 2000000
}
suffixes 用于匹配文件名结尾,适用于无法通过扩展名识别的文件类型。Salesforce 元数据附属文件已内置支持:AccountSvc.cls-meta.xml、panel.js-meta.xml 和 Account.object-meta.xml 会被编入索引,而 pom.xml、web.xml 和 manifest/package.xml 不会——如果将 .xml 添加到 extensions,仓库中的所有配置目录都会被纳入。通过后缀匹配的文件会被编入搜索索引并可供读取,但不会提取符号。
配置会与内置忽略列表合并(node_modules、dist、.venv、.svelte-kit、Pods、.pytest_cache 等)。ignoreDirs 条目可以是一个纯目录名,用于匹配任意层级中同名的目录;也可以是包含 / 的路径,此时路径以仓库根目录为基准,并遵循目录边界(忽略 src/gen 不会连带忽略 src/generated)。index_repo 会回显已加载的配置,并对未知键、类型错误或无效 JSON 发出警告,因此拼写错误的配置不会被悄悄当作未配置处理。
通常无需配置即可处理构建输出。 除目录列表外,任何单行长度超过约 5,000 个字符的文件都会被视为压缩后的构建输出,不纳入索引——打包工具会移除换行符,而手写源码不会如此。这能识别出目录名称列表无法通过结构判断的文件,例如位于 assets 目录中的哈希命名打包文件(index-B7xK2p9q.js)。assets、public 和 static 不会因目录名称而被忽略,因为其中可能包含真实源码;index_repo 会报告数量,格式为 skipped(minified build output): N。
令牌节省的原理
这里没有压缩技巧。节省来自行为上的变化:这些工具让 Agent 检索大纲、代码范围和位置,而不是读取整个文件;持久化索引则让重复查询命中缓存,而不必重新读取。
之后的两个会话分别由不同模型在不同形态的仓库中运行,为原报告补充了实际数据:
多文件 Web 应用,修复 Bug 会话(GPT-5.3-Codex)。 使用 Slimdex 后报告消耗 19 个额度;模型估计相同范围的任务若不使用它会消耗 45–70 个额度。计算:19/45 → 19/70 ≈ 便宜 58–73%。反事实数据是模型估算值,并非实测 A/B 对比,仅供参考。
单个超大文件(folio-app:一个 6,200 行、313 KB 的 app.js)。
Slimdex 自身的统计:8 次调用共约 34,000 个字符 ≈ 9–10k 个令牌——先获取一个骨架(213 个签名),再获取仅约 12 个相关函数的函数体,其中 9 个通过一次 get_symbol_context names:[...] 调用获取。朴素路径:313 KB ≈ 78–85k 个令牌,需要被迫完整读取 3–4 次。计算:约 10k 对比约 80k ≈ 节省约 70k 个令牌,探索阶段减少 85–90%。Bug 的原因(存在导出路径,却没有匹配的导入路径)在打开任何函数体之前,就能从骨架的签名中看出来。
两者共同勾勒出缩放规律:节省量取决于朴素路径会带入多少无关代码。 单个超大文件是最佳情况;普通仓库的成本会便宜约一半到三分之二;由小文件组成的仓库则大致持平。和本文其他数据一样,也有常见注意事项:统计的是字符而非令牌(÷3.5–4),单次会话只能作为证据,并非基准测试。
上述两个数据都只衡量读取,这是成本较低的一半。 输出成本约为输入的 4–5 倍,因此不加节制的编辑比不加节制的读取浪费更多:通过通用编辑工具重写整个函数,意味着必须重新发送整个旧函数体,纯粹是为了让工具定位它。replace_symbol 按名称定位,因此这部分成本就消失了。stats 会在读取分布旁报告这一项,因为否则这种浪费并不可见——成本更高的路径仍然会产生正确的编辑结果,因此没有任何信号能表明你付出了过多成本:
write discipline:
replace_symbol: 0 call(s), 0 symbol(s) rewritten by name
changed outside slimdex: 12 file(s)
pre-edit checks (find_tests/dep_graph/get_context/changed_files): 0
外部编辑是通过比较两次 index_repo 运行之间的内容哈希变化推断出来的,因此这个数字也如实体现了它的局限:它能看出字节发生了变化,却无法判断是哪个工具更改的;人在另一个窗口中编辑也会计入。
整个工作流的实际区间
上述数据是单一场景下的探索阶段数据——也就是朴素路径会带入最多无关代码的最佳情况。若在完整的实际工作日中取平均,而不是只看探索阶段,节省幅度会更低:
- 约 55–60%,适用于以导航为主的工作——读取和理解代码库,此时窄范围检索最常取代整文件读取。
- 约 45%,适用于以输出为主的工作——大量编写新代码,此时代价中有更多来自服务端无法处理的生成过程(不过
replace_symbol现在也能减少写入侧的成本)。 - 平均约 50%,适用于日常使用。使用它的会话越多,节省就越明显,因为
brief和记忆功能意味着每次新聊天一开始就掌握上下文,而不必从头重新推导整个仓库。
在 IDE 中的多个会话间定期使用,效果最佳。
请将这些视为一个数据点,而非基准测试。 单个仓库、单个任务、各进行一次 A/B 测试、自行测量,没有重复测试或方差数据。实际效果很大程度上取决于 Agent 是否会实际使用窄范围工具,而不是退回到读取文件;这会因客户端和模型而异。如果想验证,可以重复此方法:在两个全新的会话中运行相同任务,一个明确要求只使用 Slimdex,另一个明确要求不要使用它,然后比较 /status 的缓存写入数据。
实际验证了哪些内容
特此说明,以免对 README 的其他内容过度解读。
由单元测试套件覆盖(npm test 会运行 23 个文件中的 224 项测试):
-
JS/TS 中的符号提取(包括 class 和对象字面量方法),以及 Python、Go、Rust、Java/C# 中的符号提取和注释跳过 —
symbols.test.ts -
提取 JS
import/require/export-from、Python 和 Rust 的导入 -
提取代码块,支持按花括号作用域和缩进作用域,并能识别字符串和注释(引号、模板字符串、
//、/* */、整行#)—extractBlock.test.ts -
导入解析、外部模块分类、反向边依赖项、Mermaid 输出,以及基于根节点 BFS 的深度范围 —
graph.test.ts -
搜索匹配格式、无重叠分页、逐行出现次数统计、精确总数、正则转义与拒绝 —
search.test.ts -
不透明游标往返转换和格式错误游标拒绝;解析器后端回退 —
pagination.test.ts -
区分大纲声明与控制流 —
outline.test.ts -
get_symbol_context的maxLines预算和截断提示 -
字符串/注释屏蔽和花括号深度跟踪 —
lexer.test.ts -
对所有 12 种受支持语言逐一提取 —
languages.test.ts -
索引缓存会一直返回同一个对象,直到索引被重写
-
加载
.slimdex.json:通过真实索引构建应用每个键;同时验证每种失败情况(无效 JSON、未知键、类型错误)都会显示警告,而不是默默忽略 —config.test.ts -
在真实临时 git 仓库中测试
changed_files:将变更块归属到符号、未跟踪文件、显式基础引用和格式化;未安装 git 时会正常跳过 —git.test.ts -
使用真实文件系统事件测试文件监视器:保存操作会经过防抖、重新索引,并写入磁盘上的索引 —
watch.test.ts -
导入之外的图边:为没有导入语句的代码创建名称引用边(class→所用 class、interface→通过依赖项关联的实现、trigger→handler),并为仓库 XML 中的声明式连线创建边(metadata-binding→class);排除注释/字符串中的提及,并按构建缓存 —
apexgraph.test.ts -
内存文件缓存会提供重复请求的内容而无需重新读取,并始终在磁盘内容变更后提供最新内容 —
fscache.test.ts -
检测 JS/TS/Python/Go/Ruby/Java/C# 中的测试文件惯例,规范化 Windows 分隔符,并确保普通源文件(
latest.ts、Contest.java)不会被误标记 —testlink.test.ts -
写入侧:替换符号代码块、保留尾部代码,并保留 CRLF 与 LF 行尾格式,避免编辑导致整个文件被重新排版并产生差异 —
edit.test.ts -
记忆过时检测:事实提及的符号/文件仍存在时标记为有效;仅在所有代码提及都消失时标记为过时;纯散文内容不做标记 — 另含简要内容合成 —
brief.test.ts -
意图搜索:camelCase/snake_case 分词,以及 BM25 排序;可根据意图词找出名称不同的符号,并将无关查询的得分评为零 —
intent.test.ts -
新鲜度:文件修改时间晚于其索引修改时间时会显示为过时(行号可能不准确);修改时间匹配时显示为最新;文件缺失时绝不会误报为过时 —
freshness.test.ts -
组装
context_pack:在同一捆绑包中包含标头、排名后的符号和正文;无匹配项时显示提示;字符预算门控仍确保包含第一个正文;并设有符号数量上限 —pack.test.ts -
架构摘要:摘要读取后被修改的覆盖文件会显示为过时;较新的摘要会显示为正常;支持覆盖范围和目录前缀筛选,并渲染最新/过时判定 —
digest.test.ts通过真实 MCP 服务进行端到端覆盖(integration.test.ts会通过 stdio 启动服务,针对临时 fixture 仓库运行,并断言输出):index_repo、repo_map、read_lines、get_file_skeleton、outline_file、get_symbol_context、find_definition、find_references、find_tests(命中 和无覆盖警告)、search_intent(意图排序)、context_pack(单次调用 打包)、digest_save/digest_get(往返验证新鲜度判定)、get_context(包括其maxChars上限)、dep_graph(导入 + mermaid)、batch、search_code、search_symbols、stats、brief、replace_symbol(先写入再查询的往返验证,以及 对未知符号的拒绝)、memory_save/search/list/delete往返验证、 路径逃逸防护,以及未找到时的处理路径。
CI 会在 Ubuntu + Windows、Node 20 和 22 上运行构建和两个测试套件。
**关于监视器测试的注意事项:**递归 fs.watch 与平台有关,因此
在始终不触发事件的文件系统上,watch.test.ts 会降级为记录日志并跳过——
与监视器本身的行为相同。在 Windows、macOS 和当前版本的 Linux 上,它会断言完整的保存→重新索引路径。
npm run smoke 仍然存在,但只能证明流水线正常运行——正确性断言在 integration.test.ts 中。
检查确认:src/ 中没有网络调用——不会有代码离开你的计算机。这一点你可以自行检查:
grep -rE "fetch\(|https?://|axios|http\.request" src/。
更多文档
位于 docs/:
tool-guide.md— 每个工具都用技术语言和通俗语言各解释一次, 并各配有一个示例,还介绍了组合工作流以及基于 mtime 的持久化工作原理tool-guide.html— 同一份指南的样式化独立页面,可在浏览器中查看token-savings-report.md— 原始 A/B 测量、测量方法以及如何复现agent-brain.md— 完整的操作规范,以易读文档的形式呈现agent-brain-slim.md— 应放入仓库的版本,作为 CLAUDE.md / AGENTS.md。内容自足且仅一页:节省阶梯、问题→工具表、记忆规范、会话卫生、诚实说明限制、环境变量开关。覆盖内容与完整版相同,但篇幅约为其 30%;工具规则采用密集表格,而非服务器已注入的段落。
语言覆盖范围
有两项测量,因为仅靠 fixture 几乎说明不了什么。
Fixture — 每种语言一个,统计开发者实际会跳转到的声明:65/65 个均已找到,0 个误报,由
test/languages.test.ts 固定验证。
真实第三方代码 — 对来自数百个真实软件包(React、Babel、Remix、Socket.io、Playwright、Three.js、 Emotion、zod、ajv …)的约 11,800 个文件进行提取,并与独立编写的声明判定启发式规则进行比较:召回率为 95.9%。你可以自行复现:
npm run audit -- ./node_modules # or any directory of code you didn't write
这个数字是下限,而不是评分——真实情况启发式规则会将一些非声明也计入,因此实际召回率略高。它的用途是捕捉回归问题并找到下一个实际缺口。
关于框架
审计中几乎没有失败项是框架特有的。框架会添加注解、装饰器和约定,但很少创造新语法。处理好语言本身,框架也就随之涵盖了——fflib 的 Application/Domain/Selector/Service/UnitOfWork 层可被完整提取(129 个声明),无需任何 fflib 专用规则。
唯一真正的例外是测试 DSL。vitest/jest/mocha/RSpec 文件通常没有任何顶层声明,因此整个测试目录过去索引结果都为空。现在,describe/it/test 标题会以 test 类型编入索引,这正是你在测试文件中实际需要跳转查看的内容。
只要仓库中某处存在相关引用,框架的语义就能通过图中的两个额外边来源还原:
- 名称引用边,适用于没有导入语句的语言(例如 Apex):如果一个文件的代码(屏蔽注释和字符串后)提到了另一个文件中定义的顶层类型,就会形成一条边。这使
implements可以回答“谁实现了这个接口”,也能将触发器关联到它实例化的处理程序类。 - 声明式接线边:框架保存在配置而非代码中的绑定(自定义元数据记录、流程定义)通常以 XML 形式存放在仓库中,类型名称则作为元素值。系统会扫描仓库中的 XML,查找已知类型名称(不包括 XML 注释),每个匹配项都会形成一条
metadata-file → class边,因此dependents可以回答“是什么将其接入”。
这两种扫描都会按索引构建缓存;对于不包含此类文件的仓库,开销为零。由 apexgraph.test.ts 覆盖。静态读取器无法看到的是仅存在于实时系统中的绑定——它配置在正在运行的组织或数据库中,从未检索到仓库里。如果它没有以任何形式存在于仓库中,就无法绘制对应的边;请改为搜索类型名称。
| 语言 | 扩展名 | 可识别内容 |
|---|---|---|
| JavaScript / TypeScript | .js .jsx .mjs .cjs .ts .tsx .vue .svelte | 类、接口、类型、枚举、函数、顶层箭头函数、类方法和对象字面量方法 |
| Apex | .cls .trigger | 类、内部类、方法(包括 @AuraEnabled、global、泛型返回值)、触发器 |
| Java | .java | 类、接口、枚举、方法、带前置 <T> 的泛型方法 |
| C# | .cs | 类、接口、结构体、异步方法和泛型方法、虚成员 |
| Kotlin | .kt | 类、数据类、接口、object、fun、suspend fun |
| Swift | .swift | 类、结构体、枚举、协议、func、static func |
| Python | .py | 类、def、async def、dunder 方法和带装饰器的方法 |
| Go | .go | 函数、接收者方法、结构体类型和接口类型 |
| Rust | .rs | 结构体、枚举、trait、fn、pub async fn、impl 方法 |
| Ruby | .rb | 类、模块、def、def self.x、attr_accessor/reader/writer |
| PHP | .php | 类、接口、trait、方法、函数 |
| Scala | .scala | 类、样例类、trait、对象、带修饰符的 def |
| C / C++ / Objective-C | .c .h .cpp .hpp .cc .m .mm | 类、结构体、枚举、自由函数(包括 K&R 花括号形式、指针返回值)、类外定义的 Foo::bar、构造函数/析构函数、命名空间、类函数式 #define 宏、typedef struct {…} Name、@interface/@implementation/@protocol |
性能
冷索引是完整解析;热索引是逐文件检查 mtime。在 Windows、Node 24 上测量。
| 仓库 | 文件数 | 符号数 | 冷索引 | 热索引 | 典型查询 |
|---|---|---|---|---|---|
| Salesforce DX org | 56 | 344 | 0.1 s | 15 ms | < 10 ms |
| Java + React 应用 | 356 | 1,713 | 0.42 s | 26 ms | 3–57 ms |
| 合成压力测试 | 5,000 | 50,000 | 1.5 s | 0.24 s | 5–22 ms |
索引保存在内存中,并由索引文件的 mtime 失效。没有这个缓存时,每次工具调用都会重新读取并解析整个索引——在 5,000 个文件的仓库中,每次调用会白白耗费约 20 ms,而且随着仓库规模增长,这个耗时也会增加。
find_references 是大规模场景下最慢的工具,因为它执行的是文本扫描,而不是索引查询。不过,现在会先进行字面内容预筛选:如果文件原始内容不包含要搜索的名称,就跳过拆分行和逐行正则匹配;在典型仓库中,大多数文件都会被跳过。如果大致知道要查找的位置,可使用 pathPrefix 限定范围,减少剩余的文件读取。
文件内容也由有字节数上限的内存 LRU 缓存提供(64 MB,每次命中时通过 mtime+size 验证),因此第二次扫描仓库,以及 Agent 实际在一个文件上执行的 skeleton→read_lines→context 流程,只需执行 stat(),而不必读取文件。
跨会话记忆
memory_save 会写入 <root>/.slimdex/memory.json,该文件会在进程退出后继续保留——某次对话中保存的事实,在下次会话重启后可由另一个客户端读取。只有当聊天端和编辑器都指向同一个 SLIMDEX_ROOT 时,两者才会共用一个存储。
不会自动捕获任何内容:服务看不到你的对话,因此 Agent 必须决定哪些内容值得保留。随附的 instructions 会指示 Agent 在新会话中先读取记忆,并在了解情况后保存决策、约束和注意事项——但这只是给模型的指导,并非保证。
已知限制
- 符号提取基于正则表达式和启发式规则,不是解析器或 LSP。它可能会漏掉不常见的声明,而
find_references执行的是文本匹配,可能会包含同名但无关的标识符。 - 符号和大纲提取现在会针对每行的遮罩副本运行,字符串和注释内容会被清空,因此模板字面量中形似声明的文本不再会被当作代码编入索引。声明也会按深度处理:只有顶层的
const x = () => …或type X = …才会计入,因为函数体内的局部变量不是人们会导航到的对象。类方法仍会按其嵌套深度编入索引。 - 内联 Python
#注释中如果包含花括号,仍可能干扰代码块提取(#也是 JS 私有字段的标记,因此不能不加判断地删除)。 changed_files会将代码块归到最近的前置声明名下——对于普通函数体是准确的,对于声明之间的代码则是近似值。应将其视为影响范围,而不是调用图。search_code会报告准确的总数,但在结果集非常大时会达到内部扫描上限,并显示N+ (scan cap reached),而不是给出一个看似确定但实际错误的数字。- 语言支持程度不一:JS/TS 覆盖最完善。C 系列和 Ruby 之前支持最少,现已增加专用规则(自由函数、
Foo::bar定义、类似函数的宏、attr_*);剩余的薄弱环节是高级 C++ 语法形式——跨行模板、运算符重载。 - 要达到 LSP 级别的精度,需要将解析器换成 tree-sitter 或语言服务器。
src/parser.ts是替换接口:由SLIMDEX_PARSER选择Parser接口的实现,随项目提供的只有正则解析器。tree-sitter 后端可以在此接入,无需修改任何工具或索引格式。它尚未构建——各语言的语法库会牺牲“即时安装、离线运行、零配置”的特性。
有意不实现的功能
经过评估后拒绝的想法及其理由——这些是设计观点,并非测量结果:
- 符号 ID 字典(
S42→ 路径)——MCP 没有客户端扩展层,因此模型会收到一个不透明的令牌,必须再花一次调用来解析。 - 令牌预算管理器 / 成本估算器——
chars/4的估算在不同分词器之间并不可靠,而且基于错误估算自动压缩可能会丢弃模型需要的数据。 - 增量 /“已发送,参见响应 #5”缓存——上下文压缩后,早前的载荷已不复存在,因此该引用什么也找不到。
- 嵌入 / 语义搜索——依赖项占用较大;未来可以考虑作为可选标志,但不会设为默认功能。
- tree-sitter 解析器后端——这是唯一能弥补剩余约 4% 的方案,我们评估了成本,并非凭空带过:
web-tree-sitter基于 WASM,无需原生编译,但语法包(tree-sitter-wasms)解压后有 51.7 MB,而当前整个安装包约为 4.5 MB。在实测召回率为 95.9% 时,我们评估后决定不采用,因为“秒级安装、离线运行、无需配置”正是此服务存在的意义。若今后情况有变,src/parser.ts仍保留了接入点——只需在那里替换后端,无需改动任何工具或索引格式。
安装
已在 npm 上发布,包名为 slimdex-mcp,
并以 io.github.Siddhukaushik/slimdex-mcp 列入 MCP Registry。
无需构建——让客户端连接到:
npx slimdex-mcp
或者,如果你想参与开发,也可以从源码开始:
git clone https://github.com/Siddhukaushik/slimdex-mcp
cd slimdex-mcp
npm install
npm run build # produces dist/index.js
npm test # vitest unit suite
验证它能否针对某个代码仓库端到端运行:
npm run smoke # this repo
node smoke-test.mjs "C:/path/to/some/repo" # any other
环境变量
| 变量 | 作用 |
|---|---|
SLIMDEX_ROOT | 要建立索引的代码仓库(或作为第一个 CLI 参数传入;默认为当前工作目录) |
SLIMDEX_WATCH | 设为 1,在文件保存时自动重新建立索引(原生监视器,无依赖项) |
SLIMDEX_PARSER | 解析器后端;目前只有 regex |
SLIMDEX_PRETTY | 设为 1,恢复详细且便于人工阅读的呈现方式:在 search_code、find_definition、search_symbols、find_references、repo_map、read_lines、outline_file 中使用更长的标题和列填充。精简模式为默认设置——这些填充会占用上下文,模型在后续每一轮都要为其付出代价。SLIMDEX_TERSE=0 效果相同。 |
SLIMDEX_PROFILE | lean 会公开 15 个工具,而非 29 个,从而将每轮重新发送的工具架构从约 22,300 个字符减少到约 12,600 个字符。其他 14 个工具(get_context、changed_files、find_tests、dep_graph、outline_file、search_symbols、recap、memory_list、memory_search、memory_delete、digest_save、digest_get、snapshot、stats)仍可使用,并通过 batch 调用——服务器指令也会在此配置下列出这些工具,因此模型会被告知哪些工具只能通过 batch 调用,而不必自行摸索。默认为 full。 |
SLIMDEX_NO_DEDUPE | 设为 1 可禁用重复响应抑制(对于未更改文件,第二次相同的 read_lines/get_file_skeleton/outline_file 调用会返回指向早前调用的指针,而非正文;第三次相同调用会重新完整输出)。 |
持久化缓存
对于每个代码仓库,Slimdex 会写入 <repo>/.slimdex/:
index.json——代码索引(按文件根据 mtime 失效;索引格式版本变更时会整体丢弃,因此绝不会复用由较旧提取器构建的过期索引)memory.json——已保存的记忆事实stats.json——各工具的使用计数器
该目录会忽略自身:目录内会写入一个仅含 * 的 .gitignore(node_modules/.cache 的做法),因此它永远不会出现在 git status 中,也无需修改代码仓库自己的 .gitignore。如果你想要提交缓存,删除这个内部文件即可。
将其接入 MCP 客户端
MCP 是一项通用标准,因此同一个服务应能接入任何支持 MCP 的
客户端。项目根目录通过 SLIMDEX_ROOT(或作为第一个 CLI
参数)传入。
实际上只在 Claude Code 和 Claude Desktop 中运行过。 下方其他 客户端的配置均采用各自的标准格式,根据其文档编写——尚未在此处测试, 可能需要调整。
从 1.0.0 起,最简单的接入方式是 npx -y slimdex-mcp——无需克隆、无需构建,
且会保持最新。下方示例保留了 node <ABS_PATH> 的形式,供从源码运行的用户使用;
若要改用已发布的包,请将
"command": "node", "args": ["<ABS_PATH>"] 替换为
"command": "npx", "args": ["-y", "slimdex-mcp"]。
将 <ABS_PATH> 替换为构建输出路径,例如
C:\path\to\slimdex-mcp\dist\index.js,并将 <REPO> 替换为要建立索引的仓库。
无需调整设置。 各客户端默认启用了所有重要的节省措施:记忆事实列表以预览形式呈现,响应简洁,对未更改文件进行相同的重新读取时会返回指针而非正文,多个符号编辑会合并在一次调用中。下方的环境变量用于选择退出这些设置,或启用 lean——它可每轮进一步节省约 8,700 个字符,但会将三分之一的工具路由到 batch,因此有意不设为默认选项。
Claude Code(CLI)— 已测试
claude mcp add slimdex --env SLIMDEX_ROOT=<REPO> -- npx -y slimdex-mcp
从源码运行:-- node <ABS_PATH>。
Claude Desktop — 已测试
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"slimdex": {
"command": "npx",
"args": ["-y", "slimdex-mcp"],
"env": { "SLIMDEX_ROOT": "<REPO>" }
}
}
}
Codex CLI — 已测试
~/.codex/config.toml
[mcp_servers.slimdex]
command = 'C:\Program Files\nodejs\node.exe'
args = ['<ABS_PATH>']
startup_timeout_sec = 30
按这种方式全局注册后,slimdex 会附加到每个 Codex 任务,并将该任务的工作目录用作仓库根目录——无需设置 SLIMDEX_ROOT。Codex 会在受限环境中启动服务,因此请为 command 提供 node 的绝对路径,而不要依赖 PATH。
Cursor — 未测试
.cursor/mcp.json(项目级)或 ~/.cursor/mcp.json(全局)
{
"mcpServers": {
"slimdex": {
"command": "node",
"args": ["<ABS_PATH>"],
"env": { "SLIMDEX_ROOT": "${workspaceFolder}" }
}
}
}
Windsurf — 已测试
~/.codeium/windsurf/mcp_config.json — 与 Cursor 使用相同的 mcpServers 结构。
VS Code(Copilot / MCP)— 已测试
.vscode/mcp.json
{
"servers": {
"slimdex": {
"command": "node",
"args": ["<ABS_PATH>"],
"env": { "SLIMDEX_ROOT": "${workspaceFolder}" }
}
}
}
Cline(VS Code 扩展)— 已测试
Cline 设置 → MCP Servers → 添加:
{
"slimdex": {
"command": "node",
"args": ["<ABS_PATH>"],
"env": { "SLIMDEX_ROOT": "<REPO>" }
}
}
Zed — 已测试
settings.json → context_servers
{
"context_servers": {
"slimdex": {
"command": { "path": "node", "args": ["<ABS_PATH>"], "env": { "SLIMDEX_ROOT": "<REPO>" } }
}
}
}
对于可获取工作区文件夹的客户端(Cursor、VS Code),
${workspaceFolder}可让 Slimdex 始终指向你当前打开的仓库。
典型 Agent 工作流
- 在开始时运行一次
index_repo(后续运行会更快),然后运行brief,从上次会话继续;过时的笔记会预先标记出来。 - 运行
repo_map→ 了解项目概况。 - 对感兴趣的文件运行
outline_file→ 选择行范围。 - 使用
read_lines只读取这些范围。 - 使用
find_definition/find_references/dep_graph进行导航。 - 编辑符号前运行
find_tests;使用replace_symbol重写符号,无需重新发送其旧正文。 - 使用
memory_save保存决策和注意事项,让下次会话一开始就掌握相关信息。
许可证
MIT © 2026 Kael VK Inc.(Business Number 751569161 RC0001)— 参见 LICENSE。
按原样提供,不作任何保证,也不提供支持。如果无法构建、无法运行,或无法在你的环境中正常工作,责任由你承担——请参阅许可证中的免责声明。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。