深入讨论 Model Context Protocol 的发现机制与安全边界,对构建 Agent 和 MCP 服务的程序员有实用参考。
如果你使用过 Model Context Protocol,可能已经遇到过发现机制的问题:Agent 如何找到一个从未显式配置过的 MCP server?最显而易见的答案是“注册中心”——但 MCP server 的发现注册中心需要提供的保证,远不只是列出一些条目。
目前,大多数 MCP 环境都是这样工作的:你在 Claude Desktop 配置、Agent SDK 配置或 MCP client 的设置文件中添加一段 JSON。每个条目都将 server 名称映射到一条命令或一个 URL。它明确、直观而且安全——你清楚地知道自己的 Agent 可以访问哪些工具。
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
}
}
如果只有少量经过你亲自审核的 server,这种方式完全够用。但只要你希望 Agent 寻找某项配置中尚未包含的能力,它就会立刻失效。
这正是发现机制发挥作用的地方——也是大多数人不再继续思考发现注册中心究竟需要提供哪些保证的地方。
从理论上看,动态发现 MCP server 很简单:Agent 询问注册中心“有没有提供 X 能力的 server?”,注册中心返回一个列表,然后 Agent 建立连接。真正困难的是这两个步骤之间发生的事情。
想想注册中心会交给 Agent 什么:
现在再想想,恶意注册条目能做些什么。一个声称提供“代码分析”功能、实际却会窃取文件的 server。一个通过拼写仿冒的包名。一个完全没有验证发布者身份的注册中心。一个曾经合法,但维护者密钥已被轮换或泄露的 server。
这并非假设。困扰包注册中心(npm、PyPI、crates.io)的那些问题,在这里会造成双倍影响——因为 MCP server 并不会只是被动地待在你的 node_modules 中;它会在你的机器上运行工具、读取你的数据,并将结果传递给 AI Agent。它的影响范围更广。
如果要让 Agent 在没有人工逐条阅读的情况下安全使用发现注册中心,它需要具备以下四点。
注册中心必须知道每个 server 是由谁发布的。这里需要的不是一个用户名,而是在注册时经过确认、可以验证的真实身份。缺少这一点,拼写仿冒和社会工程攻击便易如反掌:我注册一个 mcp-server-aws-s3-storage,而你因为它看起来像正版就安装了它。
包注册中心已经付出惨痛代价才吸取了这个教训。MCP server 发现注册中心应该继承这些经验,而不是重蹈覆辙。
Agent 在运行时解析到的条目,必须与注册中心在发布时批准的载荷完全一致。任何偏差——被修改的工具定义、重定向的下载 URL、被注入的参数——都属于完整性失效。
这意味着必须使用签名。不仅要有传输过程中的 TLS(它可以抵御网络攻击者),还要有制品级签名,使其在重新托管、缓存或 DNS rebinding 的情况下依然有效。Agent 不应该信任提供内容的 endpoint;它应该信任随载荷一同提供的签名。
注册中心可以说明一个 server 声称自己能做什么,但无法在运行时强制它遵守这一限制。关键在于,Agent 必须在收到 server 身份信息的同时收到其能力声明,从而决定是否授予访问权限。
这类似于 Android manifest 或 macOS entitlements 文件:安装时,用户——在这里则是 Agent——可以看到 server 声称需要哪些权限,然后接受或拒绝。不能存在默认拥有的环境权限。注册中心的职责,是在 server 启动之前就呈现这些信息。
Server 可能遭到入侵。维护者可能轮换密钥。合法项目可能被遗弃并遭到劫持。没有撤销机制的注册中心,不出六个月就会变得不安全。
这是最难正确实现的部分——许多系统甚至从未实现过它。但要让 MCP 发现机制能够自主运行(Agent 发现 server、Agent 安装 server、Agent 使用 server),Agent 就需要一种检查方式:“现在的发布者还是原来的合法发布者吗?自从我上次查看以来,这个 server 是否已被撤回?”
MCP 规范本身并没有定义发现注册中心——它定义的是 client 与 server 之间调用工具和访问资源的协议。目前,发现机制仍由各个 client 或生态系统自行处理。一些项目提供经过筛选的目录。另一些项目则依赖现有的包注册中心(npm、PyPI),MCP server 恰好发布在这些平台上。
每种方案都解决了部分问题:
包注册中心能够处理真实性(大多数平台都验证发布者)和完整性(使用校验和验证制品),但无法表达能力边界——注册中心不知道(也不会检查)某个包是不是 MCP server,更不用说它暴露了哪些工具。
包注册中心能够处理真实性(大多数平台都验证发布者)和完整性(使用校验和验证制品),但无法表达能力边界——注册中心不知道(也不会检查)某个包是不是 MCP server,更不用说它暴露了哪些工具。
精选目录(由团队审核每个条目)解决了真实性和能力审核问题,但无法扩展,而且会造成单一审核瓶颈。它们通常也无法妥善处理撤销——删除一个列表条目,并不能阻止已经缓存该条目的 client 继续使用它。
精选目录(由团队审核每个条目)解决了真实性和能力审核问题,但无法扩展,而且会造成单一审核瓶颈。它们通常也无法妥善处理撤销——删除一个列表条目,并不能阻止已经缓存该条目的 client 继续使用它。
签名 manifest 方案(server 发布 manifest,client 独立验证)解决了完整性和分发问题,但没有解决发现问题——Agent 仍然需要一个起点,才能找到这些 manifest。
签名 manifest 方案(server 发布 manifest,client 独立验证)解决了完整性和分发问题,但没有解决发现问题——Agent 仍然需要一个起点,才能找到这些 manifest。
像 Pilot Protocol 的 App Store 这样的系统,正好可以在这里发挥作用。严格来说,它并不是 MCP 注册中心,而是面向 Agent 的通用能力注册中心,但它提供的保证与上述四项要求完全对应。
它的模型结构如下:
每个 App 都经过签名。manifest 中包含 SHA-256 hash,以及发布者生成的 Ed25519 signature。daemon 会在每次启动 App 时重新验证,而不仅仅是在安装时验证——因此,即使注册中心 server 遭到入侵,之后提供了不同的制品,也不会在无人察觉的情况下蒙混过关。
每个 App 都经过签名。manifest 中包含 SHA-256 hash,以及发布者生成的 Ed25519 signature。daemon 会在每次启动 App 时重新验证,而不仅仅是在安装时验证——因此,即使注册中心 server 遭到入侵,之后提供了不同的制品,也不会在无人察觉的情况下蒙混过关。
权限以授权范围为边界。安装 App 时,manifest 会声明它需要的能力(网络访问、文件系统等)。Agent(或其操作者)可以在安装时接受或拒绝。daemon 会在运行时强制执行这一边界——不存在默认拥有的环境权限。
权限以授权范围为边界。安装 App 时,manifest 会声明它需要的能力(网络访问、文件系统等)。Agent(或其操作者)可以在安装时接受或拒绝。daemon 会在运行时强制执行这一边界——不存在默认拥有的环境权限。
撤销机制是明确的。发布者可以取消发布 manifest,或对其重新签名。daemon 每次启动 App 时都会检查其时效性。被撤销的 App 将直接无法解析。
撤销机制是明确的。发布者可以取消发布 manifest,或对其重新签名。daemon 每次启动 App 时都会检查其时效性。被撤销的 App 将直接无法解析。
发现发生在运行时,而不是配置阶段。Agent 可以查询目录(pilotctl appstore catalogue),并通过一条命令完成安装——无须编辑配置文件,也无须手动固定 URL。
发现发生在运行时,而不是配置阶段。Agent 可以查询目录(pilotctl appstore catalogue),并通过一条命令完成安装——无须编辑配置文件,也无须手动固定 URL。
具体流程是“发现 → 安装 → 调用”,安全保证直接内置于协议本身,而不是依赖一个中央审核团队。
# Discover
pilotctl appstore catalogue
# Inspect
pilotctl appstore view io.pilot.cosift
# Install and call
pilotctl appstore install io.pilot.cosift --force
pilotctl appstore call io.pilot.cosift cosift.search '{"q":"latest MCP server ecosystem developments"}'
这并不能取代 MCP 专用注册中心——但其中的架构选择(签名验证、限定授权范围的权限、运行时撤销、发布者身份)恰恰是任何 MCP server 发现注册中心都必须提供的保证。
MCP server 发现并不是一个有关 DNS 或 API 设计的技术难题,而是一个信任难题:如何让 Agent 在没有人工逐行审查的情况下,安全地安装并调用一种此前从未接触过的能力?
要解决这个问题,注册中心需要具备经过签名的制品、经过验证的发布者身份、可强制执行的能力声明,以及真正可用的撤销路径。缺少其中任何一项,它都只是一个换了名字的包注册中心——而包注册中心在大规模场景下早已深受信任问题困扰。
安全的 Agent 原生工具发现所需的基础设施已经存在。下一步,是建立一套能够让它成为通用能力的规范。
如果需要采取进一步措施,可以考虑屏蔽此人和/或举报滥用行为。