跳到主要内容

MCP 服务端坟场:当你的智能体依赖停止更新时

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的 Agent 每五分钟调用一次的 MCP 服务,其最后一次 commit 还是在八个月前。它所封装的上游 API 在二月份推出了新的身份验证模型。目前有 47 个未解决的 issue,其中 12 个被标记为安全风险。维护者的 GitHub 账号自十月以来就没有过任何活动。你的 Agent 仍然能够连接,仍然能够接收工具描述,仍然能够执行调用 —— 而在无声无息中,每一次调用都流经一段无人看管的基础设施。

这就是 MCP 被遗弃的现状。不是恶意的卷款跑路(rug pull),也不是被攻破的软件包,仅仅是由于疏忽。有人在 2025 年发布了一个有用的服务,被大家采用后,便转向了其他项目。该服务之所以能继续运行,是因为没有任何因素强行让它崩溃。直到它彻底崩溃 —— 而到那时,你的 Agent 每五分钟跨越一次的信任边界其实早已失效。

大多数团队采用社区 MCP 服务的方式与采用 npm 包的方式如出一辙:运行 install 并阅读 README。这种思维模型在面对 MCP 时失效了。在 MCP 中,依赖是一个动态的信任边界,LLM 在循环中携带凭据,并在生产数据上对其进行调用。

遗弃是供应链风险的隐蔽版本

主动攻击会留下痕迹。恶意的 commit 会出现在 diff 中。凭据窃取尝试会触发你的出口流量监控。被投毒的工具描述有时会出现在提示注入检测器中。即使你读取信号的速度很慢,但信号确实存在。

遗弃则没有任何信号。服务依然在它的 socket 上响应。工具描述依然渲染在 Agent 的上下文窗口中。每一次调用依然返回 200 状态码和看起来正确的 JSON 主体。其失败模式并不是“东西停止工作了”,而是“这东西在无声无息中停止了与它所对话的世界保持同步”。

与此同时,世界在变。上游 API 增加了新的必填字段。该服务的某个间接依赖项公开了一个 CVE。协议本身发布了新的功能版本。该领域的安全最佳实践也在演进。你的系统不会因此触发任何警报,因为这些变化都不会改变你的 Agent 与这个孤儿进程(orphaned process)之间的 socket 形态。

最近的行业研究表明,已公开 CVE 的平均利用时间(time-to-exploit)为五天。一个静默了六十天的 MCP 服务,从定义上讲,已经错过了该窗口期内的每一次安全更新 —— 包括它自己的代码、运行时以及其下方的传递依赖链。你不会收到任何警告,你运行的是一个已存在已知漏洞的信任边界。

基础概率比你想象的要糟糕得多

npm 生态系统是 MCP 发展趋势最接近的参照物,而其数据令人警醒。针对该注册表(registry)的学术研究发现,下载量最高的软件包中有 8.2% 已被官方弃用;如果将定义扩大到包括存档的仓库和没有 GitHub 记录的包,这一比例将推高至 15% 左右。npm 上约 61% 的软件包在过去十二个月内没有任何发布。超过一千天未触及的包在实践中被视为无人维护 —— 当它们的漏洞浮出水面时,不会有任何补丁。

用户每周从 npm 下载超过二十亿次已弃用的软件包。下载量、流行度得分、甚至是注册表中的显著排名,几乎无法告诉你代码是否正在被积极维护。

MCP 生态系统继承了这种动态,并缩短了演进的时间线。到 2026 年 3 月,Python 和 TypeScript 的 MCP SDK 每月总下载量已突破 9700 万次。公共注册表索引了大约一万二千到两万个服务,尽管目录公开指出“许多是分叉版本、变体或已被遗弃”。十八个月的爆发式增长建立在一个成熟度曲线尚未弯曲的协议之上。大多数社区服务都是个人开发者的周末项目,为了抢占命名空间而匆忙发布。MCP 维护者注意力的统计分布几乎肯定比 npm 的情况更糟,而不是更好。

这种命名方式本身就很说明问题。一个如此年轻的协议,拥有如此饥渴的社区,产生了一个坟墓数量增长速度超过园丁清理速度的墓地。

MCP 特有的失败模式

有三点使得 MCP 遗弃比过时的 npm 包更糟糕。

上游 API 漂移。 大多数社区 MCP 服务都是他人 API 的垫片(shim)—— 比如 Figma、Postmark、Linear、数据库驱动程序或云控制台。MCP 服务将工具调用转换为 API 调用。当被封装的 API 改变形态时 —— 新的必填字段、弃用的端点、变更的响应模式、收紧的身份验证 —— 一个被遗弃的垫片会在原地腐烂。有时它会返回看似合理的错误;有时它会以微妙的错误语义成功执行,因为 LLM 对响应格式的宽容度很高,并且会自信地向用户报告成功。Agent 认为它发送了邮件、应用了迁移或关闭了工单。没有人监控垫片与它所封装的对象之间的契约。

工具描述契约冻结。 MCP 工具描述的文本是 LLM 在决定是否以及如何调用工具时所读取的内容。在被遗弃的服务中,该描述会与底层 API 实际接受的内容脱节。参数名称发生漂移。速率限制发生变化。以前可选的字段变成了必填。描述依然承诺旧的行为,模型也照此调用。调用会失败,或者更糟糕的是,产生看起来像幻觉的输出,因为模型用一个看似合理的猜测修补了这种差异。没有人更新描述,因为没有人更新任何东西。

