ClaudeClaude Code

给 Claude 写连接器:远程 MCP 服务器从快速上手到上架目录,本站实测了授权、超长结果和 MCP Apps

按 claude.com 的连接器开发文档整理:连接器、插件、MCP App 各是什么,远程服务器要定的四件事,claude.ai 的登录要求,连不上时查什么,上架目录的审核标准。本站在服务器上照官方快速上手搭了一个,用 Claude Code 实测了调用、授权、只读标注、超长结果和 MCP App 的返回。

发布 · 约 18 分钟读完 · 经人工审核()· 本站的内容怎么来的

本站已实测,测试日期:2026-10-16。

本页目录(9 节)
  1. 一、先分清几样东西
  2. 二、动手之前要定的四件事
  3. 三、本站实测:照官方快速上手搭一个
  4. 四、给 claude.ai 的用户用:公网地址和登录(本站没有实测)
  5. 五、连不上时先查这几样
  6. 六、上架目录(本站没有实测)
  7. 七、只在用户电脑上跑的:MCPB
  8. 没有实测的部分
  9. 参考

这篇解决一个问题:你有一个产品或者公司内部的系统,想让 Claude 能查它、操作它,而且不只在你自己的 Claude Code 里,claude.ai、桌面和手机应用里的用户也能用。

做法是写一个远程 MCP 服务器,用户在 Claude 里看到的就是一个“连接器”。本站的《Claude Code 接 MCP 服务器实战》讲的是把现成的服务器接进自己的 Claude Code,自己写的那个例子是只在本机跑的 stdio 服务器。这篇讲给别人用的远程服务器,内容按 claude.com 的连接器开发文档整理。

哪些实测了、哪些没有: 本站在服务器上照官方的快速上手搭了一个,用 Claude Code 测了调用、没授权时会怎样、只读标注、超长的结果、隧道的 Host 检查、MCP Inspector、MCP App 返回的内容。claude.ai 和桌面应用里的部分(加自定义连接器、OAuth 登录、MCP App 的界面、上架目录)要公网地址和 claude.ai 账号,没有实测,照文档写。

一、先分清几样东西

名字 是什么
连接器 用户在 Claude 里看到的 MCP 服务器。claude.ai、桌面、手机、Cowork、Claude Code 用的是同一套连接器基础设施
插件 一个包,可以装连接器(指向你的服务器)、skills、命令、子代理、MCP App 里的任意几样。只装一样也是完整的插件
MCP App 你的服务器在对话里显示的交互界面,比如图表、地图、表单。可选
MCPB 把本地的 MCP 服务器打成一个 .mcpb 文件,Claude 桌面应用双击就能装
自定义连接器 用户或组织的 Owner 填你的网址加进来,Anthropic 不审
目录里的连接器 经 Anthropic 审核后列在 claude.ai/directory,用户能搜到

自定义连接器和目录里的连接器跑在完全相同的基础设施上,差别只在审核、能不能被搜到和分发方式。所以自定义连接器上能用的,上架以后也能用;官方也没有单独的测试环境,测试就是把它当自定义连接器加进自己的 Claude。

给自己的产品做集成,官方建议连接器和 skills 都做:连接器让 Claude 够得着你的产品,skills 教它按你设计的方式用,而不是让每个用户自己摸索。已经有公开的 API 或命令行工具、Claude 能直接用的,插件里可以只放 skills,不要连接器。

二、动手之前要定的四件事

一、跑在哪里。 给别人用的,跑在你自己的服务器上,走公网,传输方式用 Streamable HTTP(旧的 HTTP+SSE 还支持,但在淘汰)。只在用户电脑上跑的本地服务器,桌面应用用 MCPB 打包,见第七节。

二、用户怎么登录。 要在写工具之前定。Claude 支持的几种:

