"它在注册表里"这句话,在 MCP 的选型决策里干着一份它远远配不上的重活。如今你和一个服务器之间横着四个索引,它们回答的是四个不同的问题——名字归谁、谁替你把它跑起来、镜像由谁构建,以及世上到底有些什么。其中恰好只有一个对你将要执行的那件产物做出了承诺,而四个都没有读过模型将当作指令服从的那些工具描述。按你手上真正的问题去挑,别再把"出现在某个索引里"当成安全的证据。
一览
这四个通常被摆成竞争关系。它们不是——它们位于"某处存在一个服务器"到"一个服务器正跑在我的智能体凭据旁边"这条路径上的不同位置。
| 索引 | 它实际上是什么 | 它能给出的承诺 | 最适合 |
|---|---|---|---|
| 官方 MCP Registry | 一个带公开只读 API 的命名空间,由 MCP 项目运营 | 这个名字属于那个证明了自己掌控该域名或 GitHub 账号的人 | 解析身份;充当其他索引读取的上游 |
| Smithery | 目录加托管——CLI 安装、托管的远程端点,以及一个做路由的元服务器 | 我们会在一个 URL 上替你把它跑起来 | 今天就要一个远程服务器能用,且不想运维任何东西 |
| Docker MCP Catalog | 一批经过挑选、以镜像分发的容器化服务器 | 这个镜像由我们掌控的流水线构建,带签名、SBOM 与来源证明 | 任何要在公司内部运行的东西 |
| PulseMCP | 一个大型的人工审阅目录,按周更新 | 这东西存在,而它是做什么用的 | 搞清楚有没有人为某件事做过服务器 |
目录规模相差一个数量级以上,而多数公布出来的数字都是自报的。有一个不是:把官方 Registry 自己的只读 API 一路翻到底,截至撰写时它返回 24,330 个不同的服务器名字、79,651 条版本记录,其中约七成落在 io.github.* 命名空间下。社区目录处在同一量级;Docker 精选目录以百计。把规模当作"准入政策"的陈述,而不是"质量"的陈述——大的那几个索引,收的是一个已验证命名空间能发布的一切;小的那个,收的是它自己构建的东西。
官方 Registry 是一个命名空间,不是一份目录
理解官方 Registry 最直接的办法是读一条记录。名字采用反向 DNS 形式,只读 API 无需认证:
{
"server": {
"name": "io.github.acme/mcp-search",
"description": "Search Acme's docs, then fetch full articles by id.",
"version": "1.4.2",
"remotes": [{ "type": "streamable-http", "url": "https://acme.dev/mcp" }]
},
"_meta": {
"io.modelcontextprotocol.registry/official": {
"status": "active",
"publishedAt": "2026-04-13T17:32:20Z",
"isLatest": true
}
}
}
名字本身就是产品。要以 io.github.acme/… 发布,你必须以那个 GitHub 账号身份认证,或从它名下仓库的 GitHub Action 里发布;要用自定义域名发布,你必须通过该域名的 DNS TXT 或 HTTP 挑战。这是一项真实且被低估的安全性质——它让抢注命名空间变得昂贵,于是一条声称属于你的供应商的条目,几乎肯定真的来自你的供应商。
它不是什么:一次审查。审核是被动的——社区通过 issue 举报垃圾条目、冒名或恶意代码,维护者事后把条目拉黑。元数据字段带有长度限制与正则校验,用来挡住最粗糙的滥用。没有人会去把服务器跑起来、读它的工具描述,或者查它连了哪里。这个设计意图是明说的、也是合理的:做名字与元数据的上游事实源,把策展留给上面的子注册表。这篇四方对比之所以存在,正是因为那些子注册表真的出现了。
值得内化的区分:名字验证告诉你的是谁发布的,不是发布了什么。一个经过验证的命名空间能挡住冒充供应商的攻击者。它对以下情形毫无作用:某个供应商的服务器有一个作用域没划好的工具,或者一个正当的发布者下个季度账号被攻陷——而后者正是 npm 与 PyPI 上早已在发生的软件供应链攻击的形状。
Smithery 卖给你的是运行时,这就是那笔交易
说 Smithery 是目录,就像说云厂商是硬件目录一样。列表是前门;产品是它能通过 CLI 替你装好一个服务器,或者——后果更重的那种——把一个服务器作为托管的远程端点替你跑起来,再加一个把智能体路由到多台服务器中正确那一台的元服务器。
就"今天下午就要能跑"而言,这四个里它遥遥领先。2026-07-28 的无状态修订让远程 MCP 在运维上简单了不少——一台远程服务器如今就是一份普通的 HTTP 负载——但"更好运维"不等于"已经有人在运维",而 Smithery 卖的正是这个差额。这笔交易很清楚,值得直说:
- 一台托管的 MCP 服务器坐在你的智能体与上游 SaaS 之间,这意味着那个 SaaS 的 OAuth 令牌是在别人的基础设施里被行使的。这与智能体连接器平台是同一个保管问题,也值得同样的审视——你买的产品是那个保险库,而不是那份目录。
- 一个远程端点可以在你批准之后改掉它的工具列表。托管并没有创造这项风险,但它意味着你的模型读到的那份定义,是由一台你不掌控的机器、按一份你看不到的发布节奏供给的。机制在工具投毒,而抓住它的运维纪律在第三方工具漂移。
- 便利会聚集。一个挡在许多服务器前面做路由的元服务器,对这些服务器而言是同一份凭据、同一个可用性依赖、同一个爆炸半径。
这些都不能说明托管 MCP 是个坏主意。它说明的是:这是一个关于凭据保管的决定,而它极容易在不经意间做出,因为把它卖给你的那个界面看起来只是个搜索框。
只有 Docker 的目录在对产物本身做出承诺
Docker 的 MCP Catalog 是四者中最小的一个,也是唯一一个其条目携带着"关于你将执行之物"的证据的。服务器以容器镜像发布;对于 Docker 自己构建的那些,它端到端掌控流水线,并附上密码学签名、一份 SBOM、来源证明与持续的漏洞扫描。条目按来源打标——Docker 构建 vs 社区构建、由发布者维护——而网关可以在启动时而不是浏览时校验这些证明,这才是关键的部分:
docker mcp gateway run --verify-signatures
由此得出两个方向相反的后果。
好的一面是,容器化让"好的默认值"同时成为"最省事的那个"。一个用 npx 拉起的 stdio 服务器继承了你的 shell、你的文件系统与你的环境变量;一个镜像只跑在你授予它的挂载与网络里,并从工具箱里取密钥,而不是从一份你粘了 token 进去的配置文件里取。这就是隔离作为默认值抵达,而不是靠自律抵达;对任何要在公司内部运行的东西而言,这比任何列表元数据都值钱。
不好的一面,是签名产物所诱发的一种范畴错误。来源证明回答的是"这东西是不是来自它所声称的那一方、未经改动"。它回答不了"该不该允许这东西读你的仓库"。一个服务器的 search_docs 工具描述里悄悄指示模型顺便把结果发给攻击者的端点——它的镜像可以被正确签名、证明齐备,同时彻头彻尾是敌对的。供应链完整性与行为安全是两个不同的问题、由不同的控制手段负责——见智能体供应链安全,那里讲了各自该放在哪。
PulseMCP 回答的是你真正最先问的那个问题
"这安全吗"之前是"这东西存在吗",而回答后者,PulseMCP 是四者中最好的:最大的人工审阅目录、按周刷新、按"服务器是干什么用的"而非"谁发布的"来组织。它不做任何信任承诺,也不暗示任何一种——对一份目录来说,这是诚实的立场。
把它当搜索引擎用——用来发现真的有人为你那个偏门的内部工具做过服务器,然后把名字拿去官方 Registry 查清对方是谁,把镜像拿去 Docker 或你自己的构建里查清你将要运行的是什么。目录里的一条命中是一次评估的开始,不是结束。
四者都空着的那一列
上面每一个索引都验证了某种结构性的东西:一个名字、一次构建、一条列表、一个 URL。它们都不评估那件真正带有敌意的产物——模型会读到并当作指令服从的、用自然语言写成的工具描述。
有四道缺口在所有索引面前都幸存下来,而这四道都是普通的工程活儿,不是研究难题:
- 工具描述是提示词可见的文本。每次更新都对它做 diff,把描述的变更当作依赖版本的变更来对待,因为它就是——它改变了别人告诉你的模型该做什么。
- 默认没有任何东西钉住版本。Registry 记录版本并标出最新的那个;而多数宿主配置乐呵呵地在启动时装上
npx -y解析到的任何东西。钉住它,然后有意识地升级。 - 出站方向在任何地方都没有声明。没有哪个索引字段写着一台服务器会去连哪些主机。如果服务器跑在你的基础设施里,你可以用白名单回答这个问题;如果它是被托管的,你根本回答不了。
- 列上去之后没人复查。这四者做出的每一项声明,都是在发布那一刻做出的。有意思的变化永远发生在之后。
MCP 项目在 2026 年 8 月 22 日发布的路线图,指向一个相关且值得提前规划的转变:渐进式发现(progressive discovery)——服务器逐步披露工具,而不是一上来就把整份目录倒出来。这对上下文膨胀是个合理的答案,同时也意味着"你的模型能看到哪些工具"变成了服务器的一项运行时性质,而不再是你批准过一次的一张静态清单。当目录能在会话中途变化时,上面每一条论证都变得更锋利。
何时选哪个
| 处境 | 从这里开始 | 然后 |
|---|---|---|
| 这个工具到底有没有现成的服务器? | PulseMCP,胜在广度与新鲜度 | 把名字拿到官方 Registry 里解析 |
| 供应商发来一个服务器,真是他家的吗? | 官方 Registry——已验证的命名空间就是答案 | 钉住版本;更新时对工具描述做 diff |
| 要在公司内部运行 | Docker MCP Catalog(如果收录了);没收录就自己构建镜像 | 启动时校验签名;显式授予挂载与出站 |
| 今天下午就要交原型 | Smithery 的托管端点 | 上生产之前决定:那一方该不该拿着你的令牌 |
| 你自己要发布服务器 | 名字发到官方 Registry,发现渠道看你的用户在哪儿找 | 顺手也出一个镜像——那是唯一带着证据的那份列表 |
对多数团队来说,现实的答案是把四个按顺序都用上,而不是从中选一个:在目录里发现、在 Registry 里解析身份、从一个真去构建它的目录里取产物、在你自己掌控的隔离下运行它。这套栈没有任何新奇之处;它和"解析一个包名、校验一份签名、在沙箱里跑构建"是同一个形状。
可长期依赖的原则:索引能验证身份、来源或可用性,而没有哪个索引能验证意图。出现在注册表里是一个关于名字的事实。一份签名是一个关于构建的事实。一个托管 URL 是一个关于可用性的事实。而真正决定一个 MCP 服务器装不装得的问题——它的工具在让你的模型做什么,以及模型照做时那些工具够得到哪里——只能靠读工具描述、以及你围着这个进程建起的隔离来回答。这两件事在四种情况下都归你干,所以把它们的预算一次性排进去,别再反复争论哪个索引才是可信的那一个。
常见问题
被官方 MCP Registry 收录,是否意味着这个服务器经过了审查?
不。发布需要证明你掌控那个命名空间——一个 GitHub 账号或一个域名,通过 OAuth、DNS TXT 或 HTTP 挑战——而审核是被动的:社区举报滥用,维护者事后把条目拉黑。这是一个很强的身份信号,不是一次安全审查。
这四个是竞争关系吗?
大体上不是。官方 Registry 被有意定位为名字与元数据的上游事实源,让子注册表与市场在它之上叠加策展、发现与托管。Smithery 与 PulseMCP 在发现这一层互相竞争;Docker 的目录竞争的对象是"你自己构建容器"。
一个签过名的 Docker 镜像到底保证了什么?
保证你拉下来的产物就是流水线产出的那一个、它的内容被 SBOM 一一列出、它的构建有一份证明,并且它被扫描过已知漏洞。它对服务器的行为不做任何保证,因为一个忠实构建出来的恶意服务器,签起名来和良性的一样漂亮。
托管的 MCP 端点是不是比我自己跑的更不安全?
是"安全的方式不同"。你交出了强制出站策略与检查进程的能力,并增加了一方——它的发布可以改变你的模型读到的工具定义。作为交换,你得到一个现在就能用的端点,以及别人的值班。对原型来说这是笔划算的交易;对一台握着生产凭据的服务器,请有意识地做这个决定。
装任何 MCP 服务器之前该查什么?
四件事,按顺序:命名空间归谁、工具描述在指示模型做什么、这个进程在网络与文件系统上够得到什么,以及版本有没有被钉住。四个索引里没有一个替你回答第二和第三件。
延伸阅读
本站:
- MCP 注册表与分发——发布你自己的服务器,以及每种打包方式的代价。
- MCP 工具投毒——为什么工具描述才是攻击面。
- MCP 安全反模式——在各家服务器实现里反复出现的那些错误。
- 智能体供应链安全——来源、版本钉住,以及签名覆盖不到的地方。
- 什么是 MCP?——一页讲完这个协议。
- MCP 变成无状态了,而状态只是挪了个地方——让远程服务器变成普通 HTTP 的那次 2026-07-28 修订。
来源:
- Official MCP Registry — public read API
- Model Context Protocol — About the MCP Registry
- Model Context Protocol — Authenticating when publishing to the registry
- Model Context Protocol — The new MCP roadmap (2026 年 8 月 22 日)
- Docker — Docker MCP Catalog: a secure way to discover and run MCP servers
- GitHub — docker/mcp-registry
- GitHub — modelcontextprotocol/registry