mcpField
C
CustomDomain™

CustomDomain™

远程服务
customdomain.ai云与基础设施02 天前更新

关于 CustomDomain™

CustomDomain™ 是托管式 MCP 服务,让 Agent 查找、连接、诊断和管理域名,面向构建 Agent 的团队及需要客户自有域名的 SaaS 平台。它通过受限工具处理 DNS 配置、邮件记录和 HTTPS 状态,而不接受任意 DNS 记录参数。

主要功能

  1. 01搜索域名并查看价格
  2. 02连接域名并检测 DNS 服务商
  3. 03诊断记录问题并检查连接状态
  4. 04配置邮件记录和域名转发
  5. 05管理证书、域名清单及名称服务器

适用场景

  1. 01为新上线的应用连接客户域名
  2. 02为 SaaS 企业客户处理域名接入
  3. 03配置邮件域名的 MX、SPF、DKIM 和 DMARC
  4. 04排查或修复未生效的域名连接

MCP 相关

托管式 MCP 服务通过 Streamable HTTP 提供 20 个域名管理工具,支持 OAuth 和按范围授权。工具返回所需 DNS 记录并处理连接检查等操作,不允许 Agent 直接提交任意记录值。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://mcp.customdomain.ai/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

CustomDomain™ MCP 服务:为 AI Agent 提供自定义域名

这是官方 CustomDomain™ 产品 MCP 服务。它唯一的端点是 https://mcp.customdomain.ai/mcp, 在官方 MCP 注册表中的名称为 ai.customdomain/mcp,OAuth 作用域为 domains:read、 domains:connect、domains:disconnect 和 domains:purchase。没有其他主机提供此服务,因此,任何其他 地址上自称为 CustomDomain™ 的服务都不是此服务。

用于自定义域名的 MCP 服务:让 Claude 和其他 AI Agent 查找、连接、诊断和管理域名。

状态: 生产环境 · 服务端 0.6.0 · 发布版本 v0.6.0

live MCP registry protocol docs license

网站 · 文档 · 控制台 · 产品页面 · MCP 文档 · 工具参考 · 服务商覆盖范围 · 定价

安装: Install in VS Code Install in VS Code Insiders · Claude Code、Claude Desktop 和 Cursor:快速入门 · GitHub Copilot 云 Agent:配置

星标可以帮助 GitHub 上的其他开发者发现此服务。如果它对你有用,请为此代码库点亮星标。

它是什么一个托管式 MCP 服务,为 AI Agent 提供 20 种域名工具
适用对象需要客户使用自有域名的 Agent 构建者、SaaS 平台和编码 Agent 用户
在线地址customdomain.ai/mcp-server · 端点 https://mcp.customdomain.ai/mcp
技术栈Go 1.26 · 基于 streamable HTTP 的 JSON-RPC 2.0 · 托管式,服务中不设数据存储
状态生产环境 · 已在官方 MCP 注册表发布 0.6.0 版本 · 20 种工具 · 收录 178 家 DNS 服务商,其中 62 家支持自动配置

CustomDomain™ MCP 是一个托管式 Model Context Protocol 服务,让 AI Agent 帮助用户使用自己的域名:连接已有域名、设置电子邮件记录、 监控域名何时启用 HTTPS,以及查明尚未启用的原因。它取代了人们通常在 DNS 控制面板中手动完成的那部分工作。无需安装,也无需持续运行任何程序:将 MCP 客户端指向上面的端点即可。

flowchart LR
  A["Agent<br/>Claude · Cursor · ChatGPT"] -->|"JSON-RPC over HTTPS"| M["mcp.customdomain.ai<br/>20 tools"]
  M -->|"credential forwarded"| C["Control plane<br/>api.customdomain.ai"]
  C --> R["Registrars<br/>search · price"]
  C --> D["DNS providers<br/>178 catalogued · 62 automatic"]
  C --> E["Edge<br/>TLS issued"]

问题

每款 SaaS 产品最终都需要让客户使用自己的域名:白标应用的主机、个性化链接,或用于发送邮件的域名。这项工作不复杂,而且总是一样:查明客户使用哪家 DNS 服务商,按正确格式写入正确的记录,等待记录生效,然后获取证书。手动完成,这就是一张支持工单;用代码完成,这就是一个你并不想维护的 DNS 服务商集成,而且要做 60 次。

Agent 在带来好处之前,反而会让问题变得更糟。让 Agent 来做这项工作的显而易见的方法,是给它 DNS 凭据和写入记录的能力。这意味着,只要一次误解指令,或一张被投毒的网页,就可能修改客户的区域配置。没人愿意把生产域名上的 SetRecords 调用交给大模型,而另一种做法(让 Agent 把说明念出来,再请用户到别处手动输入)又会变回支持工单,只是多了几步。这不是靠提示词就能解决的权限问题,而是参数列表的问题;解决方法是改变 Agent 能够发出的指令。

