先说结论
我们查过的远程 MCP 服务器,大多有自己独立的域名。2026年10月2日,在端点要求登录的 22 个服务中,14 个用的是 mcp.<domain>/mcp,另有 6 个用 mcp. 域名但不带路径或带版本号路径,还有 2 个用 api. 域名。地址没有统一标准,路径也猜不出来,所以要公布确切的 URL。我们把自己的地址从 scorestarling.com/mcp 迁到了 https://mcp.scorestarling.com/mcp,好让网站上的 /mcp 变成给人看的连接指南。
公开的 MCP 服务器都用什么 URL?
大多是专用的 mcp. 子域名,路径通常是 /mcp。当时我们正在 mcp.scorestarling.com/mcp 和 ElevenLabs 那种写法 api.scorestarling.com/v1/mcp 之间犹豫,想知道其他服务实际怎么做,就去查了一圈。
2026年10月2日 17:40 至 17:42(UTC),我们向 27 个服务的 33 个地址各发了一个不带认证信息的 POST 请求:请求体为 {},带 Accept: application/json, text/event-stream 请求头,超时 8 秒,只记录状态码。401 表示这个地址上有服务响应,并且需要令牌,受保护的 MCP 服务器正是这样开始登录流程的。404 表示这个路径下没有任何服务。有些地址是各服务公开的,另一些是我们为了看哪些路径有响应而尝试的变体和猜测。这只是一些知名服务的快照,不是普查,其中任何一个此后都可能有变化。
| 模式 | 服务数 | 返回 401 的地址 |
|---|---|---|
| mcp. 子域名,路径为 /mcp | 14 | mcp.notion.com/mcp, mcp.linear.app/mcp, mcp.sentry.dev/mcp, mcp.supabase.com/mcp, mcp.canva.com/mcp, mcp.higgsfield.ai/mcp, mcp.runwayml.com/mcp, mcp.airtable.com/mcp, mcp.gamma.app/mcp, mcp.posthog.com/mcp, mcp.wix.com/mcp, mcp.intercom.com/mcp, mcp.monday.com/mcp, mcp.paypal.com/mcp |
| mcp. 子域名,不带路径或带版本号路径 | 6 | mcp.stripe.com、mcp.vercel.com、mcp.box.com、mcp.miro.com;mcp.atlassian.com/v1/mcp、mcp.asana.com/v2/mcp(Asana 的 mcp.asana.com/sse 也返回了 401) |
| api. 子域名,带路径 | 2 | api.elevenlabs.io/v1/mcp、api.githubcopilot.com/mcp/(GitHub) |
| 主站或文档站上的路径 | 0 | 没有;huggingface.co/mcp 和 learn.microsoft.com/api/mcp 返回了 400 |
| 合计 | 22 | 23 个地址,因为 Asana 在两个地址上都返回了 401 |
| 结果 | 地址 | 说明了什么 |
|---|---|---|
| 404 | mcp.stripe.com/mcp, mcp.vercel.com/mcp, mcp.higgsfield.ai, api.elevenlabs.io/mcp | 该路径下没有端点;这几个服务都在同一域名的另一个路径上返回了 401 |
| 400 | mcp.figma.com/mcp, huggingface.co/mcp, learn.microsoft.com/api/mcp, docs.mcp.cloudflare.com/mcp | 有服务响应,但拒绝了我们的空请求;我们没有深究 |
| 无响应 | mcp.suno.com/mcp, mcp.elevenlabs.io/mcp | 8 秒内没有任何 HTTP 响应 |
最有用的教训来自那几个 404:MCP 的 URL 无法从域名推断出来。Stripe 和 Vercel 在不带路径的域名上响应,访问 /mcp 反而返回 404;Higgsfield 正好相反;ElevenLabs 则必须带上 /v1。客户端只会原样使用拿到的 URL,而 RFC 9728 把这个 URL 定为服务器元数据必须匹配的身份标识,所以文档、安装链接和插件清单里必须是同一个字符串。插件清单里的写法更是五花八门:在我们装过的插件中,有直接挂在 gitlab.com 主站路径上的 gitlab.com/api/v4/mcp,还有 mcp.hubspot.com/anthropic。这两个我们没有探测。
MCP 端点该和网站共用一个域名吗?
我们认为不该。端点是给软件用的,连接指南是给人看的,两者都想占用那个最直观的地址。2026年10月2日之前,scorestarling.com/mcp 是我们的 MCP 服务器,指南只能放在别处;而且每个客户端都是靠这个 URL 返回的 401 找到登录入口的,它不可能同时又是一个网页。
我们考虑过在同一个 URL 上同时提供两者,给浏览器返回网页、给客户端返回 MCP,但没有把它当作长期方案:对请求的判断只要错一次,所有客户端都会找不到登录入口。传输规范还允许客户端向端点发送 GET 请求来打开事件流,期待的回复是事件流或 405,而不是一个 HTML 页面。
单独的域名还能让网站的改动影响不到端点:网站改版挪不动它,适合营销网站的 CDN 缓存或浏览器人机验证也永远不会挡在它前面。AI 助手是从自己的基础设施而不是浏览器调用服务器的:Anthropic 的连接器文档说,Claude 从 Anthropic 的云端发起连接,身份提供方前面的防火墙可能导致登录失败。我们看过的两家同行也是这样拆分的(2026年10月2日查看,10月3日复核):Higgsfield 的指南在 higgsfield.ai/mcp,服务器在 mcp.higgsfield.ai/mcp;ElevenLabs 的指南在 elevenlabs.io/mcp,服务器在 api.elevenlabs.io/v1/mcp。
我们的 MCP 域名只提供 /mcp 和 /.well-known/*。其他路径一律以 308 重定向到网站上相同的路径和查询参数,这样登录、授权同意、页面、下载链接和 Cookie 都留在同一个域名下。网站上的 /mcp 现在是 Claude、ChatGPT 等客户端的连接指南。
$ curl -si "https://mcp.scorestarling.com/login?x=1"
HTTP/2 308
location: https://scorestarling.com/login?x=1
选 mcp.example.com/mcp、不带路径的域名,还是 api.example.com/v1/mcp?
三种都可以,看这个域名上还放了什么。MCP 授权规范把 https://mcp.example.com/mcp 和 https://mcp.example.com 都列为合法的标准服务器 URI,并要求使用不带末尾斜杠的形式,除非斜杠有实际含义。传输规范只要求有一个同时接受 POST 和 GET 的端点路径,示例是 https://example.com/mcp;Anthropic 的连接器文档用的则是 https://mcp.example.com/mcp。
| 方案 | 采用者(2026年10月2日) | 对我们来说 |
|---|---|---|
| mcp. 域名 + /mcp(最终选择) | 14 个服务,包括 Notion、Linear、Canva、Higgsfield 和 Runway | 样本中最常见的模式;我们的服务器本来就在 /mcp 上响应,只需要换域名 |
| 不带路径的 mcp. 域名 | Stripe、Vercel、Box、Miro | 最短,但要改更多代码,还得先多发一个版本 |
| api. 域名 + /v1/mcp | ElevenLabs;GitHub 用的是 api.githubcopilot.com/mcp/ | 适合在这个域名上提供公开开发者 API 的公司;我们没有 |
还有两条小规则。Streamable HTTP 端点不要以 /sse 结尾:Anthropic 的文档说,在 Claude 的连接器表单里,以它结尾的 URL 会选用旧的 SSE 传输方式。另外,除非确有必要,不要加末尾斜杠;返回 401 的 23 个地址里,只有 GitHub 的带了斜杠。
怎样把 MCP 服务器迁移到新 URL?
让新旧两个地址并行一段时间,并且每个地址都要能独立完整地工作:有自己的 401、自己的元数据,两种受众的令牌都能用。我们分四步完成迁移,在 2026年10月2日晚(UTC)一小时内全部上线:
趁还没有任何地方用到,先上线别名支持。用一项配置列出以前的地址,每个都必须是 HTTPS、以
/mcp结尾。令牌的受众是当前地址或某个别名时验证通过,其他受众一律拒绝。主机白名单(Starlette 的可信主机列表和 MCP SDK 的 DNS 重绑定防护)包含所有地址以及网站本身。没有设置别名时,生产环境的行为与以前完全一样。添加新域名,然后在同一次变更中切换地址并设置别名。新子域名先配好 DNS 记录,大约 6 分钟后证书也签发了;在我们的服务器被配置为信任它之前,这个域名一直返回 400。一次配置变更既设置了新的资源 URL,又把旧地址列为别名,所以只重新部署一次就让两者同时生效。如果在第 1 步上线前就这样做,正在运行的代码会拒绝网站自己的域名。
把所有会被人复制的地方都改指向新地址:连接指南(包括为 Claude、Cursor 和 VS Code 编码好的一键安装链接)、插件清单和文档。
切换令牌受众,然后停用旧地址。一次数据库迁移让我们的访问令牌钩子改为签发新的受众,CI 在代码上线前就应用了这次迁移;别名还在时,两种受众的令牌都照常可用。随后我们删除别名并重新部署。在那次发布和重新部署之间的几分钟里,网站的
/mcp对浏览器返回指南,对 MCP 客户端返回服务器。现在它只提供指南,指南原来的地址/connect则以 308 重定向过来。
最容易漏掉的是元数据。RFC 9728 要求其中的 resource 与客户端连接时用的 URL 完全一致,Anthropic 的文档也要求它与用户在 Claude 里填写的 URL 相同。所以在新旧并行期间,每个域名都描述它自己,每个 401 都指向本域名下的元数据文档:
GET https://scorestarling.com/.well-known/oauth-protected-resource/mcp
→ "resource": "https://scorestarling.com/mcp"
GET https://mcp.scorestarling.com/.well-known/oauth-protected-resource/mcp
→ "resource": "https://mcp.scorestarling.com/mcp"
我们没有对 /mcp 本身做重定向。传输规范没有为端点规定重定向行为,而端点 URL 作为资源(resource)和令牌受众,是 OAuth 握手的一部分,所以我们选择在两个地址上同时提供 MCP。其他路径则用 308 而不是 301,这样能保留请求方法,因为 RFC 9110 不允许客户端在收到 308 后把 POST 改成 GET。受众是怎样写进令牌的,见我们关于 MCP OAuth 的笔记。
我们能迁得这么快,是因为 ScoreStarling 当时还处在仅限邀请的小规模试运营阶段,还没有人依赖旧地址。别名删除后,仍配置着 scorestarling.com/mcp 的客户端必须重新连接。按照我们运维手册的预期,已经改用新地址、手里却还是旧受众令牌的客户端,会收到一次 401 invalid_token,随后刷新令牌、拿到新受众;不过我们还没亲眼看到真实的 Claude 或 ChatGPT 客户端这样做。如果已经有真实用户,就保留别名,直到旧地址不再有流量。
迁移过程中出了哪些问题?
过程中出了三个小问题:
- 一个检查脚本用
resource.replace('/mcp', '/.well-known/oauth-protected-resource/mcp')拼接元数据 URL。旧地址上没问题;换成https://mcp.scorestarling.com/mcp后,//mcp.里的/mcp也被匹配到了,结果变成https://.well-known/oauth-protected-resource/mcp.scorestarling.com/.well-known/oauth-protected-resource/mcp。正确的做法是先解析 URL,再按各部分拼接:协议和主机名,然后是 well-known 段,最后是路径。 - 地址变长后,在 320 像素宽的屏幕上撑破了指南页的版面,直到我们允许行内代码换行才解决。
- 用 Railway 命令行工具删除别名变量,只是把改动暂存了起来;直到我们手动重新部署,旧地址都还被接受。
MCP 服务器地址选择清单
- 给端点一个专用域名,不在上面放任何给人看的内容;在我们的样本中,常见做法是
mcp.加上你的域名。 - 路径一次定好。
/mcp最常见,不带路径的域名也合法;不要加末尾斜杠,也不要让路径以/sse结尾。 - 给人看的连接指南放在主站上,用一个猜得到的地址,并在导航里加上链接。
- 为这个确切的 URL 提供 RFC 9728 元数据:放在
/.well-known/oauth-protected-resource加上你的路径处,根路径下也放一份,其中的resource要等于客户端使用的地址。 - 把这个 URL 设为令牌受众,并在需要迁移之前就做好别名支持。
- MCP 域名上的其他所有路径都用 308 重定向到你的网站,并保留查询字符串。
- MCP 域名上不要启用浏览器人机验证和 HTML 缓存。
- 所有地方(指南、安装链接、插件清单、文档)都只公布同一个字符串,并测试每一处是否一致。
- 迁移顺序:先做别名支持,再在同一次变更中切换新地址、设置别名,然后改掉每一处引用,切换受众,等旧地址没有流量后再停用。
参考资料
- MCP 规范(2025-11-25 版):传输 — Model Context Protocol
- MCP 规范(2025-11-25 版):授权 — Model Context Protocol
- RFC 9728:OAuth 2.0 受保护资源元数据 — IETF
- RFC 9110:HTTP 语义,§15.4.9 308 永久重定向 — IETF
- 添加不在目录中的连接器 — Anthropic
- 连接器的身份验证 — Anthropic
- Higgsfield MCP — Higgsfield
- ElevenLabs Agents & Creative MCP — ElevenLabs
常见问题
MCP 服务器的 URL 一定要以 /mcp 结尾吗?
不用。MCP 规范只要求有一个端点路径,并把 https://mcp.example.com 和 https://mcp.example.com/mcp 都列为合法的服务器 URI。在我们 2026年10月2日的样本中,要求登录的 22 个服务里有 18 个用了 /mcp 或 /v1/mcp 这类路径,另外 4 个直接在不带路径的域名上响应。选定一种,公布时一字不差即可。
连接指南页和 MCP 端点能共用一个 URL 吗?
可以在同一个 URL 上给浏览器返回网页、给 MCP 客户端返回服务器,但除了迁移期间的几分钟,我们没有这样做。只要误判一次请求,客户端就找不到登录入口;而且 Streamable HTTP 客户端可能会向端点发送 GET 请求,期待收到事件流或 405。我们的指南在 scorestarling.com/mcp,服务器则有自己的域名。
更换 MCP 服务器的 URL 会让用户断开连接吗?
只有停用旧地址时才会。这个 URL 既是 OAuth 的资源(resource),也是令牌的受众(audience),所以旧地址一旦不再响应,仍配置着旧地址的客户端就得重新连接。过渡期内让两个地址同时提供服务:两种受众都接受,每个地址各有自己的元数据,等旧地址没有流量了再停用。
向 MCP URL 发 POST 请求,返回 401、404 或 400 分别是什么意思?
在我们的调查中,401 表示受保护的端点有响应,并要求提供令牌;404 表示这个路径下什么都没有。400 只能说明某个环节拒绝了我们的空测试请求体,我们没有进一步解读。要正确测试一个服务器,请用真正的 MCP 客户端去连接。
MCP 服务器的 URL 末尾要加斜杠吗?
最好不加。MCP 授权规范要求实现方使用不带末尾斜杠的形式,除非斜杠有实际含义。在我们调查中返回 401 的 23 个地址里,只有 GitHub 的 api.githubcopilot.com/mcp/ 带了斜杠。