WARDEN 新版突出 MCP 工具指令变更
WARDEN 首次审核时固定 MCP 工具定义,后续发生变化便阻止服务器使用,直到人工重新批准。0.18.0 将变更内容优先显示,帮助审查者发现藏在长描述中的行为调整,例如发布操作改为直接使用支付正式模式。
AI 深度解读
你批准过的 MCP 工具,之后可能悄悄换了一套给模型看的指令。原文举了一个发布工具的真实变化:原先涉及 Stripe test mode 的移动端测试构建,改成始终发布到 live,并要求模型不要再问用户选测试还是正式环境。
WARDEN 0.18.0 解决的是审批时的可读性:把藏在整段 JSON 里的改动,直接标到眼前。它没有因此变得更会判断风险,但能帮助审批者看清自己到底在批准什么。这对接入发布、支付、文件操作等 MCP 工具的团队很有参考价值。
批准过工具,不等于批准它以后的每句话
9 月 29 日,一个拥有 45 个工具的 MCP server 修改了 publish_app 的描述。新文本明确要求:始终发布 live,包括 Web、已构建的移动应用,以及 Stripe live mode,并且不要询问用户选择 test 还是 live。
作者明确说,这不是攻击。服务端调整了发布行为,也相应更新了工具说明。
问题在于,模型会把工具描述当作行动指导。对人来说,这是服务说明更新;对 Agent 来说,其中的「never ask」直接改变了下一步该不该询问用户。
工具描述既是文档,也是模型执行任务时接收的指令。
WARDEN 的处理方式是固定工具定义,也就是 pin:首次审核后记录定义,后续只要发生变化,就阻止该 server 继续使用,直到人工重新批准。
这套机制在 0.18 之前已经存在。新版本改变的是审核界面。以前,审批者看到的是新旧两行完整 JSON;上述案例合计 6,614 个字符,关键句埋在第二行中间。现在,WARDEN 0.18.0 会先显示差异,再附上完整定义供核对。按原文时间线,该版本于 10 月 21 日上线 npm。
这里要区分两件事:发现定义变了,靠的是原有的固定机制;让人容易看懂变了什么,才是这次更新的重点。
「只改了数字」为什么也不能直接放行
作者团队维护的 HISTOR 会每天读取官方 MCP registry 中远程 server 的工具列表,并对 npm、PyPI 的 MCP 包逐版本在沙箱中运行。
其 2026-10-20 公开快照记录了 9 月 24 日至 10 月 20 日之间的 23,821 次变化。原文称,约每八次变化就有一次只涉及数字。
数字变化很容易制造审批疲劳。计数、日期、平均值不断更新,每次都展示两大段 JSON,人很快就会习惯性点通过。但数字也可能决定费用和调用边界。
例如,get_api_external_search 的描述把每次调用的平均 Credits 从约 0.84 改成约 0.81。同一段说明还写着,每次返回最少 1 个、最多 10 个商品。这些都只是数字,却对应不同含义。
另一个酒店工具 book_hotel 把人数限制从 JavaScript 安全整数上下界,收紧到 1–10:
maximum从9007199254740991改为10。minimum从-9007199254740991改为1。- 人数字段的描述也补上了
1-10。
所以,WARDEN 会标记 numbers only,但仍然要求审批。它不知道某个数字是无关紧要的计数,还是价格、额度、人数限制。
原文还有一处应当保留的纠错:0.18.0 changelog 曾写「52% 的变化涉及描述」「23% 涉及工具增删」,作者重新统计后无法复现这两个数字,并表示会修正。提供的正文缺少它提到的统计表,因此不能把这两个比例继续当作结论引用。
差异能看清,不代表风险已经判断完
WARDEN 0.18 对不同字段采用不同展示方式:
描述和 schema 中的字符串显示词级差异,用 [-删除内容-] 和 {+新增内容+} 标注;普通值显示字段路径和前后值,例如 inputSchema.properties.days.maximum: 7 → 365;required、enum 这类简单列表显示增删项,例如新增必填的 api_key。新增、移除的工具也会单独列出。
这比只比较描述更完整。工具可能名字和说明都没变,却多了必填参数,或者扩大了允许操作的范围。
作者也统计了指令性措辞:在 23,821 次变化中,有 2,345 次、涉及 1,744 个 server,出现工具描述中「always」「never」「must」「do not」「don't」等表达增加的情况。
这只是词句统计,不是恶意判定。登录工具要求确认期间继续轮询,报价表单要求不要询问手机号,都可能有合理原因。真正需要审核的是这些句子改变了什么行为。
作者对差异算法做过可复核的检查:快照中的 59,287 条工具描述变化,都能从差异结果逐字符还原旧文本和新文本,结果是 59,287 / 59,287;单次最慢耗时为 12 ms。这里统计的是工具描述变化,与前面的变化记录数不是同一口径。
这些数据支持「差异没有漏字、错引」和该样本中的运行耗时,不能证明它识别出了危险指令。
实现也有边界:每个工具最多展示 200 个变化值,超出后提示查看完整定义;特别长的重写会保留共同开头和结尾,把中间作为整体替换。CI 使用 scan --lock 时仍然查看 warden.lock.json 的 Git diff,流程没有变化。
我的判断
我认可这次更新的方向。工具更新可能完全合理,但合理更新仍可能改变 Agent 的授权范围。审批者需要先看见变化,才谈得上作出判断。
更容易读懂的差异,是审批所需的信息,不是安全结论。
和只固定 MCP 包版本相比,固定工具定义能覆盖远程 server 更新描述的情况;和单独依赖扫描器相比,它把「新定义是否被扫描判为可疑」与「人是否接受这次变化」分开。这两件事确实应该分别处理。
不过,作者没有提供审批耗时、漏审率,或与完整 JSON 审核的对照数据。因此,「这种展示能改善团队审核效果」目前仍是有道理的经验判断,不能写成已经验证的收益。
人工审批本身也有前提。pins approve 要求 TTY,可以防止 Agent 意外批准自己的工具;但能分配 PTY 或修改 WARDEN 状态的本地进程,仍可能绕过去。终端交互不等于身份认证。
另外,原文说得很明确:默认固定策略下,数字变化也会阻断;但配置 pinToolDefs: false 的策略,仍会自动公告审核通过且被判为干净的变化。评估接入方案时,需要先看实际配置,不能只看产品默认描述。
能拿来做什么
-
给日常 AI 编程环境做一次工具盘点。原文提供的命令会扫描 Claude Code、Claude Desktop、Cursor、VS Code、Windsurf 等客户端已经启动的 MCP server:
npx -y @aimarket/warden@0.18.0 scan注意这里指定的是
@0.18.0;运行扫描本身不等于已经给每个 server 加上人工审批。 -
对需要人工确认定义变化的工具,在客户端 MCP 配置中加入包装层。原文以文件服务为例:
"filesystem": { "command": "npx", "args": ["-y", "@aimarket/warden@0.18.0", "wrap", "--id", "filesystem", "--require-approval", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"] }关键是
--require-approval。之后用warden-mcp pins status --id filesystem查看变化,再用warden-mcp pins approve --id filesystem批准;示例目录需要按实际用途调整。 -
审核发布、支付或文件工具时,优先阅读行为边界的变化,包括「是否询问用户」、test/live、必填项、价格和数值上限。不要因为显示
numbers only就跳过,也不要因为出现「never」就直接判断为攻击。 -
如果在 Node 项目里自建审核界面,可以使用库导出的
diffToolDefinitions、formatDefinitionDiff和wordDiff。status_mcp_server也会返回结构化的changes与可读的reviewText,适合把差异接到已有审核流程中。