适用对象

  • 打造可交付产品的团队。 编码 Agent、网站构建器、部署机器人:任何能产出可运行应用,并且需要一个用户真正会输入的地址的工具。Agent 会连接域名并轮询其状态,直到变为 live,而不是在最后一步停下来,只给出一段 DNS 操作说明。
  • 拥有租户域名的 SaaS 平台。 如果客户会将自己的域名连接到你的产品,这就是 CustomDomain™ 小组件和 REST API 背后的同一套引擎,Agent 可以通过自己已经使用的协议来访问。
  • 电子邮件和消息平台。 在客户的服务商处,以正确格式验证发件域名(MX、SPF、DKIM、DMARC),在这里一次调用即可完成,无需翻阅文档或排队等待支持。
  • 需要维护域名组合的任何人。 域名连接可能失效,证书需要仍能解析的记录。能够列出、诊断、重新检查并重新应用设置的 Agent,比每季度都由人工处理更省钱。

功能

二十种工具,只需一个凭据,参数中无需包含 DNS 记录。以下每项都是独立的工具调用,而不是你必须自行组装的工作流:

  • 检查域名是否可以注册,并获取实时购买和续费价格:search-domain-availability
  • 根据一组关键词,以确定性方式推荐确实可用的名称:generate-domain-suggestions
  • 通过已解析的注册商注册域名,并受默认拒绝授权关卡保护。目前托管服务上已禁用:create-domain-order
  • 连接客户已拥有的域名,并获取必须存在的准确记录:connect-domain
  • 在向任何人索取信息之前检测 DNS 提供商,提供各接入线路的判定结果,并进行冲突和 CAA 预检:discover-provider
  • 轮询连接直至完成,从写入记录到签发证书:check-connection-status
  • 逐条说明域名为何尚未上线:diagnose-connection
  • 在用户修复问题后立即重新运行 DNS 检查:recheck-connection
  • 读取 HTTPS 证书(到期时间、续订失败情况):check-certificate-status
  • 跨两个不同的账本轮询注册订单,无需猜测适用哪一个:check-order-status
  • 列出通过该账户完成的购买:list-domain-orders
  • 通过一次调用设置电子邮件(根据服务器端模板配置 MX、SPF、DKIM 和 DMARC):add-email
  • 将域名永久指向其他位置,并使用 301 重定向:forward-domain
  • 修复已偏离 live 状态的域名,使用已存储的授权:reapply-connection
  • 下线域名,操作前让用户确认具体域名:disconnect-domain
  • 分页列出整个账户的资源清单,以便 Agent 协调整个域名组合,而不只是它发起的任务:list-connections
  • 在批量操作前,或收到 billing_required 拒绝后,检查工作区是否可以连接新域名:check-billing-status
  • 将域名的名称服务器迁移到应用的 DNS 主机,先复制记录(包括邮件记录),以便此后始终正确维护这些记录:migrate-nameservers
  • 跟踪迁移直至完成,并转达需要用户执行的步骤:check-nameserver-status
  • 将名称服务器迁回旧服务器,或迁至注册商自有的 DNS:rollback-nameservers

完整的参数、权限范围和响应结构请参阅:TOOLS.md。

所有凭据均可从外部验证:该服务已在官方 MCP 注册表中以 ai.customdomain/mcp 发布,版本为 0.6.0,支持协议修订版 2025-06-18,无需身份验证即可在 /.well-known/agent/mcp.json 查看其版本和工具;对于未经身份验证的调用,服务会返回 RFC 9728 挑战,其中会指明自身的元数据文档,而不是仅返回裸 401。自动设置涵盖目录中列出的 178 家提供商中的 62 家(其中 55 家使用受限范围 API 令牌,6 家使用提供商 OAuth,1 家使用 Domain Connect);其余 116 家仍可使用,并会返回记录和供人工操作的链接。实时分布见 /v1/providers/census。

所有这些工具都遵循同一条经验构建:只返回控制台链接就停止工作的 Agent,并没有完成任务。工具会直接返回权威记录集,因此 Agent 可以明确告知用户需要添加哪些记录;完成信号是布尔值,而不是集成可能误读的状态字符串。