类型 是什么 能不能直接用
oauth_dcr OAuth 2.0,Claude 用动态客户端注册(DCR)自己注册 默认支持
oauth_cimd OAuth 2.0,用客户端 ID 元数据文档(CIMD) 默认支持
oauth_anthropic_creds OAuth 2.0,用 Anthropic 持有的客户端凭据 要发邮件给 mcp-review@anthropic.com
custom_connection 连接时由用户填网址或 OAuth 客户端凭据 同上
static_headers Owner 加连接器时填一个 API key 或 bearer token,每个请求带在请求头里 测试阶段,只对一部分组织开放
none 不登录 默认支持

三、暴露什么。 工具、提示词、资源都行,工具结果可以是文字或图片,资源可以是文字或二进制。Claude 还不支持资源订阅、sampling 和草案阶段的能力,别依赖它们。

四、结果多大、跑多久。 两边的限制不一样:

限制 claude.ai 和桌面应用 Claude Code
一次工具结果的大小 约 15 万个字符 25,000 token,可以用 MAX_MCP_OUTPUT_TOKENS 改
一次工具调用的超时 240 秒 可以用 MCP_TOOL_TIMEOUT 改

想让 Claude Code 帮你写,官方有一个插件 mcp-server-dev,它的 skills 会照这套文档一步步带你建、测、打包。

三、本站实测:照官方快速上手搭一个

实测环境
日期 2026-10-16
系统 Ubuntu 24.04,Node.js 22.23.2
Claude Code 2.1.300,用 claude -p 跑,模型指定 Sonnet 5.5(--model sonnet)
接口 通过酷站AI 中转站,不是直连官方。这次测的都是 Claude Code 和本机服务器之间的事,和接口走哪条路无关
装到的版本 @modelcontextprotocol/sdk 1.32.1,zod 4.6.7,@modelcontextprotocol/ext-apps 1.7.5(官方页面核对时用的是 1.30.1、4.6.5、1.7.5)

建项目、写服务器

mkdir mcp-quickstart && cd mcp-quickstart
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/sdk zod

整个服务器一个文件 server.mjs,照官方快速上手写,只有一个掷骰子的工具 roll_dice。我们加了一行,把每个请求的方法和客户端信息记进日志:

import { appendFileSync } from 'node:fs';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { createMcpExpressApp } from '@modelcontextprotocol/sdk/server/express.js';
import { z } from 'zod';

const log = (o) => appendFileSync('requests.log', JSON.stringify(o) + '\n');

function buildServer() {
  const server = new McpServer({ name: 'quickstart-server', version: '1.0.0' });
  server.registerTool(
    'roll_dice',
    {
      title: 'Roll dice',
      description: 'Roll `count` dice with `sides` sides each. Returns each roll and the total.',
      inputSchema: {
        sides: z.number().int().min(2).max(100).describe('Number of sides per die (2-100)'),
        count: z.number().int().min(1).max(10).default(1).describe('How many dice to roll (1-10)'),
      },
    },
    async ({ sides, count }) => {
      const rolls = Array.from({ length: count }, () => 1 + Math.floor(Math.random() * sides));
      const total = rolls.reduce((a, b) => a + b, 0);
      return { content: [{ type: 'text', text: `Rolled ${count}d${sides}: [${rolls.join(', ')}] total=${total}` }] };
    },
  );
  return server;
}

// 每条 MCP 消息都是一个发到 /mcp 的 POST。不保留会话,每个请求新建一个 server。
const app = createMcpExpressApp();
app.post('/mcp', async (req, res) => {
  log({ method: req.body?.method, clientInfo: req.body?.params?.clientInfo });
  const server = buildServer();
  const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
  res.on('close', () => { transport.close(); server.close(); });
  await server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});
const notAllowed = (req, res) => res.status(405).json({ jsonrpc: '2.0', error: { code: -32000, message: 'Method not allowed.' }, id: null });
app.get('/mcp', notAllowed);
app.delete('/mcp', notAllowed);

const PORT = Number(process.env.PORT ?? 3000);
app.listen(PORT, '127.0.0.1', (err) => {
  if (err) { console.error(`failed to listen on ${PORT}: ${err.message}`); process.exit(1); }
  console.log(`quickstart-server listening on http://localhost:${PORT}/mcp`);
});

我们的服务器上 3000 端口已经被别的程序占了,所以用 PORT=3456 node server.mjs 启动。

