news 2026/9/16 12:03:00

MCP Registry 管理实战:服务器编辑、状态管理、Takedown 下线与生产数据库访问

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MCP Registry 管理实战:服务器编辑、状态管理、Takedown 下线与生产数据库访问

MCP Registry 管理实战:服务器编辑、状态管理、Takedown 下线与生产数据库访问

【免费下载链接】registryA community driven registry service for Model Context Protocol (MCP) servers.项目地址: https://gitcode.com/GitHub_Trending/registry43/registry

本文基于registry(Model Context Protocol 官方服务器注册中心)仓库中的管理运维文档 docs/administration/admin-operations.md,完整讲解管理员与审核员(moderator)如何对注册中心内容执行编辑、状态变更与下线(takedown)操作。读完后,你将掌握:如何通过auth.sh完成 OIDC 到 Registry JWT 的令牌交换、如何用 REST API 精准修改单个版本或批量变更所有版本的状态、如何使用takedown.sh安全地下线服务器,以及如何通过 GKE 端口转发直连生产 PostgreSQL 并开启只读保护。所有操作均需遵循 MCP Registry 审核政策。

前置条件

执行任何管理操作前,需要满足以下条件:

  • 拥有带@modelcontextprotocol.io邮箱的管理员账号(如果你是维护者并希望申请账号,可在项目 Discord 中提出)
  • 已安装并配置好gcloudCLI
  • 已安装curljq
  • 已安装kubectlgke-gcloud-auth-plugin(用于数据库访问)

认证:OIDC 令牌交换为 Registry JWT

管理操作的第一步是获取 Registry 令牌。仓库提供了 tools/admin/auth.sh 辅助脚本:

# Run this, then run the export command it outputs ./tools/admin/auth.sh

脚本的完整工作流程(见 tools/admin/auth.sh)是:

  1. gcloud projects list失败,先触发gcloud auth login完成登录;
  2. 通过gcloud auth print-identity-token获取 Google Cloud identity token;
  3. 将其作为oidc_tokenPOST 到${REGISTRY_URL}/v0/auth/oidcREGISTRY_URL默认为https://registry.modelcontextprotocol.io);
  4. jq解析响应中的registry_token,并打印出形如export REGISTRY_TOKEN='...'的导出命令供你手动执行;
  5. 若解析不到令牌,脚本打印完整响应并以非零状态退出。

源码层面的认证机制

从 internal/api/handlers/v0/auth/oidc.go 可以看到,/v0/auth/oidc端点(exchange-oidc-token)接收任意已配置 OIDC 提供方的 ID token,经StandardOIDCValidator(基于go-oidc库)验证签名与声明后,支持通过OIDCExtraClaims配置对额外声明(如 groups、roles、aud)做强制校验——列表型声明只要与期望值有任一交集即通过(见claimMatches实现)。随后buildPermissions根据服务端的OIDCPublishPerms/OIDCEditPerms配置生成权限列表,写入 JWT 声明并签发短生命周期的 Registry JWT。

