ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

MCP 官方 Registry 发布附加验证规则:server.json 在 registry 源码中的落地实现

MCP 官方 Registry 发布附加验证规则:server.json 在 registry 源码中的落地实现 MCP 官方 Registry 发布附加验证规则server.json 在 registry 源码中的落地实现【免费下载链接】registryA community driven registry service for Model Context Protocol (MCP) servers.项目地址: https://gitcode.com/GitHub_Trending/registry43/registry本文基于官方 Registry 的server.json附加要求文档完整讲解发布到官方 MCP Registryregistry.modelcontextprotocol.io时在通用server.json规范之上额外施加的四类验证命名空间鉴权、包归属验证、受限的 Registry Base URL 白名单以及_meta命名空间限制。同时结合 registry 仓库源码说明每条规则在验证器与鉴权处理函数中的具体实现位置与错误语义帮助你在发布前预检问题、准确理解发布失败信息。总览官方 Registry 在通用规范之上做了什么通用server.json格式见 server.json 格式规范定义了基础字段与结构校验而官方 Registry 在此基础上追加了四类强制约束目的是保证命名空间鉴权Namespace authenticationServer 只能发布到发布者实际拥有的命名空间之下包归属验证Package ownership verification发布者必须能证明其确实拥有所引用的包防止冒名受限的 Registry Base URL包必须来自受信任的公共 Registry私有源与第三方镜像不被允许_meta命名空间限制_meta对象中仅publisher相关键的数据会被保留其余键在发布时被静默丢弃。从源码结构看这四类约束分别落在不同模块server 名称格式由 parseServerName 强制包归属与 Base URL 白名单由internal/validators/registries/下的各验证器执行_meta大小限制由 validatePublisherExtensions 执行命名空间所有权证明由internal/api/handlers/v0/auth/下的各类鉴权端点完成。命名空间鉴权证明你拥有该命名空间发布者必须证明其拥有对应命名空间。例如要发布到com.example/server发布者必须证明其拥有example.com域名。从源码可以确认 server 名称的硬性格式name字段必须形如dns-namespace/name恰好包含一个/且匹配正则^[a-zA-Z0-9.-]/[a-zA-Z0-9._-]$长度 3200定义在 ServerJSON 类型的 JSON Schema 标签与 parseServerName 中。命名空间部分只能以字母数字开头和结尾、中间可含点与连字符name 部分额外允许下划线。格式不合法时验证器会给出精确到是 namespace 还是 name 部分非法的错误提示。Registry 提供了多种命名空间所有权证明途径对应 鉴权实现目录 下的不同端点DNS 命名空间通过解析域名 TXT 记录完成挑战验证。DNSAuthHandler 通过DNSResolver.LookupTXT查询 DNS TXT 记录注册了exchange-dns-token令牌交换端点GitHub 命名空间如io.github.user通过 GitHub App 访问令牌或 OIDC 流程证明仓库/组织归属对应 github_at.go 与 github_oidc.go此外还有基于 HTTP 挑战http.go、OIDCoidc.go与无鉴权测试模式none.go等实现便于自建 Registry 时按环境选择鉴权后端。具体的 GitHub 与域名命名空间的逐步认证操作见 发布指南。包归属验证每种包类型都有明确的所有权凭证所有包都必须携带能证明发布者拥有它的元数据。这一机制防止有人把别人的包绑定到自己控制的 server 记录上。上游项目对此的安全动机在 registry 项目 issue #96 中有专门讨论。各 Registry 类型的具体验证要求详见 包类型文档每种 registry 都有 Ownership Verification 一节。从本仓库源码可以印证各类型的验证手段Registry 类型所有权凭证源码位置NPM包的package.json元数据中必须有mcpName字段且取值与 server name 完全一致ValidateNPMPyPI包的 descriptionREADME中必须包含mcp-name: server-name令牌pypi.goNuGet包的 README 中必须包含mcp-name: server-name令牌nuget.goCargocrates.io 上该版本的渲染 README 中必须包含mcp-name: server-name令牌cargo.goOCI/Docker镜像标签labelio.modelcontextprotocol.server.name必须等于 server nameValidateOCIMCPB仅允许 GitHub / GitLab Releases 下载链接mcpb.go几个源码层面的实用细节NPM 的mcpName必须精确匹配。validateNPMPackage 会请求{baseURL}/{identifier}/{version}元数据端点缺失mcpName时错误信息会直接告诉你该往package.json加什么NPM package %s is missing required mcpName field. Add this to your package.json: \mcpName\: \%s\。取值不匹配时则报ownership validation failed. Expected mcpName ... got ...。NPM 对 404 做了精细区分。当版本元数据返回 404 时npmVersion404Error 会用 HEAD 请求探测包级端点区分包不存在、包存在但版本尚未同步新发布可能有传播延迟与上游瞬时故障429/5xx三种情况给出可操作的重试建议而不是笼统地报未找到。README 令牌采用边界锚定匹配。PyPI/NuGet/Cargo 的mcp-name:令牌必须后接空格、换行或 HTML 标签等边界如果令牌后面紧贴了其他字符比如mcp-name: foo与你要的mcp-name: food混淆错误信息会明确指出请放到单独一行并重新发布见 nuget.go、cargo.go。OCI 验证失败是失败关闭fail closed。由于io.modelcontextprotocol.server.name标签是官方 Registry 对 OCI 包唯一的归属凭证ValidateOCI 在遇到 429 限流时不会放行而是返回可重试错误私有镜像401/403会明确提示仅支持公共镜像。OCI 包的字段约束identifier必须是规范引用如docker.io/owner/image:1.0.0不允许再带registryBaseUrl、version或fileSha256字段版本信息包含在identifier中tag 或sha256:digest 均可。包级验证在EnableRegistryValidation配置开启时执行入口是 ValidatePublishRequest它先做_meta扩展校验再对packages数组逐包调用ValidatePackage任一包失败即整体失败错误信息会带上包序号与 identifier。受限的 Registry Base URL只允许受信任的公共源官方 Registry 只接受受信任的公共 Registry私有 Registry 与替代镜像一律拒绝。支持的清单如下Registry 类型允许值NPM仅https://registry.npmjs.orgPyPI仅https://pypi.orgNuGet仅https://api.nuget.org/v3/index.jsonCargo仅https://crates.ioDocker/OCIDocker Hubdocker.io、GitHub Container Registryghcr.io、Quay.ioquay.io、Google Artifact Registry*.pkg.dev、Azure Container Registry*.azurecr.io、Microsoft Container Registrymcr.microsoft.comMCPB仅https://github.com与https://gitlab.com的 Releases 下载链接源码层面的印证固定的 Base URL 常量集中定义在 pkg/model/constants.goRegistryURLNPM、RegistryURLPyPI、RegistryURLNuGet、RegistryURLCrates、RegistryURLGitHub、RegistryURLGitLab等。以 NPM 为例ValidateNPM 要求registryBaseUrl与https://registry.npmjs.org完全相等否则返回registry type and base URL do not match错误该错误定义于 constants.go。OCI 的白名单是唯一的域名集合型规则实现在 allowedOCIRegistries 与 isAllowedRegistry精确匹配docker.io、registry-1.docker.io、index.docker.ioDocker Hub 的 API 端点别名、ghcr.io、quay.io、mcr.microsoft.com外加两个通配后缀*.pkg.devGoogle Artifact Registry与*.azurecr.ioAzure Container Registry。单元测试 oci_test.go 覆盖了通配主机如myregistry.azurecr.io、us-west1-docker.pkg.dev/...与固定主机的放行行为。不在白名单内的 registry 会返回unsupported OCI registry错误。_meta命名空间限制只保留 publisher-provided 数据server.json中的_meta字段允许发布者携带自定义元数据但发布到官方 Registry 时有严格限制只有io.modelcontextprotocol.registry/publisher-provided键之下的数据会被保留_meta对象中的任何其他键都会在发布时被静默丢弃——既不存储也不会在 API 中返回。对应地ServerMeta 类型 中_meta只有一个PublisherProvided字段JSON 标签即为io.modelcontextprotocol.registry/publisher-provided这从数据结构层面保证了其他键根本无法进入存储。示例{ _meta: { io.modelcontextprotocol.registry/publisher-provided: { tool: ci-publisher, version: 1.0.0, custom_data: your data here }, some.other.key: { // 该键会被丢弃不会被保留 } } }大小限制publisher-provided 扩展的序列化 JSON 上限为4KB4096 字节超限会导致发布失败错误信息中会给出实际字节数。该限制由 validatePublisherExtensions 实现错误消息格式为_meta.io.modelcontextprotocol.registry/publisher-provided extension exceeds 4KB limit (%d bytes)推荐做法按反向域名做子命名空间当publisher-provided元数据变大、或来自多个来源例如 GitHub 专属提示加上自家 CI 工具的元数据时按反向 DNS 子键分组是避免键冲突的实用惯例{ _meta: { io.modelcontextprotocol.registry/publisher-provided: { com.github: { serverDisplayName: My Server }, io.example.ci-publisher: { tool: ci-publisher, version: 1.0.0 } } } }需要说明的是该惯例不被强制。简单场景下扁平键完全可以仓库内的既有示例也使用扁平形式只有当元数据来自多个来源时才建议改用命名空间子键形式。注意区分server.json的_meta与 API 响应中的_metaserver.json里的_meta与 Registry API 响应返回的_meta是两个不同的东西server.json中_meta包含发布者自定义元数据位于io.modelcontextprotocol.registry/publisher-provided之下API 响应中_meta是响应级别的独立属性不在server.json内部承载 Registry 托管的元数据包括status生命周期状态active、deprecated、deleted、publishedAt首次发布时间、updatedAt最近更新时间、isLatest是否为最新版本。你发布的内容server.json{ name: io.github.example/my-server, version: 1.0.0, description: My MCP server, // ... 其他字段 ... _meta: { io.modelcontextprotocol.registry/publisher-provided: { tool: ci-publisher, version: 2.0.0 } } }Registry API 返回的内容{ server: { name: io.github.example/my-server, version: 1.0.0, description: My MCP server, // ... 其他字段 ... _meta: { io.modelcontextprotocol.registry/publisher-provided: { tool: ci-publisher, version: 2.0.0 } } }, _meta: { // 响应级别的 Registry 托管元数据 status: active, publishedAt: 2024-01-15T10:30:00Z, updatedAt: 2024-01-15T10:30:00Z, isLatest: true } }可以看到 API 响应中存在两个_meta一个在server对象内部从 server.json 原样保留的发布者数据另一个在响应级别Registry 自动添加的托管元数据。Registry 托管元数据无法被发布者设置或覆盖。从源码可以确认这一点ServerResponse 的结构正是server内含 ServerMeta加上响应级Meta而后者实际包装的是 RegistryExtensionsstatus/statusChangedAt/statusMessage/publishedAt/updatedAt/isLatestJSON 键为io.modelcontextprotocol.registry/official。完整的响应结构参见 官方 Registry API 文档 与 OpenAPI 定义。如何在发布前自查结合上述规则发布前可以用仓库自带工具链自查用 server.schema.json当前版本日期为2025-12-11见 constants.go对server.json做结构校验仓库提供了 validate-schemas.sh 等脚本用于校验 schema 本身。检查各包的所有权凭证是否就位NPM 包在package.json中加mcpNamePyPI/NuGet/Cargo 包在 README 中加独立一行的mcp-name: server-name令牌OCI 镜像在 Dockerfile 中加LABEL io.modelcontextprotocol.server.nameserver-name验证器在缺失时会在错误信息中直接给出对应的 LABEL 写法。确认registryBaseUrl在上表白名单内、OCI 包未误用registryBaseUrl/version字段。控制_meta中publisher-provided的序列化体积在 4096 字节以内。发布流程的命令行操作validate/publish等子命令见 发布指南 与 CLI 参考集成测试 tests/integration/main.go 中对publisher-provided元数据的逐键比对可作为发布后数据是否原样保留的验收参考。小结官方 Registry 的附加验证可以概括为命名空间靠 DNS/GitHub 等所有权证明把关包靠各 Registry 的原生元数据凭证mcpName、README 中的mcp-name:令牌、OCI label绑定归属包源靠固定白名单收敛到受信任的公共 Registry_meta靠单一保留键加 4KB 上限控制体积。这些规则在 validators、registries 验证器 与 auth 处理函数 中均有可核对的实现遇到发布失败时对照错误信息中给出的具体字段与期望值如期望的mcpName、期望的 LABEL 写法修正后重新发布即可。【免费下载链接】registryA community driven registry service for Model Context Protocol (MCP) servers.项目地址: https://gitcode.com/GitHub_Trending/registry43/registry创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表