先用 curl 测,不经过 Claude

curl -sS -X POST http://localhost:3456/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"roll_dice","arguments":{"sides":20,"count":3}}}'
event: message
data: {"result":{"content":[{"type":"text","text":"Rolled 3d20: [14, 2, 4] total=20"}]},"jsonrpc":"2.0","id":3}

几处和文档对得上的细节:

  • 不带 Accept 头,返回 406。
  • tools/list 列出 roll_dice,inputSchema 是 zod 生成的 JSON Schema:sides 必填,count 默认 1。
  • 参数超出范围(sides: 1000)时,不是协议层面的报错,而是一个 isError: true 的工具结果,文字写明了哪个参数、为什么不对。审核标准要求的“返回能照着改的错误信息”,SDK 的参数校验已经替你做了一部分。
  • GET /mcp 返回 405。

接进 Claude Code

claude mcp add --transport http quickstart http://localhost:3456/mcp
claude mcp list
Added HTTP MCP server quickstart with URL: http://localhost:3456/mcp to local config
……
quickstart: http://localhost:3456/mcp (HTTP) - ✔ Connected

注意要在项目目录里运行:claude mcp add 默认存到当前项目,换个目录 Claude Code 就看不到它了。然后让 Claude 调它,--allowedTools 放行这个工具,工具名的格式是 mcp__<服务器>__<工具>:

claude -p "Roll three 20-sided dice using the quickstart server and tell me each roll and the total." \
  --model sonnet --allowedTools "mcp__quickstart__roll_dice" \
  --output-format stream-json --verbose

从输出里挑出工具调用和结果:

tool_use: mcp__quickstart__roll_dice {"sides": 20, "count": 3}
tool_result: [{"type": "text", "text": "Rolled 3d20: [1, 14, 2] total=17"}]

服务器的日志里,Claude Code 在握手时报的客户端信息是:

{"name": "claude-code", "title": "Claude Code", "version": "2.1.300", "description": "Anthropic's agentic coding tool", "websiteUrl": "https://claude.com/claude-code"}

文档提醒:clientInfo 在不同的 Claude 应用、不同的请求路径上不一样,claude.ai 那边可能是 claude-ai 或 Anthropic,而且谁都可以冒充,只能拿来做统计,不能拿来做权限判断。

没授权的工具会被拦下

把 --allowedTools 去掉,用 --permission-mode default(我们的测试账号默认是 auto 模式,不显式指定的话看不出差别):

tool_use: mcp__quickstart__roll_dice {"sides": 20, "count": 3}
tool_result: Claude requested permissions to use mcp__quickstart__roll_dice, but you haven't granted it yet.

claude -p 没有人能点“允许”,工具没跑。Claude 回答说它没拿到结果,不会编数字。

只读标注在 Claude Code 里不等于免确认

审核标准要求每个工具都带标注:只读的写 readOnlyHint: true,会改或删数据的写 destructiveHint: true。文档说这些标注决定了 Claude 里的自动授权:只读的工具可以不用每次确认,破坏性的总要确认。

我们在 buildServer() 里 return server; 前面加了一个标了只读的工具:

server.registerTool(
  'dice_help',
  {
    title: 'Dice notation help',
    description: 'Explain dice notation such as 3d20. Read-only, no side effects.',
    inputSchema: {},
    annotations: { readOnlyHint: true },
  },
  async () => ({ content: [{ type: 'text', text: 'NdM means roll N dice with M sides each.' }] }),
);

同样不放行、用 --permission-mode default 跑,照样被拦,提示和上面一样(2026-10-16 审核时又跑了一次,结果相同)。也就是说,在 Claude Code 2.1.300 里,免不免确认看的是 Claude Code 自己的权限设置,不看工具的标注。标注照样要写:上架要求它,claude.ai 那边用它;Claude Code 的 Agent SDK 文档里说,它还决定几个工具能不能并行调用。

结果太长时,Claude Code 存成文件

我们再加了一个工具,按参数返回很多行文字,让它返回 6 万行,约 83 万个字符,远超 Claude Code 的 25,000 token。结果没有被截断,Claude Code 给模型的是这样一段:

Error: result (828,893 characters across 60,000 lines) exceeds maximum allowed tokens. Output has been saved to /home/ccdemo/.claude/projects/-home-ccdemo-demo-h56-connector/…/tool-results/mcp-quickstart-dump_rolls-….txt.

然后 Claude 自己用 wc -l 和 tail 去读那个文件,答出了行数和最后一次的结果。在 Claude Code 里这样还能救回来;claude.ai 上没有这个文件可读,超过约 15 万字符就是失败。审核标准也要求结果的大小和任务相称,别在要一份摘要的时候返回整个数据库。分页、过滤、给摘要,要在服务器上做。

隧道的 Host 检查

claude.ai 是从 Anthropic 的机器连你的服务器,localhost 它够不着。本机的服务器想让 claude.ai 测,文档建议用 Cloudflare Tunnel 或 ngrok 暴露出去。但 createMcpExpressApp() 默认带防 DNS 重绑定的检查,只认 localhost、127.0.0.1、[::1]。我们模拟了一个从隧道进来的请求:

curl -sS -X POST http://localhost:3456/mcp -H 'Host: abc123.example.com' \
  -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":5,"method":"tools/list","params":{}}'
{"jsonrpc":"2.0","error":{"code":-32000,"message":"Invalid Host: abc123.example.com"},"id":null}

状态码 403,和文档写的一样。用隧道测时,把隧道的主机名加进 allowedHosts:

const app = createMcpExpressApp({ allowedHosts: ['localhost', '127.0.0.1', 'abc123.example.com'] });

隧道会把你的服务器暴露到公网,测的时候保持登录开着,测完就关。

MCP Inspector

接 Claude 之前,可以先用 MCP Inspector 的命令行模式检查协议和工具定义:

npx @modelcontextprotocol/inspector --cli http://localhost:3456/mcp --transport http --method tools/list
npx @modelcontextprotocol/inspector --cli http://localhost:3456/mcp --transport http \
  --method tools/call --tool-name roll_dice --tool-arg sides=6 --tool-arg count=2

两条都正常返回:第一条列出服务器上的工具和各自的标注(dice_help 带着 readOnlyHint: true),第二条返回 Rolled 2d6: [4, 2] total=6 这样的结果。文档说的“Claude Code 能连、Inspector 能连、claude.ai 连不上”的情况,用它对照很方便,见第五节。

MCP App:给工具加界面

照官方的第二个快速上手,装 @modelcontextprotocol/ext-apps@^1,把 registerTool 换成 registerAppTool,在工具上加 _meta.ui.resourceUri 指向一个 ui:// 资源,再用 registerAppResource 注册这个资源,内容是一段 HTML。工具的结果里同时返回给人看的 content 文字和给界面用的 structuredContent。

用 curl 看,三样都和文档一致:tools/list 里工具多了 _meta(还附带一个旧的平铺写法 ui/resourceUri);resources/read 返回的类型是 text/html;profile=mcp-app;tools/call 的结果里两样都有。

界面要在支持 MCP App 的地方才显示,比如 Claude 桌面应用,Claude Code 只把它当普通工具。我们让 Claude Code 调了一次,有一个细节值得知道:它交给模型的是 structuredContent 那份 JSON,不是 content 里的文字:

tool_result: {"sides":6,"count":4,"rolls":[5,2,3,6],"total":16}

所以 structuredContent 也要写得让模型看得懂,别只放给界面用的内部字段。界面怎么在桌面应用里显示,本站没有图形环境,没有测。

花费

每次 claude -p 用 Sonnet 5.5 约 0.07 到 0.12 美元(Claude Code 按官方价估算),这一节全部跑下来不到 1 美元。

四、给 claude.ai 的用户用:公网地址和登录(本站没有实测)

服务器要有一个公网的 HTTPS 地址,用户在 Customize > Connectors 里按网址加成自定义连接器,Free 到 Enterprise 都能加。加完之后检查三样:显示 Connected;工具权限里列出了每个工具,名字和说明是你写的;在对话里真调一次,看服务器收到的参数和 Claude 读到的结果。