使用场景

  • 交付副项目的编码 Agent。“把我的域名指向这个应用。”先调用 discover-provider,再调用 connect-domain,然后反复调用 check-connection-status,直到 connected 为 true。唯一需要人工操作的步骤是 在 DNS 服务商处授权,或添加返回的记录。
  • **为企业客户提供服务的 SaaS。**Agent 首先调用 discover-provider,发现客户使用的服务商无法为根域名设置别名,于是在任何人授权之前发出警告。
  • 电子邮件平台。add-email 根据模板写入 MX、SPF、DKIM 和 DMARC 记录;Agent 只需提供每个域名的 DKIM 选择器,无需提供其他内容。
  • **拥有上千个租户域名的平台。**调用 list-connections 并设置 status=failed(持续使用 nextCursor,直到获取完整列表),保留 managed: true 的行,对这些行调用 reapply-connection,对其余行调用 diagnose-connection 并交由人工处理。这是 Agent 可以按计划运行的协调循环,也是库存工具存在的原因。
  • 回答“为什么我的域名还不能用”的支持 Agent。diagnose-connection 会说明哪条记录缺失或有误,以及原因(例如在 Name 字段中输入了主机名,或前面有代理),而 recheck-connection 无需等待下一次计划检查即可确认问题已修复。
  • **确保用户域名持续正常运行的平台。**应用负责维护域名时,Agent 会询问用户,调用 migrate-nameservers 并设置 confirm: true,然后轮询 check-nameserver-status,直到状态为 done;每当用户需要在注册商处操作时,Agent 都会转达 nextStep。rollback-nameservers 可撤销迁移。

通过 MCP 购买域名的功能已经开发完成,但托管服务暂不可用:购买需要授权,而此处未配置购买授权回调,因此 create-domain-order 会返回 rejected。请先在控制台购买,再在此处连接域名。

为什么使用 MCP 服务而不是 REST API

REST API 确实存在,也是此服务调用的对象。区别在于 Agent 可以发出什么请求。REST API 接受 DNS 记录,而 MCP 工具不接受。每条记录的值都由控制平面根据经过审核的模板计算,因此,遭到提示词注入的 Agent 在这里最糟糕的操作也只是连接错误的域名,而不是向客户的区域写入任意 MX 记录。安全模型由参数列表构成。此外,委托的 Agent 令牌只包含用户批准的作用域;移除域名需要单独的作用域,并且必须在 confirm 中再次指定域名。付费注册有单独的门控:create-domain-order 要求在 confirm_domain 中再次填写域名,并且只有在集成方的购买授权回调批准后才会下单;未配置的回调会拒绝所有购买请求。迁移名称服务器需要设置 confirm: true,而 Agent 令牌无法选择名称服务器的目标位置:由应用的设置决定。

第二个原因是发现能力。即使 Agent 从未听说过这款产品,也能找到它:该服务已列入官方 MCP 注册表,会在 well-known 路径发布 Agent 清单和 OAuth 受保护资源文档;未通过身份验证的调用会返回一个指向受保护资源文档的质询,而不是简单的 401。支持 OAuth 的客户端会根据该文档找到授权服务器,为用户登录,并获取作用域受限的令牌,无需复制任何密钥。REST API 无法以这种方式介绍自己。


快速入门

大多数客户端通过 OAuth 登录,因此无需复制密钥:浏览器会打开,由用户批准 Agent 可以执行的操作,然后 Agent 会获得一个限定范围的令牌。无法登录的客户端会使用从 app.customdomain.ai 控制台的 API & SDK 页面获取的 API 密钥。密钥格式为 cd_live_... 或 cd_test_...(旧版 sk_live_ / sk_test_ 密钥仍可使用)。请将密钥存放在环境变量中,切勿放在会提交的文件里。

Claude Code,使用 OAuth 登录:

claude mcp add --transport http customdomain https://mcp.customdomain.ai/mcp
# then run /mcp inside Claude Code and sign in

或使用环境中的 API 密钥:

claude mcp add --transport http customdomain https://mcp.customdomain.ai/mcp \
  --header "Authorization: Bearer $CUSTOMDOMAIN_API_KEY"

Claude Desktop:进入 Settings → Connectors → Add custom connector。输入 URL https://mcp.customdomain.ai/mcp,添加后选择 Connect 并登录(OAuth)。

Cursor 目前还不能独立登录新的服务,因此需要使用密钥。请将以下内容放入用户级的 ~/.cursor/mcp.json,不要放在会提交的项目 .cursor/mcp.json 中,并在启动 Cursor 时使用的环境中设置 CUSTOMDOMAIN_API_KEY:

{
  "mcpServers": {
    "customdomain": {
      "url": "https://mcp.customdomain.ai/mcp",
      "headers": { "Authorization": "Bearer ${env:CUSTOMDOMAIN_API_KEY}" }
    }
  }
}

任何 HTTP 客户端:此端点使用标准 JSON-RPC 2.0,因此你可以通过 curl 调用工具:

curl -X POST https://mcp.customdomain.ai/mcp \
  -H "Authorization: Bearer $CUSTOMDOMAIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"discover-provider","arguments":{"domain":"example.com"}}}'

控制台的 MCP server 页面提供这些客户端以及 Codex、VS Code、ChatGPT 等客户端的复制粘贴式配置,还提供连接测试。

VS Code

顶部的安装徽章会添加此条目。你也可以自行将其放入 .vscode/mcp.json,或运行 MCP: Add Server:

{
  "servers": {
    "customdomain": { "type": "http", "url": "https://mcp.customdomain.ai/mcp" }
  }
}

