给代码 Agent 一张可按需展开的仓库地图
Sentinel-IR-MCP 新增 TypeScript、TSX 支持,通过紧凑目录摘要帮助 Agent 按需读取代码。新版还显式标注分析不完整或跳过的文件,避免把未知状态误判为低风险。
AI 深度解读
AI 编程助手接手仓库,是否必须先读一大堆源码?Sentinel-IR 的思路是先生成结构地图,让 Agent 看清模块、路由和敏感操作,再按需读取文件。Sentinel-IR-MCP 0.2.0 把 TypeScript、TSX 接入这套流程,0.2.1 则补上一个更关键的能力:明确告诉使用者,哪些文件没有分析完整。
这篇值得读的地方,不只是节省上下文,而是它把「没发现风险」和「根本没看明白」分开了。对准备给 AI 接入代码分析工具的程序员,这比一个漂亮的风险分数更有参考价值。
先给 Agent 一张地图,能省掉什么
Sentinel-IR 是分析库,负责把源码转换成紧凑的中间表示(IR)。它提取 imports、exports、路由、环境变量读取,以及文件系统、网络、进程和加密相关调用,同时给出规则识别到的风险和解析状态。
IR 不是逐行解释代码,而是一份结构索引:文件依赖谁、暴露什么、哪里可能需要进一步检查。Agent 据此选择下一批要读的源码,减少为了找入口而进行的无差别阅读。
Sentinel-IR-MCP 通过 Model Context Protocol(MCP)暴露三个工具:
analyze_code分析客户端提交的源码,支持可选的target和language。analyze_file读取允许目录内的单个受支持文件。analyze_directory扫描目录,接受目录路径、max_files和recursive,按风险返回文件摘要。
MCP 提供统一调用接口,并不会让分析规则自动变聪明。结果同时通过 JSON 文本和 structuredContent 返回,客户端 SDK 支持时,可以直接使用后者。
0.2.0 新增 .ts、.mts、.cts、.tsx,原有 JavaScript 扩展名是 .js、.mjs、.cjs。文件工具根据扩展名选择解析方式;直接提交文本时,target 可以提供文件名,显式 language 可以覆盖默认选择。
这对 TSX 项目很实际:类型断言、TypeScript 声明和 TSX 语法都需要对应的解析能力。作者还保留了 JavaScript 原有分析路径,避免新增语言支持时悄悄改变已有结果。
低风险与分析完整,必须分开看
0.2.1 的重点是目录报告的可信程度。它区分三种结果:
完整分析表示解析完成,但不保证程序安全;不完整分析表示已经产出 IR,却没有顺利解析整个文件;跳过则表示读取或分析抛出异常,没有正常结果可加入列表。
风险等级描述已识别的行为,分析状态描述工具看懂了多少。
原文这段简化输出,展示了为什么两者必须并存:
{ "analyzed": 3, "truncated": false, "riskCounts": { "critical": 1, "high": 0, "medium": 0, "low": 2 }, "statusCounts": { "complete": 2, "incomplete": 1 }, "incomplete": [ "src/broken.ts" ], "skipped": { "tooLarge": [], "symlinks": 0, "unreadable": [ "src/locked.js" ] }, "files": [ { "path": "src/run.ts", "analysisStatus": "complete", "language": "typescript", "risk": "critical" }, { "path": "src/broken.ts", "analysisStatus": "incomplete", "language": "typescript", "risk": "low" }, { "path": "src/ok.ts", "analysisStatus": "complete", "language": "typescript", "risk": "low" } ] }
重点看 src/broken.ts:它同时具有 risk: "low" 和 analysisStatus: "incomplete"。低风险不能覆盖解析缺口。src/locked.js 没有正常分析结果,因此 analyzed 是 3,不是 4。
新增的 incomplete 按路径去重、排序;原有 files 继续按风险排序。statusCounts.complete + statusCounts.incomplete 等于 analyzed,riskCounts 各项之和也等于 analyzed。跳过文件不参与这些计数。
这是一次增量式 API 演进:保留旧列表的结构和排序,新增一份专门回答「哪里没分析完」的视图。0.2.1 没有修改底层 Sentinel-IR 库及其 IR 契约。
另一个修复是逐文件隔离异常。此前一个文件读取失败可能让整个目录分析失败,现在会记录路径并继续。不过,skipped.unreadable 同时接收读取异常和分析器异常,不能看到名字就认定是权限问题。未来若要区分 readErrors 与 analysisErrors,还需要单独设计。
接入很短,判断覆盖范围不能省
服务器要求 Node.js 20 或更新版本。原文给出的 Cursor 项目配置可以放入 .cursor/mcp.json:
{ "mcpServers": { "sentinel-ir": { "command": "npx", "args": [ "-y", "sentinel-ir-mcp@0.2.1", "${workspaceFolder}" ] } } }
要关注 sentinel-ir-mcp@0.2.1 和 ${workspaceFolder}:前者固定已验证版本,后者指定允许检查的项目目录。Claude Desktop 的 claude_desktop_config.json 使用同样的 mcpServers 结构,但示例路径是 /absolute/path/to/your/project;应合并配置,再按客户端要求重启或重载。删除 @0.2.1 才会跟随 npm 最新版。
分析有明确边界:默认单文件上限为 1 MiB,目录默认最多 50 个文件,可配置最大值为 500;遍历跳过 node_modules、.git、隐藏目录和符号链接,并拒绝解析后位于允许根目录之外的路径。
这些限制也会影响结论。truncated: true 表示达到 max_files 后停止收集,报告不能当成完整清单。不可读的候选文件同样占用 max_files 名额,因为限制发生在收集阶段,而非分析完成之后。超大文件记录在 skipped.tooLarge,符号链接另有跳过计数。
所以,报告数字对得上,不代表仓库扫全了;仓库扫全了,也不代表每个文件都解析完整;全部解析完整,更不代表规则能识别所有危险行为。
服务只读,不执行源码、不运行 shell 命令,也不在分析过程中打开网络连接。但工具的只读注解不能代替实现检查和目录配置。IR 虽然不复制完整注释、函数体或字符串体,仍包含模块名、导出名、路由等不可信内容,不能把它当成可信指令。
我的判断
我认可作者把不确定性放进正式输出的做法。相比只返回风险列表,它更适合进入 Agent 工作流:客户端有机会主动补读文件,并在最终报告中说明缺口。
节省 token 的数字则需要收着看。README 使用 sentinel-ir@0.1.3 的四个源码文件,经 MCP stdio 运行,并用 o200k_base 计数:原始源码合计 11,564 tokens,IR 为 317,减少约 97.3%。这是具体样本,不能直接外推到所有仓库。原文还提到每文件 IR 约有 120 tokens 的开销下限,小文件单独摘要未必划算。
作者报告在 Node 20、22、24 上本地测试为 29/29;CI 是 28 项通过、1 项跳过。跳过项依赖真实 chmod 000 文件,而 CI 以 root 运行仍能读取,因此另有模拟读取失败覆盖异常路径。发布报告还称通过官方 MCP 客户端验证过混合目录结果。这些证据支持输出一致性和故障隔离,尚不能证明 Agent 完成任务更快、更准。
与直接搜索文件名、符号、调用位置相比,结构摘要增加了一次分析和信息压缩。对入口不明确、希望发现敏感操作的任务,它可能有用;对已经知道目标函数的小改动,直接搜索和读源码也可能更省事。原文没有给出这些工作流的对照数据,也没给出任务成功率、相关文件召回率和端到端延迟,因此效果仍需在自己的项目上验证。
能拿来做什么
- 在 TypeScript、TSX 仓库的 AI 审查流程中,先调用
analyze_directory,先检查truncated、skipped、statusCounts和incomplete,再安排源码阅读顺序。 - 对 Node 项目优先查看
critical、high文件的forbidden和facts,同时逐一处理incomplete路径;必要时调用analyze_file,仍不完整就通过客户端允许的方式读取源码。 - 接入自己的 MCP 客户端时固定
sentinel-ir-mcp@0.2.1,优先读取structuredContent,并让最终报告分别列出已分析、跳过和未完整解析的范围。 - 用项目中的真实任务比较「直接搜索读源码」与「先摘要再读源码」,记录任务完成情况、相关文件是否遗漏、总 token 和延迟,再决定是否长期加入日常 AI 编程流程。