你也可以在自己的文档里放一个安装链接,打开就是填好名字和网址的“添加自定义连接器”对话框:

https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Example&connectorUrl=https%3A%2F%2Fmcp.example.com%2F

链接只是预填,用户确认了才会加上。

用 OAuth 时,要对上 Claude 的客户端:

  • 授权规范的版本:Claude 跟的是 MCP 授权规范的 2025-03-26、2025-06-18 和 2025-11-25 三版。

  • 回调地址:claude.ai、桌面、手机和 Cowork 用下面这个固定的地址;Claude Code 用本机回环地址,端口每次不一样,比如 http://localhost:3118/callback,localhost 和 127.0.0.1 两种都要接受,并且忽略端口。同意页面上要清楚显示回调地址的主机名。

    https://claude.ai/api/mcp/auth_callback
  • 刷新令牌:令牌过期时 Claude 会自己刷新。

  • 响应时间:发现、注册、换令牌的接口 10 秒内要响应,刷新令牌 30 秒。超时就算失败,哪怕你的服务器后来做完了。

两种特殊的登录方式:

  • 懒登录。 有的工具不需要用户的账号(比如浏览商品目录),有的需要(比如看订单)。可以先让用户直接用不需要登录的工具,Claude 调到要登录的工具时,才在对话里弹出登录,登录完自动重试这次调用。要点:必须在 HTTP 层返回 401 并带 WWW-Authenticate: Bearer 头,在请求进 MCP SDK 之前判断,因为工具处理函数里返回什么都会被包成 200。
  • 企业统一登录(Enterprise Managed Auth)。 Team 和 Enterprise 的用户通过组织的 SSO 连接,不用再过一遍 OAuth 的同意页面。服务端支持之后,发邮件给 mcp-review@anthropic.com,在目录的列表上标出来。

五、连不上时先查这几样

claude.ai 报 “Couldn’t reach the MCP server”,不一定是网络问题。按顺序查:

  1. 主机名解析到了私有地址。 claude.ai 在发任何请求之前,先解析你的主机名并检查地址:解析到 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、运营商级 NAT 的 100.64.0.0/10、回环或链路本地地址,或者公网和私有地址混在一起,都直接拒绝,你的服务器日志里什么都看不到。连接器只走 IPv4,只有 AAAA 记录的主机名连不上。内外网解析不一样的(split-horizon DNS)、动态 DNS、只在 VPN 里能解析的公司内网域名,是常见的原因。从外网 dig +short 一下就知道。
  2. 防火墙、WAF、CDN 拦了 Anthropic 的流量。 边缘或 CDN 的日志里有不是你的程序返回的 403、429。把 Anthropic 公布的出站 IP 段加进白名单,或者让 MCP 和 OAuth 的路径绕开拦截规则。
  3. 注册的网址会重定向到另一个主机。 比如裸域名跳 www.、按地区跳转、自定义域名跳 CDN。按 HTTP 客户端的惯例,跨主机重定向时 Authorization 头会被丢掉,目标收到一个没带凭据的请求,返回 401,最后报成授权失败。注册服务器真正监听的那个网址。
  4. OAuth 的发现接口有问题。

“Claude Code 和 curl 能连,claude.ai 不能连”,多半是第 1 或第 3 条:本地的客户端从你的机器出发,碰到跨主机重定向会直接失败,问题马上暴露;claude.ai 从 Anthropic 的机器出发,会跟着重定向走,丢掉凭据,到后面才报授权错误。

工具调用报 “Unexpected error while invoking tool”,说明连接和登录都没问题,是你的服务器对这次调用返回了错误。用 MCP Inspector 跑同样的调用,再查服务器的日志。

六、上架目录(本站没有实测)

谁能提交: Pro、Max、Team、Enterprise 套餐都行,Free 不行,不用先申请什么合作计划。Pro 和 Max 用自己的账号提交;Team 和 Enterprise 由 Owner 提交,Enterprise 还可以给别的成员开 Directory 权限。列表归提交时所在的组织。提交和维护都在开发者门户 claude.ai/directory/manage。