该条目不包含密钥。服务会在收到第一个请求时返回 401,其 WWW-Authenticate 标头会注明 受保护资源元数据,该文档会将 https://api.customdomain.ai 指定为授权服务器(使用 PKCE 的授权码流程,并支持动态客户端注册)。按照 VS Code 文档所述,遵循此质询的客户端会打开浏览器,让用户登录并批准所需权限范围。若要改用 API 密钥,请添加一个由 VS Code 提示你输入一次并以机密形式存储的标头:

{
  "servers": {
    "customdomain": {
      "type": "http",
      "url": "https://mcp.customdomain.ai/mcp",
      "headers": { "Authorization": "Bearer ${input:customdomain-key}" }
    }
  },
  "inputs": [
    { "type": "promptString", "id": "customdomain-key", "description": "CustomDomain™ API key", "password": true }
  ]
}
GitHub Copilot 云 Agent

Copilot 云 Agent(负责处理议题和拉取请求的编码 Agent)不支持通过 OAuth 登录的远程 MCP 服务,因此会将凭据作为标头发送。在代码库中,打开 Settings → Copilot → MCP servers,粘贴此配置并保存:

{
  "mcpServers": {
    "customdomain": {
      "type": "http",
      "url": "https://mcp.customdomain.ai/mcp",
      "headers": { "Authorization": "$COPILOT_MCP_CUSTOMDOMAIN_AUTH" },
      "tools": ["*"]
    }
  }
}

然后添加一个名为 COPILOT_MCP_CUSTOMDOMAIN_AUTH 的 Agents 机密(Copilot 只会传递名称以 COPILOT_MCP_ 开头的机密)。其值是完整的标头值,即 Bearer 后接以下任一内容:

  • 从控制台的 API & SDK 页面获取的 API 密钥(cd_live_...),该密钥对整个工作区生效;或
  • 通过 POST /v1/applications 创建的应用程序的 APPLICATION_ID:CLIENT_SECRET。该接口仅返回一次密钥。服务会在每个请求中将这对凭据兑换为有效期为 15 分钟的令牌,与 POST https://mcp.customdomain.ai/token 使用 client_credentials 授权类型进行的兑换相同;Agent 仅代表该应用程序执行操作。通过控制台创建的应用程序不会显示其密钥,因此请为这些应用程序使用 API 密钥。

"tools": ["*"] 允许 Agent 无需询问即可调用所有工具,包括会使域名离线的 disconnect-domain。若要限制 Agent 只执行读取和诊断操作,请改为列出具体工具,例如 ["discover-provider", "check-connection-status", "diagnose-connection", "list-connections", "check-certificate-status"]。

客户端支持

客户端连接方式备注
Claude Code原生可流式传输 HTTPclaude mcp add --transport http;使用 /mcp 登录,或传入密钥标头
Claude Desktop自定义连接器设置 → 连接器 → 添加自定义连接器;使用 OAuth 登录
Cursor原生 HTTP(带标头)在 ~/.cursor/mcp.json 中使用来自环境变量的密钥;暂不支持登录
ChatGPT开发者模式应用使用 OAuth 登录;无法发送 API 密钥
其他客户端POST /mcp,JSON-RPC 2.0按照 401 提示登录,或在 Authorization 标头中发送 Bearer 令牌

工具与三条约定

所有工具都遵循三条规则,而集成方常常会在这些地方出错。

没有工具接受 DNS 记录。 add-email 接受邮件设置(MX 主机、DKIM 选择器),然后由模板将其转换为记录。forward-domain 接受重定向目标。两者都不接受记录。

connected: true 是完成信号。 状态字符串仅供参考;用于分支判断的是布尔值,而且即使状态枚举日后扩展,它也会保持稳定。

无法撤销的调用必须得到用户同意。 disconnect-domain 接受 connectionId 和 confirm,其中 confirm 是用户确认过的域名;create-domain-order 会在 confirm_domain 中重复该域名;migrate-nameservers 和 rollback-nameservers 接受 confirm: true。若调用未提供确认信息,系统会在执行任何操作前拒绝该调用。

此外,没有所有权验证步骤:没有工具会要求或检查 TXT 验证记录。域名控制权通过写入记录的通道来证明(提供商处的 OAuth 授权、一键应用,或范围受限的 API 令牌);在手动操作流程中,控制平面只会等待记录出现在公共 DNS 中。

身份验证

POST /mcp 接受四种 Bearer 凭据。