继承的 CVE 攻击面。 一个 MCP 服务不仅是一个依赖项,它是一个依赖树。MCP 运行时、语言 SDK、HTTP 客户端、认证库、序列化层以及它们下方的每一个传递依赖项都会发布各自的安全更新。一个被遗弃的服务被冻结在它发布时的版本。每多一个月的沉默,都会拉大它的依赖图与负责任维护者应保持的进度之间的差距。你运行的是某人 2025 年的快照,而这棵依赖树仅在 2026 年就收到了至少十几个与安全相关的更新。

上述每一个失败默认都是隐蔽的。而且由于你的 Agent 在每一个相关环节都带着真实的凭据对真实的系统调用该服务,这些风险会被进一步放大。

真正有效的依赖审计框架

经历过 npm 长尾效应洗礼的团队已经熟知这种模式。核心问题不在于“这个依赖是否开源”,而在于“当它停止工作时,谁来为故障负责?”对于 MCP 而言,少数几个信号就能提供绝大部分关键信息。

  • 最后提交日期。 按周、月、年进行划分。以周计是健康的;在协议演进如此之快的阶段,以月计则处于黄色预警状态;以年计则是“墓碑”。
  • 发布节奏。 有版本的发布和变更日志(changelog)优于仅在 main 分支开发的模式。如果没有标签(tag),你就无法定义自己到底依赖的是什么。
  • 维护者身份。 一个兴趣驱动项目背后的单个 GitHub 账号,与厂商官方服务器、企业支持的项目或具名的工作组,其风险概况完全不同。要问清楚:仓库所有者持续迭代的动力是结构性的(这是他们的工作)还是可选的(这是周末的消遣)。
  • Issue 队列行为。 原始的未解决数量并不重要,重要的是对安全报告的响应延迟以及是否存在分拣(triage)标签。一个堆积了 300 个陈旧 Issue 且毫无动静的仓库并不“稳定”——它处于休眠状态。
  • CI 规范。 服务器是否有测试?测试是否通过?是否有机制确保对 main 的提交能与它封装的上游 API 兼容?一个 CI 持续报错六个月的服务器,基本上已经被弃用了。
  • 上游契约。 被封装的 API 是否稳定且有版本管理?是否有变更日志?如果适配层封装的对象更新飞快,而适配层本身却停滞不前,那么这个适配层就存在半衰期。

在采用之前应用这些信号,而不是在事故发生之后。它们不能捕捉到所有问题——它们是粗略的启发式方法——但足以将候选服务器分类为“信任并监控”或“不要放在关键路径上”。

Fork 与 Vendor 决策树

一旦某个服务器对你的产品至关重要,“观望”就不再是一种策略。选项可以简化为一个简短的决策树。

如果服务器处于关键路径且上游 API 稳定,但维护者无响应,请直接 fork 并进行 vendor 处理(引入本地仓库)。将代码纳入你的仓库,掌控依赖图谱,并接受你现在需要负责 CVE 补丁队列的事实。当困难部分已经完成、仅剩维护工作时,这是成本最低的选择。这也能让社区副本继续存在,供风险较低的用户使用。

如果服务器处于关键路径且上游 API 不稳定,不要 fork——直接针对 API 构建一个精简的内部包装层(wrapper)。你横竖都要维护这个适配层与上游的契约,不如跳过别人的抽象层,自己写那一百到三百行代码。内部包装层为你提供了你亲自编写的显式工具描述(避免未知字符串带来的注入风险)、显式的版本锁定、显式的依赖审计,以及一个在事故发生时能够立即响应的团队。代价是工程时间,好处是服务器的任何部分都不会处于“默认孤儿”状态。

如果服务器并非关键项,且存在厂商官方提供的替代方案,请更换为官方方案。厂商有结构性的动力去持续更新,而社区则是可选的。

如果以上都不适用,请自行编写并预先接受所有权带来的“税收”。这笔税收比后续每一次溯源到团队一年没人读过的代码所引发的事故都要便宜。

“但它是开源的”不能替代所有权

开源协议允许你进行 fork,但并不保证有人会去执行。“代码可用”是一种许可声明,而不是维护声明。每当有人根据 Star 数量采用社区 MCP 服务器时,这两者就会被混为一谈。

每个调用孤儿服务器的 Agent 都在将该孤儿未来的失效模式引入自己的产品层面。当上游更换凭证、当 CVE 爆发、当破坏性变更落地时,在客户电话中失效的是你的 Agent。此时运维手册上写着“联系维护者”,而维护者自去年十月起就销声匿迹了。

生态系统将会分化。API 至关重要的厂商——GitHub、Figma、Stripe、Linear、云端控制台——将把官方 MCP 服务器作为产品的一部分进行发布,因为替代方案是看着一个残破的社区适配层代表他们的品牌。社区服务器在探索和原型设计阶段仍具价值。如果你观察哪些服务器发布时带有变更日志,而哪些服务器的 README.md 自被采用起就没改动过,这种分化就已经显而易见了。

对于任何处于关键路径上的东西,假设社区服务器在 24 个月内会实质性失效,并从现在开始为此做打算。将其 Vendor 化、包装它、替换它,或者明确预算以继承其维护工作。

在每次采用 MCP 之前,只需问一个问题:如果这个仓库明天停止更新,会发生什么故障?团队中谁来负责修复?如果真实的回答是“没什么,因为我们会发现”或“没人负责,因为它是开源的”,那么你还没有做出依赖决策。你只是在赌这种沉默的代价很低。

事实并非如此,而“坟墓”正在不断增加。

References:Let's stay in touch and Follow me for more thoughts and updates