MCP server 可能在演示通过后悄悄改 tool 名称或 inputSchema,导致 agent 行为不可预测;建议对工具声明做结构校验并保留快照比对。
An MCP server 可以通过一个 happy-path demo,但仍然会交付一个让 agent 行为变得不可预测的合约变更。工具名多了一个空格。inputSchema 在重构过程中消失了。生成的列表返回的顺序与你审查时的构建不同。
困难的部分不是再写一个单元测试。而是在允许 agent 发现可以触碰真实系统的工具之前,先决定哪些必须保持稳定。
我的建议很小:对每个工具声明做结构校验,然后保留一份已审查的有序工具表面快照。这个快照不能替代集成测试或人工审批。它只是一个廉价的警报,用于捕捉普通 handler 测试经常漏掉的部署漂移类问题。
当前的 MCP tools 规范指出,工具具有唯一名称和 inputSchema,并建议使用确定性的工具顺序,以便客户端可以可靠地缓存工具列表。它还要求人类能够拒绝工具调用。MCP Tools 规范

我建议放在部署前的关卡
在生成或组装服务器 tools/list 输出后运行这个检查,不只是针对 TypeScript 类型。它检查 MCP 客户端实际会看到的 payload。
type Tool = {
name: string;
inputSchema?: { type?: string } | null;
};
const toolName = /^[A-Za-z0-9_.-]{1,128}$/;
export function assertToolContract(tools: Tool[], approvedNames: string[]) {
for (const tool of tools) {
if (!toolName.test(tool.name)) {
throw new Error(`Invalid MCP tool name: ${tool.name}`);
}
if (!tool.inputSchema || tool.inputSchema.type !== "object") {
throw new Error(`Tool ${tool.name} needs an object-root inputSchema`);
}
}
const names = tools.map((tool) => tool.name);
if (JSON.stringify(names) !== JSON.stringify(approvedNames)) {
throw new Error("Tool surface changed: review the ordered tools/list snapshot");
}
}
这有意不去判断一个工具是否安全。它只是让已声明的接口变更可见。授权、输出校验、测试数据、速率限制和人工审批仍然需要各自独立的控制。
我生成了 240 个合成的三工具服务器表面,然后对每个应用了五个故意的变更:包含空格的名称、缺失的 schema、null schema、数组根 schema,以及变更的工具顺序。这产生了 1,200 个注入的合约变更。
研究比较了两种检查:
从保存的确定性研究输出生成的证据图片。它是合成变更研究,不是生产遥测数据。
结果在定义测试之后并不令人惊讶:基本检查并非设计用来标记顺序变更。这正是关键所在。如果顺序对你的客户端重要,部署审查需要比较它。如果不重要,明确省略该规则并说明。
完整方法、种子、行和限制都包含在 research/mcp-contract-drift-2026-08-22/ 中。用以下命令重新运行:
node scripts/run-mcp-contract-drift-study.mjs
MCP 不会将列表顺序变成通用的正确性规则。客户端可以选择自己的行为。但确定性声明在几个实际场景中减少了意外的变更:
规范在底层集合未变更时明确推荐确定性顺序。将其视为运维手段,而不是安全保证。MCP Tools 规范
一个常见错误是把这整个称为「MCP 测试」。它只是其中一层。
2026 年 7 月的 MCP 候选版本还描述了向 JSON Schema 2020-12 的完整迁移,用于工具的输入和输出 schema。这提升了测试序列化声明的价值,而不是假设源类型能说明全部故事。MCP 候选版本说明
对于审查步骤,我使用带有边界任务的 prompt:
Given this tools/list JSON and the approved ordered-name snapshot, identify only contract drift. Return PASS or a list of changed names, missing schemas, invalid root types, and order changes. Do not recommend calling any tool.
输入:候选的 tools/list payload 加上版本控制中的 approvedNames。
确定性运行的观察输出:结构检查器检测到 960/1,200 个变更;加上有序名称快照后检测到 1,200/1,200。agent prompt 是审查辅助工具,不是真相来源——代码关卡仍然是权威的。
研究故意收窄了范围。它不能证明工具产生了正确答案、客户端理解了复杂 schema,或授权是正确的。它没有使用真实服务器或真实模型任务完成。它还将顺序漂移视为设计相关的;对于客户端不在乎顺序的团队,不应该通过强制执行来制造噪音。
更重要的一种失败模式是社会性的:一个绿色的合约关卡会造成一种自信,让人以为没有人审查过 action 本身。让人类审批边界靠近有影响的工具调用,正如协议的交互指导所建议的那样。
从你已有的工具表面开始。保存一份已审查的快照。在意外漂移时让构建失败。然后在工具可以变更客户数据、花费金钱或交付代码的地方添加行为和授权评估。
Disclosure: Human strategy, research design, code review, and editorial judgment led this article. AI assisted drafting and editing.