凭据颁发方代表对象
API 密钥 cd_live_ / cd_test_(旧版 sk_live_ / sk_test_)控制台中的 API & SDK。每个工作区都有一个默认密钥;创建的密钥只会显示一次。整个工作区
来自 POST /token 的 JWT使用 application_id + client_secret 进行 client_credentials 交换。有效期为 15 分钟。一个应用程序
CLIENT_ID:CLIENT_SECRET供无法运行令牌交换的主机使用的快捷方式;服务会在每次请求时进行交换一个应用程序
委派 Agent 令牌在 https://api.customdomain.ai 上通过 OAuth 获取:动态客户端注册、使用 PKCE(S256)的授权码,以及由用户批准的作用域一个应用程序,仅限已批准的作用域
curl -X POST https://mcp.customdomain.ai/token \
  -u "<APPLICATION_ID>:<CLIENT_SECRET>" \
  -d "grant_type=client_credentials"
# -> { "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 900 }

APPLICATION_ID 和 CLIENT_ID 是同一个值的两种名称。

集成方凭据(API 密钥、/token JWT、CLIENT_ID:CLIENT_SECRET 形式)不由服务本身验证:服务会将其转发给控制平面,由控制平面在每次调用时执行与 REST API 相同的权限检查。它们不携带作用域。在控制台中撤销密钥后,Agent 会在下一次调用时失去访问权限;目前,该调用会返回工具失败并显示 error: "unauthorized",而不是 HTTP 401。

委派 Agent 令牌是为受众 https://mcp.customdomain.ai/mcp 颁发的 ES256 令牌。服务会根据控制平面的 JWKS 在本地验证令牌,拒绝受众不匹配的令牌并返回 401 invalid_token,且会在每次调用时检查工具的作用域:

作用域工具
domains:readsearch-domain-availability、generate-domain-suggestions、check-connection-status、check-order-status、discover-provider、list-connections、check-certificate-status、diagnose-connection、check-billing-status、list-domain-orders、check-nameserver-status
domains:connectconnect-domain、reapply-connection、forward-domain、add-email、recheck-connection、migrate-nameservers、rollback-nameservers
domains:disconnectdisconnect-domain
domains:purchasecreate-domain-order

令牌缺少工具所需作用域时,会返回 JSON-RPC 错误 -32003、insufficient_scope,其中会指出所需的作用域。请参阅 Agent 访问和身份验证。

对于 Agent 会接触的任何内容,优先使用 Agent 令牌或应用程序范围的 JWT:泄露的 cd_live_ 密钥会赋予整个工作区的权限。

速率限制

每个调用方的工具调用速率限制为每秒 5 次,突发最多 20 次。对于委派 Agent 令牌,调用方是工作区(同一工作区的所有 Agent 共用一个配额桶);对于 API 密钥或 /token JWT,调用方是凭据本身(拥有三个密钥的工作区有三个配额桶);对于 CLIENT_ID:CLIENT_SECRET 形式,调用方是应用程序。超过限制时,该调用会返回工具失败并附带 error: "rate_limited" 和 retryAfterSeconds,且不会到达控制平面。控制平面还会限制每个客户端地址。

生命周期、轮询与错误

连接状态依次为 pending → propagating → live。failed 表示诊断结果,并非终结状态。

状态含义
pending已创建。记录尚未写入,或尚未在公共 DNS 中观察到。手动连接不会自行失败:72 小时后仍会保持 pending,并带有 errorCode: "setup_incomplete",每六小时重新检查一次。
propagating某个接入渠道已写入记录。轮询器正在根据记录值对照公共 DNS 进行检查。
live每条预期记录都解析为其目标值,且边缘节点已为该主机提供 TLS 服务。
failed接入渠道写入的记录在 24 小时内始终未解析(errorCode: "propagation_timeout"),或接入渠道拒绝了写入。如果连接之后重新验证成功,此状态会清除。

后台轮询器大约每分钟重新检查一次,因此将轮询间隔设为短于 30 到 60 秒毫无益处。failed 状态可以恢复,不应因此告诉用户从头开始:diagnose-connection 会说明问题所在,修复后,recheck-connection 会重新运行检查。完整生命周期请参阅连接。

错误有两种形式。格式错误的调用会在 JSON-RPC 层失败:参数无效或缺失时返回 -32602,工具未知时返回 -32601,JSON 无法解析时返回 -32700,缺少作用域时返回 -32003。这些都是调用方的问题。控制平面拒绝的调用会作为标记了 isError: true 的工具结果返回,无论调用的是哪个工具,格式都相同:

{ "success": false, "error": "billing_required", "message": "A card is needed to connect more domains.", "details": "..." }

如果控制平面提供了 error,它就是控制平面的错误代码;否则它是工具的备用代码(connect_failed、status_failed、list_failed 等)。根据 error 进行分支处理;显示 message。完整列表请参阅 TOOLS.md。

工作原理

本仓库是托管服务的公开入口:其中包含列出该服务的注册表清单、工具契约以及本页面。服务本身是一个小型 Go 进程。它负责终止 JSON-RPC、验证委托的 Agent 令牌及其作用域、限制每个调用方的速率,并将每次工具调用转发到 CustomDomain™ 控制平面。控制平面负责提供商检测、记录模板、注册商接入渠道、传播轮询器和证书签发。这种拆分让工具接口能够保持精简:所有状态和判断都在一跳之外。