几个对管理员很重要的权限细节(见 internal/auth/jwt.go 与 internal/auth/types.go):

  • Registry 权限模型只有两种动作:publishedit,每个权限携带一个资源模式(ResourcePattern,如io.github.username/*);
  • 资源模式为*的权限被视为全局权限(管理员),可跳过命名空间黑名单(BlockedNamespaces)检查;
  • NewJWTManager的初始化代码看,令牌有效期被硬编码为 5 分钟。因此如果你的curl请求偶尔返回 401,先重新运行一次auth.sh刷新令牌再操作。

编辑特定服务器版本

当你需要修改某个具体版本的细节(如修正描述、更新状态、修改 packages 字段)时使用本节流程。

第一步:下载指定版本

export SERVER_NAME="<server-name>" # e.g., "com.example/my-server" export VERSION="<version-string>" # e.g., "1.0.0" (optional, defaults to latest) # URL encode the server name (replace / with %2F) ENCODED_SERVER_NAME=$(echo "$SERVER_NAME" | sed 's|/|%2F|g') # Get specific version curl -s "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/versions/${VERSION}" > server.json # Or get the latest version (use the special version "latest") curl -s "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/versions/latest" > server.json

第二步:进行修改

打开server.json并编辑该版本的详情。服务器名和版本号不可修改——这一约束在后端被强制执行:internal/api/handlers/v0/edit.go 中,若请求体里的name与现有服务器名不一致会返回 400Cannot rename server,若请求体version与 URL 路径参数不一致会返回 400Version in request body must match URL path parameter。服务器名是该条目的不可变标识符。

第三步:更新版本

# Update specific version (requires the full server.json body) curl -X PUT "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/versions/${VERSION}" \ -H "Authorization: Bearer ${REGISTRY_TOKEN}" \ -H "Content-Type: application/json" \ -d "$(cat server.json)"

从 edit.go 的实现可以看到 PUT 编辑端点(edit-server)的完整校验链:

  1. 校验Authorization: Bearer头格式与 JWT 有效性(401);
  2. URL 解码serverNameversion路径参数(400);
  3. 查询现有版本以对照权限(已下线的版本在此返回 404,需先通过 status 端点恢复);
  4. 校验当前用户对该服务器具有edit权限(否则 403);
  5. 禁止重命名、校验版本一致性;
  6. 对完整请求体执行 schema 校验(validators.ValidateServerJSON),失败时返回 422 并提示call /validate for details

只改状态:使用 status 端点

如果只想改一个版本的状态,不必走全量编辑,直接调用 status 端点即可,它不需要完整的服务器配置:

curl -X PATCH "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/versions/${VERSION}/status" \ -H "Authorization: Bearer ${REGISTRY_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"status": "deprecated", "statusMessage": "Superseded by v2"}'

该端点(update-server-status,见 internal/api/handlers/v0/status.go)的请求体约束值得注意:

  • status为必填,取值仅限activedeprecateddeleted
  • statusMessage可选,最长 500 字符,用于说明状态变更原因;
  • 当目标状态为active不允许携带statusMessage(返回 400);
  • 若新状态与现有状态(含消息)完全相同,视为无操作,返回 400No changes to apply
  • 权限要求是publishedit任一即可,比 PUT 编辑端点(仅要求edit)更宽;
  • 查询时会包含已删除的服务器(includeDeleted=true),因此已下线的服务器可以通过该端点恢复为active

编辑整个服务器(所有版本)

批量状态变更:一次请求覆盖所有版本

对服务器所有版本的状态变更只需要一个请求,服务端的语义是单事务——要么全部版本更新成功,要么失败时一个都不变。响应中通过updatedCount字段报告被更新的版本数量,并附上全部更新后的版本列表(见UpdateAllVersionsStatusResponse,status.go)。

export SERVER_NAME="<server-name>" # e.g., "com.example/my-server" ENCODED_SERVER_NAME=$(echo "$SERVER_NAME" | sed 's|/|%2F|g') curl -X PATCH "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/status" \ -H "Authorization: Bearer ${REGISTRY_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"status": "deleted", "statusMessage": "Removed per moderation policy"}'

实现上,update-server-all-versions-status端点(status.go)会先取出该服务器任意一个版本来校验权限,再用GetAllVersionsByServerName拉取全部版本做批量转换校验——如果没有任何版本会发生变化则拒绝请求(400),最后调用服务层的UpdateAllVersionsStatus(接口定义见 internal/service/service.go)在单事务内完成写入。

批量内容变更:必须逐版本执行

内容类编辑(例如从描述中清除敏感文本)没有批量端点,必须对每个版本使用编辑端点(要求完整服务器配置)逐个应用。

第一步:列出所有版本
export SERVER_NAME="<server-name>" # e.g., "com.example/my-server" ENCODED_SERVER_NAME=$(echo "$SERVER_NAME" | sed 's|/|%2F|g') curl -s "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/versions" > all_versions.json
第二步:提取版本号
# Extract all versions from the server jq -r '.servers[].server.version' all_versions.json > versions.txt
第三步:对每个版本应用修改
while read VERSION; do echo "Processing version: $VERSION" # Download the version, edit it, then send the full body back curl -s "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/versions/${VERSION}" > version.json # Apply your changes to version.json here, then: curl -X PUT "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/versions/${VERSION}" \ -H "Authorization: Bearer ${REGISTRY_TOKEN}" \ -H "Content-Type: application/json" \ -d "$(cat version.json)" done < versions.txt # Clean up temporary files rm -f versions.txt all_versions.json version.json

快捷操作(Quick Operations)

获取服务器的最新版本

export SERVER_NAME="<server-name>" # e.g., "com.example/my-server" ENCODED_SERVER_NAME=$(echo "$SERVER_NAME" | sed 's|/|%2F|g') curl -s "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/versions/latest" > latest_version.json export VERSION=$(jq -r '.server.version' latest_version.json) echo "Latest version: $VERSION"

下线(Takedown)特定版本

export SERVER_NAME="<server-name>" # e.g., "com.example/my-server" export VERSION="<version-string>" # e.g., "1.0.0" export REGISTRY_TOKEN="<your-token>" REGISTRY_TOKEN="$REGISTRY_TOKEN" SERVER_NAME="$SERVER_NAME" VERSION="$VERSION" ./tools/admin/takedown.sh

下线服务器的所有版本

ALL_VERSIONS=true会在单个请求内把所有版本标记为 deleted。tools/admin/takedown.sh 明确要求VERSIONALL_VERSIONS二者必须显式指定其一——这样遗忘VERSION时不会意外把整个服务器全部下线:

export SERVER_NAME="<server-name>" # e.g., "com.example/my-server" export REGISTRY_TOKEN="<your-token>" REGISTRY_TOKEN="$REGISTRY_TOKEN" SERVER_NAME="$SERVER_NAME" ALL_VERSIONS=true ./tools/admin/takedown.sh

从脚本源码看,完整的防误操作设计包括:

  • SERVER_NAMEREGISTRY_TOKEN缺失时打印用法并退出(exit 1);
  • VERSIONALL_VERSIONS同时设置时直接报错set either VERSION or ALL_VERSIONS, not both
  • 两者都未设置时同样报错并打印 usage;
  • 可选环境变量:STATUSactive | deprecated | deleted,默认deleted,因此该脚本同样可用于恢复或弃用)、STATUS_MESSAGE(随状态变更记录的说明,最长 500 字符)、REGISTRY_URL(默认为官方注册中心地址,可指向自部署实例);
  • 请求体由jq -n构造(自动做 JSON 转义),发送 PATCH 后用-w '%{http_code}'捕获 HTTP 状态码,非 2xx 即报错退出,响应体始终打印到终端便于核对updatedCount

只下线最新版本

export SERVER_NAME="<server-name>" # e.g., "com.example/my-server" export REGISTRY_TOKEN="<your-token>" ENCODED_SERVER_NAME=$(echo "$SERVER_NAME" | sed 's|/|%2F|g') # Resolve the latest version, then take down that specific version VERSION=$(curl -s "https://registry.modelcontextprotocol.io/v0/servers/${ENCODED_SERVER_NAME}/versions/latest" | jq -r '.server.version') REGISTRY_TOKEN="$REGISTRY_TOKEN" SERVER_NAME="$SERVER_NAME" VERSION="$VERSION" ./tools/admin/takedown.sh

下线时附带原因记录

REGISTRY_TOKEN="$REGISTRY_TOKEN" SERVER_NAME="$SERVER_NAME" ALL_VERSIONS=true \ STATUS_MESSAGE="Removed per moderation policy" ./tools/admin/takedown.sh

关于“下线”的语义,参考 审核政策:设置status"deleted"后,服务器元数据仍可通过注册中心 API 访问,聚合器(aggregator)据此将其从索引中移除;仅在极端情况(如元数据本身违法)才会覆盖或擦除元数据。这也解释了为什么 status 端点要包含已删除服务器——它们可以被恢复。

连接生产数据库

出于调试或数据分析需要,管理员可以直连生产 PostgreSQL 数据库。务必谨慎操作,并优先使用只读方式。

前置准备

如尚未安装 GKE 认证插件:

gcloud components install gke-gcloud-auth-plugin

建立连接

# Get cluster credentials gcloud container clusters get-credentials mcp-registry-prod --zone us-central1-b --project mcp-registry-prod # Get the database password kubectl get secret registry-pg-app -o jsonpath='{.data.password}' | base64 -d # Port-forward and connect (enter the password from above) kubectl port-forward svc/registry-pg-rw 15432:5432 & sleep 2 psql -h localhost -p 15432 -U app -d app

只读访问

为防止误写,连上后应立即将会话设为只读:

SET default_transaction_read_only = on;

在断开连接之前,任何写操作都会失败报错。

关键规则速查

场景方式依据
仅改单个版本内容PUT /v0/servers/{name}/versions/{version},需完整配置edit.go
仅改单个版本状态PATCH .../versions/{version}/status,无需完整配置status.go
改所有版本状态PATCH /v0/servers/{name}/status,单事务,响应含updatedCountstatus.go
改所有版本内容无批量端点,按版本循环执行编辑流程文档 Notes 一节
状态取值active/deprecated/deletedactive时禁止statusMessage请求体枚举定义
服务器名任何版本中均不可修改(不可变标识符)Cannot rename server400 校验
权限要求状态端点:publish 或 edit;编辑端点:editjwt.go

补充说明:从 internal/api/router/v0.go 可以看出,上述 servers、edit、status 与 auth 端点会同时在/v0/v0.1两个前缀下注册,因此管理脚本中的REGISTRY_URL路径前缀可随目标 API 版本调整。

最后强调 admin-operations.md Notes 一节的核心结论,便于快速决策:版本级变更只影响该版本;服务器级状态变更通过PATCH /v0/servers/{serverName}/status一次请求覆盖全部版本;服务器级内容变更没有批量端点、必须逐版本应用;状态变更用PATCH .../status,而PUT编辑端点要求提交完整服务器配置;**内容清除(scrubbing)**走版本级编辑流程;服务器名在任何版本中都不可变更。

【免费下载链接】registryA community driven registry service for Model Context Protocol (MCP) servers.项目地址: https://gitcode.com/GitHub_Trending/registry43/registry

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 12:02:38

优秀拆分的算法设计与二进制应用

1. 问题解析与算法设计1.1 优秀拆分的数学本质优秀拆分的核心要求是将正整数n表示为若干个互不相同的2的正整数次幂之和。从数学角度看&#xff0c;这实际上考察的是二进制表示法的变形应用。我们知道&#xff0c;任何正整数都可以唯一表示为2的幂次和&#xff08;即二进制表示…

作者头像 李华
网站建设 2026/9/16 12:02:30

从数据标注到模型对齐:AI训练师的职业转型指南

1. 职业转型背景与核心价值在人工智能行业快速发展的当下&#xff0c;数据训练师的角色正在经历显著转变。五年前&#xff0c;我刚开始接触这个领域时&#xff0c;大部分同行的工作内容还停留在基础数据标注层面——给图片打标签、对文本分类、标注语音片段。但随着大模型时代的…

作者头像 李华
网站建设 2026/9/16 12:02:05

SpringBoot乐器论坛系统:音视频与乐谱处理技术实践

## 1. 项目概述与核心价值去年帮本地音乐学院搭建在线乐器交流平台时&#xff0c;我深刻体会到传统论坛系统在乐器垂直领域的适配困境。这个基于SpringBoot的乐器论坛系统&#xff0c;正是针对乐器爱好者、学习者、教师三大群体的深度定制解决方案。与通用论坛相比&#xff0c;…

作者头像 李华
网站建设 2026/9/16 11:59:36

几秒语音克隆、免费商用:OpenVoice 完整快速上手指南

几秒语音克隆、免费商用&#xff1a;OpenVoice 完整快速上手指南 【免费下载链接】OpenVoice Instant voice cloning by MIT and MyShell. Audio foundation model. 项目地址: https://gitcode.com/GitHub_Trending/op/OpenVoice 做播客、录教程视频时&#xff0c;最头疼…

作者头像 李华
网站建设 2026/9/16 11:58:48

PAJ7620手势传感器STM32驱动详解:I²C寄存器配置与状态机识别

简介&#xff1a;本资源是一套面向嵌入式开发初学者与STM32项目实践者的PAJ7620手势识别模块完整技术支撑包&#xff0c;涵盖硬件设计、驱动开发与功能验证全流程。资源包含模块原理图、多平台&#xff08;F103/F407/F429&#xff09;Keil工程源码、引脚连接说明、传感器模块详…

作者头像 李华