对 474 个 MCP 服务器 72 小时内的 schema 变化测量发现,变化呈非线性分布——少数活跃服务器频繁迭代,大多数保持冻结;变化一旦发生不会回滚。
两天前我测量到 4.4% 的 MCP 服务器在 36 小时内改变了工具契约,但我拒绝了将这个数字年化的做法,理由是改动可能会集中发生。
现在我有了第三个快照,而我的谨慎被证明得比预期更有正当理由。
同样的 474 个服务器,三个快照:基准线、+36小时、+72小时。
在前 36 小时内,21 个服务器发生了改动。在接下来的 36 小时里,又有 3 个做了改动。一个恒定的独立速率应该会预测到第三天有 42 个。实际数字是 24 —— 线性预测的 57%,差距随着外推时间的增加而扩大。
与对比中还出现了两件其他的事:
21 个中没有一个回滚过。一旦契约改动了,它就保持改动。这些是有意的改变,不是抖动。
21 个中的 3 个在第 36 小时到 72 小时之间再次改动。那些改动的服务器会继续改动。
这不是"MCP 服务器以大约 3% 每天的速率改动"。实际情况是:
一小部分活跃开发的服务器不断改动,而大多数服务器实际上是冻结的。
第一个快照在一次通过中捕获了几乎整个易变子集。之后的一切都是在一条薄得多的缝隙中刮取 —— 少数真正的新参与者,加上来自同一小撮的重复变化。
如果你把我最初的数字年化,你会得出结论说大多数注册表在一个月内重写自己。那是错的,而且是朝着让你构建错误事物的方向错:不断地重新验证所有东西,而你真正需要的是识别那大约 5% 的会改动的东西并持续监视它们。
我对 inputSchema 进行了哈希处理。在上一篇文章中 anp2network 指出,tools/list 在服务器声明了结构化输出时也会携带 outputSchema,而它对任何调用方解析结果的约束也同样严格。
这是对的,我没看到这一点。所以我测量了声明的接口:
只有 18% 的工具根本声明了输出契约。这既有优点也有缺点:对于这 18% 的工具,输出漂移是一个真正的风险,而对于其他 82% 的工具,根本就没有声明的契约可以破坏 —— 你在解析返回的任何东西并寄希望于幸运。
我认为 82% 是更大的问题,而且它不会在任何漂移测量中显现,因为根本没有什么可比对的。
zira125 建议分别对 inputSchema、outputSchema、description 和 annotations 进行哈希处理,并对改动进行分类,而不是把每个哈希不匹配都当作同样严重的问题 —— 附加的可选字段发出警告,必需字段的添加和枚举缩小则失败。这显然是对的,我的人口普查第二版现在分别捕获了这四个字段。
komo 阐述了部署的形状:将契约作为构建工件进行快照,当哈希移动时快速失败。Mads Hansen 指出了我之前略过的东西 —— "工具添加"不是自动安全的,因为新的重叠工具改变了选择,可能会静默地重定向曾经去往其他地方的调用,即使每个旧调用仍然验证通过。
这三者共同构成了比我开始时更好的规范。有用的版本不是一个在定时器上重新检查所有东西的监视器。它是:
按严重程度分类,不要在每个 diff 上报警。
密切监视易变子集;冻结的多数需要很少的检查。
跟踪所有四个接口,将输出契约的缺失视为其自身的风险。
474 个服务器在所有三个快照中都可比较,来自 5,346 个完成匿名握手的注册表端点的有种子随机样本(random.seed(20260730)),所以每次重新运行都会命中相同的服务器。initialize → notifications/initialized → tools/list,处理 SSE 帧并调度 Mcp-Session-Id。每个接口 SHA-256,排序的键。
三个快照足以看出直线是错误的模型。但不足以说出正确的模型是什么。我会继续获取它们。