仓库布局
.
├── README.md      # this file: what the server is, how to point a client at it, how it is built
├── TOOLS.md       # the tool contract: every argument, scope, response field, status value and error code
├── CHANGELOG.md   # one entry per server version, matching the tags and GitHub releases
├── server.json    # MCP registry manifest: name ai.customdomain/mcp, version 0.6.0, remote endpoint, tools and scopes
├── glama.json     # Glama directory ownership claim
└── LICENSE        # MIT
服务模块

服务端源代码位于私有的 CustomDomain™ 单体仓库中,路径为 services/mcp,与其调用的控制平面并列列出。这里列出模块名称,是为了清楚说明边界;由于仓库不公开,因此不提供链接。

模块用途调用对象
server.go路由 initialize、tools/list、tools/call;按固定顺序注册 20 个工具;工具运行前检查作用域和速率限制tools.go、usage.go
tools.go工具定义、JSON 架构、注解、处理程序和统一的失败格式client.go
nameservers.go三个名称服务器工具的处理程序:confirm: true,且 Agent 令牌不提供 target 或 nameserversclient.go
scopes.go工具与作用域的映射,以及确保每个工具恰好声明一个作用域的构建检查server.go
ratelimit.go每个调用方的令牌桶(默认每秒 5 个,突发上限为 20 个)server.go
jsonrpc.goJSON-RPC 2.0 帧格式和错误代码transport.go
transport.gostdio 和可流式传输的 HTTP 传输server.go
client.goControlPlane 端口:每个工具处理程序都会调用的接口由 httpclient.go 实现
httpclient.go接入控制平面 REST API 的 HTTP 适配器api.customdomain.ai
clientinfo.go传递调用方地址,以便控制平面的按地址限额能识别每位用户控制平面
origin.go对 /mcp 执行 Origin 检查(浏览器来源必须是服务端自身的来源,或由运营方列出的来源,否则返回 403),并处理 CORS 预检请求无
auth.goBearer 令牌提取、POST /token 和 RFC 9728 WWW-Authenticate 挑战控制平面
agenttoken.go在本地验证委派 Agent 令牌的 ES256 签名、有效期和受众控制平面 JWKS
purchaseauth.go默认拒绝的购买授权回调,在任何付费订单前进行检查集成方回调
registrar.go注册商解析和首选注册商排序控制平面
untrusted.go限制第三方文本(DNS 值、提供商错误)的长度,避免其未经处理就传给 Agent无
wellknown.go提供受保护资源和授权服务器元数据,以及 /.well-known/agent/mcp.json无
usage.go批量使用量记录器,满载时丢弃;绝不阻塞工具调用控制平面采集端
cmd/mcp/main.go进程入口:标志、环境、Sentry、OpenTelemetry以上全部

入口:services/mcp/cmd/mcp/main.go。

关键流程

连接用户已有的域名,是其他所有流程围绕其构建的核心流程。

sequenceDiagram
  participant A as Agent
  participant M as mcp.customdomain.ai
  participant C as Control plane
  participant D as Customer's DNS
  participant E as Edge
  A->>M: tools/call connect-domain {domain}
  M->>C: POST /v1/connections (credential forwarded)
  C->>C: detect provider, choose rail, compute records
  C-->>M: connectionId, records[], link, managed
  M-->>A: same payload as structuredContent
  Note over A,D: automatic rail: user authorizes once<br/>manual rail: user adds the returned records
  C->>D: poll public DNS by value (~60s)
  C->>E: request certificate once records resolve
  A->>M: tools/call check-connection-status {connectionId}
  M-->>A: status live, connected true
不变量
  • 没有工具接受 DNS 记录作为输入。 记录值由服务端根据经过审核的模板计算得出。 这是安全模型,并非功能缺失。
  • 服务端不使用数据库。 其 go.mod 只引入 Sentry 和 OpenTelemetry,没有其他依赖;工具返回的所有信息都在该请求期间从控制平面获取。速率限制器的令牌桶存储在内存中。
  • 每个工具恰好声明一个作用域。 若有工具未声明,服务端将拒绝启动。
  • 没有所有权挑战步骤。 没有工具会要求或检查 TXT 验证记录。
  • 此仓库中的任何内容都不会部署。 没有构建、没有 CI,也没有服务端源代码:这里的文件供 MCP 注册表和人阅读,服务端点在其他地方发布。
  • POST /v1/connections 按应用和域名幂等,因此重复调用 connect-domain 会恢复现有连接,并返回 already_connected: true,而不是创建第二个连接。

配置

作为客户端需要设置的内容。 此仓库中没有需要设置的环境变量。

设置项必填默认值用途
Endpoint URL是无https://mcp.customdomain.ai/mcp
Authorization header除非客户端登录无Bearer cd_live_...、来自 /token 的 JWT,或 CLIENT_ID:CLIENT_SECRET。登录的客户端会获取 Agent 令牌并自行发送。
Token URL仅用于 /token JWT无https://mcp.customdomain.ai/token