提交什么: 两种,插件包(来自一个 GitHub 仓库,上线前必须公开)和 MCP 连接器(只要服务器的网址)。有远程服务器的,连接器要单独提交一次,即使插件里已经引用了它:这样你才有连接器的列表、它的面板(服务器健康、按工具分的用量),还能把两个列表配对。插件里引用同一个网址,同时装了两样的用户看到的是一套工具,不是两套。skills 不能单独提交,要放进插件包。目录已经不收 MCPB 了,本地服务器要上目录,放进插件包里。

怎么审: 每个连接器提交后自动扫描是否合规,默认作为 Community 连接器上架;Anthropic 可能把有用的升级到 Verified 审核,由人逐个测工具,你不用申请。

审核标准里最常见的拒绝原因:

  • 读和写要拆开。 一个工具同时接受 GET 和 POST、PUT、PATCH、DELETE 会被拒,别做一个带 method 参数的万能 api_request。最好再按新建、修改、删除拆开。在说明里写清楚哪些安全也不行,必须是分开的工具。
  • 让调用方自己拼请求的工具,说明里要写明是哪个 API,给出文档链接或名字。
  • 每个工具都要有 title 和对应的 readOnlyHint 或 destructiveHint。
  • 工具名不超过 64 个字符,说明要准确,和实际行为一致。
  • 说明里不能有提示词注入的写法: 让 Claude 去调用户没要的软件或工具、干扰它调别的工具、让它从外部拉行为指令、藏着或编码过的指令、让它做和工具无关的事、试图覆盖系统指令、推销产品。只描述工具做什么,不要指挥 Claude 怎么做事。
  • 功能质量: 参数正确时每个工具都要返回成功;报错不能只有 “Internal Server Error”“Bad Request”;校验输入;结果大小和任务相称;不收集工具用不着的对话数据;不去读 Claude 的记忆、聊天记录、对话摘要和用户的文件。
  • 只调自己的 API(或者你合法代理的),服务器的域名要和你的服务对得上。
  • 不收的用途: 转账、转加密货币等金融资产;用 AI 模型生成图片、视频、音频。画图表、流程图、界面草图的可以。

要一起交的: 测试账号,必须是有真实数据的账号,不能是空壳,还要附上给不熟悉你们服务的人看的设置步骤;公开的使用文档,上线前要有,一篇博客或帮助中心的文章就够;用了 MCP App 并且会打开外链的,列出允许直接打开的网址。门户的“Test & launch”一步会让你确认每个工具都用 MCP Inspector 和自定义连接器测过。

上架后的列表网址是下面这样,slug 批下来以后不能改:

https://claude.ai/directory/connectors/<slug>

七、只在用户电脑上跑的:MCPB

要访问防火墙后面的系统(内部的工单、维基、私有数据库)、用公司现有的 SSO 和浏览器会话、直接读写本地文件和 Git、调本机装的 Docker 和 IDE、数据不能离开用户电脑的,适合做成本地服务器,用 MCPB 打包给 Claude 桌面应用:

npm install -g @anthropic-ai/mcpb
mcpb init   # 生成 manifest.json
mcpb pack   # 打成 .mcpb

用户双击 .mcpb、拖进桌面应用的窗口,或者在 Settings > Extensions > Advanced settings 里装。官方强烈建议用 Node.js 写,因为桌面应用在 macOS 和 Windows 上都自带 Node。面向多个组织的公开服务、要在网页和手机上也能用的,还是做远程连接器。本站没有图形环境,MCPB 没有实测。

没有实测的部分

本站实测的是第三节:在服务器上照快速上手搭服务器,用 Claude Code 2.1.300 调用。第四到七节(claude.ai 的自定义连接器、OAuth 和两种特殊登录、连不上时的排查、上架目录、MCPB、MCP App 的界面)按 claude.com 的文档整理,没有实测。

参考

Claude 应用文档(claude.com/docs):

来源

通过 API 中转站使用这些模型?到 Veridrop 免费检测中转站给你的是不是它声称的模型,或者看看中转站排行榜前 100 名。

相关文章