如果客户端支持,请勿将密钥写入配置文件。如果密钥存储在密钥管理器中,请在启动时注入;切勿将明文密钥粘贴到仓库、提交的 .cursor/mcp.json 或问题帖中。

托管服务的配置方式。 列出这些设置,是因为其中一些会改变工具的行为,而且集成方会询问购买被拒绝的原因。密钥值会在部署时注入,不会出现在任何仓库中。

变量必填默认值用途
MCP_ADDR否:8080HTTP 监听地址
MCP_API_BASE否https://api.customdomain.ai控制平面基础 URL
MCP_PUBLIC_BASE否https://mcp.customdomain.ai写入发现文档的公共来源,以及 Agent 令牌受众的基础 URL
MCP_AUTH_SERVER否https://api.customdomain.ai签发 Agent 令牌的控制平面公共来源;在受保护资源元数据中列为首项
MCP_AGENT_JWKS_URL否未设置委托 Agent 令牌的 JWKS。未设置时,Agent 令牌路径将保持关闭。 托管服务会设置此项。
MCP_ALLOWED_ORIGINS否未设置除服务自身来源外,允许调用 /mcp 的浏览器来源(格式为 scheme://host[:port],以逗号分隔)。任何其他 Origin 都会收到 403;不含 Origin 的请求(所有非浏览器客户端)不受影响。不支持通配符。托管服务中未设置此项。
MCP_TENANT_RPS否5每位调用方每秒可调用工具的次数。0 表示关闭限制。
MCP_TENANT_BURST否20每位调用方单次突发可调用工具的次数
MCP_LINK_BASE否控制台 URL返回给 Agent 的引导式 DNS 回退链接前缀
MCP_PURCHASE_AUTHZ_URL购买时必填未设置授权回调。未设置时会拒绝所有付费订单,这正是托管服务目前的运行方式。
MCP_PURCHASE_AUTHZ_USER设置了 URL 时必填未设置该回调的基本身份验证用户名
MCP_PURCHASE_AUTHZ_PASSWORD设置了 URL 时必填未设置该回调的基本身份验证密码(注入,不会存储)
MCP_PREFERRED_REGISTRAR否未设置订单解析期间优先尝试的注册商
JUSTEASY_MCP_USAGE_KEY否未设置启用用量记录;未设置时,记录器不执行任何操作。系统会先读取 CUSTOMDOMAIN_MCP_USAGE_KEY,并在未设置时使用 MCP_USAGE_INGEST_KEY 作为备用值。
MCP_USAGE_INGEST_URL否根据 MCP_API_BASE 推导用量批次的提交目标
CUSTOMDOMAIN_API_TOKEN仅限 stdio未设置本地 stdio 传输使用的静态控制平面 bearer;JUSTEASY_API_TOKEN 是旧名称
MCP_INSECURE否未设置不进行 bearer 检查即可提供 /mcp 服务,仅供一位开发者在自己的机器上使用:除非监听地址为环回地址,否则服务拒绝启动;在生产主机上也会拒绝启动。
SENTRY_ENVIRONMENT否未设置环境标签;生产环境防护也会读取此项
OTEL_EXPORTER_OTLP_ENDPOINT否未设置启用追踪(选择性);未设置时不执行任何操作

开发与测试

这里无需构建。仓库中只有两个 JSON 清单和三份 Markdown 文档,因此检查也相应简单:

git clone https://github.com/CUSTOM-DOMAIN-APP/customdomain-mcp.git
cd customdomain-mcp
jq -e . server.json glama.json > /dev/null && echo "manifests parse"

server.json 必须符合它声明的 MCP 注册表架构 (https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json;请注意,description 的长度上限为 100 个字符),其 version 也必须与发布到注册表的版本一致。TOOLS.md 是约定文档:如果上游更改了工具参数或响应字段,只有将更改反映到该文档中,工作才算完成。

服务本身使用 Go 1.26,包含196 项测试,分布在 26 个测试文件中(于 2026-10-21 在 0.6.0 提交中统计),覆盖协议、传输、控制平面适配器、购买门控及其确认、范围强制执行、Agent 令牌验证、速率限制器、Origin 检查、名称服务器工具,以及发现文档的一致性。在有内容到达端点之前,会先在单体仓库中运行 go build ./... && go test ./...,并执行 -race 检查。

实时检查无需任何准备,因为 Agent 清单是公开的:

curl -s https://mcp.customdomain.ai/.well-known/agent/mcp.json | jq '{version, tools: (.tools | length)}'
# -> { "version": "0.6.0", "tools": 20 }

版本管理与发布

服务的版本号只有一个:serverInfo、/.well-known/agent/mcp.json、注册表条目以及此处的 server.json 中的 version。每个版本都有一个 vX.Y.Z 标签、一项 GitHub 发布和一条 CHANGELOG.md 记录。当前版本为 0.6.0。

有两类内容按不同的节奏发布,混淆它们就会导致版本字符串过期。

此仓库向目录发布。官方 MCP 注册表会读取 server.json,用于 ai.customdomain/mcp;glama.json 则是向 Glama 目录声明所有权的文件。发布更改意味着更新 server.json 中的 version、将清单重新发布到注册表(已发布的注册表版本不可变)、添加 CHANGELOG 记录并打上标签。如需回滚:还原提交并重新发布之前的版本。这里的任何内容都不在请求路径上,因此此处的错误提交不会导致端点宕机。

注册表通过 customdomain.ai 上的 DNS TXT 记录(v=MCPv1; k=ed25519; p=...)识别命名空间 ai.customdomain,因此发布时需要使用与该记录匹配的 Ed25519 私钥以及注册表的 mcp-publisher CLI。私钥由维护人员保管,绝不会放入此仓库:

mcp-publisher login dns --domain customdomain.ai --private-key "$REGISTRY_PRIVATE_KEY_HEX"
mcp-publisher publish server.json

端点以 distroless 容器形式从私有单体仓库发布,二进制文件内置了 /healthz 探针(使用 -probe,因为镜像中没有 shell)。客户端始终连接到已部署的构建,上游新增的工具会自动出现,无需你做任何更改;回滚只需重新部署之前的镜像,客户端完全无需采取任何操作。请将集成固定到工具名称和 connected 布尔值,而非版本字符串。

按通常的处理顺序,可用的运维手段如下:在控制台撤销密钥或 Agent 的授权,以切断行为异常的 Agent;降低 MCP_TENANT_RPS;取消设置 MCP_PURCHASE_AUTHZ_URL 以拒绝所有购买;监控服务和控制平面的错误报告。影响工具的更改会记录在文档更新日志中。

已知限制

  • 178 个已编目的 DNS 提供商中,有 116 个没有自动流程。 工具仍然可用(会返回记录和链接),但需要人工添加。先调用 discover-provider,了解你遇到的是哪种情况。详细情况已发布在 提供商 页面。
  • Agent 无法独自完成手动连接。 这种设计有意采用链接中介方式:Agent 返回链接并轮询;人工完成付款步骤,以及在没有自动流程时完成 DNS 步骤。
  • 托管服务上无法购买。 create-domain-order 需要授权,但该服务未配置购买授权回调,因此会返回 rejected。请在控制台购买。
  • 只有对 Agent 令牌,才会将 confirm 与域名进行比对。 disconnect-domain 要求所有调用方都提供 confirm,但目前控制平面仅会对委派的 Agent 令牌检查该值是否为连接对应的域名。使用 API 密钥或客户端凭据令牌时,请在调用前自行检查。
  • Cursor 目前尚无法登录。 它使用 API 密钥,该密钥可访问整个工作区。
  • 基于浏览器的客户端会被拒绝。 网页发出的请求会携带 Origin,而托管服务只接受自身的来源(该服务未设置 MCP_ALLOWED_ORIGINS),因此此类客户端会收到 403。以进程或服务器形式运行的客户端不会发送 Origin,不受影响。
  • Agent 令牌无法选择域名名称服务器的目标位置。 migrate-nameservers 会将名称服务器迁移到应用程序的 DNS 主机;指定 target 或 nameservers 需要平台自身的凭据。
  • 绝不支持任意 DNS 写入。 如果你需要写入自定义记录,这不是适合的服务;请使用 REST API 或你所用提供商自己的服务。
  • API 密钥的速率限制按凭据计算。 将调用分散到多个密钥上的工作区,每个密钥都有各自的额度桶;Agent 令牌则在每个工作区内共享一个额度桶。连接数也会按 UTC 日历月计量,并受套餐额度限制。
  • 此仓库不包含服务端源代码。 这里提供的是清单和契约;服务端托管在其他位置。

安全

本仓库中不应存放任何凭据,这里也没有。MCP 服务本身不持有任何密钥:它会将你的凭据转发给控制平面,并在不存储 Agent 令牌的情况下对其进行验证。对于 Agent 会接触的内容,优先使用委派的 Agent 令牌(范围受限、可撤销、有效期为 15 分钟)或应用级 JWT,而不是工作区级的 cd_live_ 密钥。请按“支持”部分所述报告漏洞,切勿在公开议题中披露。

相关项目

贡献

欢迎在此提交有关文档和清单的问题与拉取请求。工具行为的变更在上游私有单体仓库中进行:请提交议题描述所需行为,相关请求会转交处理。请确保 TOOLS.md 与线上工具架构保持一致;如果拉取请求只修改其中一项而未修改另一项,我们会要求补齐。

支持

许可证

MIT。CustomDomain™ 是 EverJust Company 的产品。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。