MCP 的两端:OpenRouter 的 MCP server 与客户端里配的 MCP 不是一回事

2026-08-18

同一个词,两个方向。有人照着 OpenRouter 文档在编辑器里加了一条 MCP,然后问「我线上服务的请求为什么没走这个 MCP」;也有人反过来,想在自己的 agent 里接 Linear 的 MCP server,却去翻 OpenRouter 那页 MCP server 文档。这两次都不是参数配错了,是把 MCP 的两端认成了一端。

MCP 有服务端和客户端两个角色。OpenRouter 官方文档里的「MCP」至少落在两处,职责完全不同:一处是 OpenRouter 自己当服务端、被你的编辑器连过去;另一处是 @openrouter/mcp 这个包,让你的程序当客户端去连别人的服务端。下面沿着这两页文档把边界画清楚,再和 Claude Code 官方文档里写明的客户端行为对照一遍。两边都是闭源商业产品,我们只对照各自文档白纸黑字写了的东西。

第一端:OpenRouter 自己是一台被连接的远程 server

openrouter.ai/docs/guides/overview/mcp-server 这一页讲的是 OpenRouter MCP server。文档写明它是 OpenRouter 托管的远程服务,本地不安装任何东西;你要做的是在 MCP 客户端里加一个 URL,再在浏览器里完成一次 OAuth 授权。

以 Claude Code 为例,文档给出的命令是:

claude mcp add --transport http openrouter https://mcp.openrouter.ai/mcp
claude mcp login openrouter

文档同时写明,也可以在会话内跑 /mcp,选中 openrouter,点 Authenticate——这是官方文档写明的操作路径,不是我们看到的界面。

这一端的职责边界,文档自己用一个 Note 划得很死:这个 MCP 是给你在构建过程中用的,让助手不离开编辑器就能拿到 OpenRouter 的实时信息;真要在应用里跑模型,继续直接调 OpenRouter API。这句话是理解整页的钥匙。

工具那张表里,文档写明大部分是针对实时数据的只读查询,随后点出非只读的那几个:send-messagegenerate-image 会产生计费的推理调用,send-feedback 会对你自己的某次生成写入反馈。这里有个小出入值得一提——原文那句话写的是「有两个例外」,但紧接着列出来的工具是三个,按能不能改动状态来读,这三个都该当成例外看。其余像 list-modelsget-modellist-model-endpointsget-creditsget-generationsearch-docsping 这些,文档都归在查询里。

授权这一步也是同一个味道:文档写明同意页上批准的是一把专门给这条连接用的 key,与你其它 key 分开,带过期时间和默认花费上限(具体数值本文不列,以官方文档与审批页为准),可以随时断开,也能在自己的密钥管理页找到并吊销。Troubleshooting 那节写明,工具调用报鉴权错误的第一个原因就是这把 key 过期或被断开,处置办法是重跑一次你这个客户端的认证步骤。

一句话:这一端是开发期的信息通道加试打通道,不是生产流量通道。

第二端:@openrouter/mcp 是让你的程序去当客户端

openrouter.ai/docs/agent-sdk/call-model/mcp-tools 讲的是另一回事。这个包连接一台远程 MCP server(Streamable HTTP 或 SSE),把它对外声明的工具包装成 callModel 的一等工具:

const mcp = await createMCPTools({
  url: 'https://mcp.example.com/mcp',
  auth: { kind: 'bearer', token: process.env.MCP_TOKEN },
});

const result = callModel(client, {
  model: 'anthropic/claude-opus-4-8',
  input: 'What are my three most recently updated issues?',
  tools: mcp.tools,
});

示例里的 model slug 是官方文档当时的示例值,平台上有哪些模型随时在变,别当清单用。

createMCPTools() 返回的 handle 上有三样东西:mcp.tools(一个 MCP 工具对应一个 SDK 工具,直接展开进 callModel({ tools }))、mcp.serialize()mcp.close()。auth 文档给了三种形状:{ kind: 'bearer', token }{ kind: 'headers', headers }{ kind: 'oauth', provider },并建议服务端支持 OAuth 时优先用 OAuthClientProvider,理由是传输层会通过 provider 自动刷新。

这一端最该记住的边界写在开头的 Note 里:stdio MCP servers 被明确写为 intentionally out of scope,这个包只面向能通过 HTTP 访问到的远程服务端。

还有一处细节直接体现了「谁负责什么」:ToolExecutionResult 和流式的 tool.result 事件都带一个 source 判别式,只有两个取值。'client' 是你自己用 tool() 定义的工具,结果按 outputSchema 有类型;'mcp' 是包装过的 MCP 工具,结果是 unknown。文档给的理由是 MCP server 在运行时才描述自己的输出。类型的责任在这里切了一刀:跨过 MCP 这条线,类型就不归 SDK 保证了,得你自己收窄。文档还提醒,不按 source 收窄的话,一个未定型的 MCP 工具会把整个结果联合类型塌成 unknown

对照:Claude Code 把客户端的边界划在哪

Claude Code 官方文档(code.claude.com/docs/en/mcp)整页讲的都是客户端职责,正好和上面第二端对得上。

传输层。 该页列了四个安装选项:远程 HTTP(文档写明是推荐项)、远程 SSE(文档带 Warning,明确写该传输已 deprecated,建议改用 HTTP)、本地 stdio、远程 WebSocket。stdio 那项文档写明是跑在你机器上的本地进程,适合需要直接访问系统的工具。第一个会咬到你的差异就在这里:你手上那台只有 stdio 的本地 server,在 Claude Code 这条路上是一等公民,在 OpenRouter Agent SDK 那条路上文档明说不在范围内。

配置作用域。 Claude Code 文档给了一张三行的表:local(默认,只在当前项目、只对你)、project(写进项目根的 .mcp.json,随版本控制共享)、user(跨你所有项目)。@openrouter/mcp 是代码里的调用,没有这个概念,它的作用域就是你那段代码。这一点谈不上优劣,但值得记住:把 MCP 接进程序和把 MCP 接进一个会话,配置的生命周期完全不同。

Claude Code 自己也能当服务端。 文档写明 claude mcp serve 可以把它作为 stdio MCP server 起起来,并附了一句 Tip 值得抄给做集成的人看:这个 server 只把 Claude Code 的工具暴露给你的 MCP 客户端,逐个工具调用的用户确认由你自己的客户端负责实现。职责切分写得比什么都直白。

三处真会咬人的差异

一、谁来回答 elicitation。 有些 MCP server 会在一次工具调用中途停下来,用 elicitation/create 向调用方要结构化输入。两边文档都写了这件事,默认行为却正相反:@openrouter/mcp 让你传 onElicitation 处理器,文档写明省略它时请求会被自动拒绝,好让这次工具调用干净地失败而不是挂住;Claude Code 文档则写明这边不需要任何配置,服务端一请求就自动弹出交互对话框,并列了两种模式(form mode 与 URL mode),想免对话框自动应答要用 Elicitation hook。

这不是谁做得对,是两边假设的场景不同:一个跑在没人盯着的进程里,一个跑在有人坐在终端前的会话里。你把一台会 elicit 的 server 从会话搬进服务端 agent 时,这条差异会直接变成「调用为什么全失败了」。

二、resources 怎么送到模型面前。 @openrouter/mcp 把服务端声明的 resources 暴露成两个合成工具让模型直接调:list_resourcesread_resource,默认开启,设 resources: false 可以隐藏。Claude Code 文档走的是另一条:用 @ 提及,格式为 @server:protocol://resource/path,同时写明在服务端支持时会自动提供列举与读取 resources 的工具。前者面向模型自主取用,后者面向人手动点名。同一份 resources,接法不一样,写提示词的方式也就不一样。

三、凭据落在哪。 @openrouter/mcp 的缓存机制里,cacheCredentials 文档写明默认为 false,并带一条 Warning:开启后快照里会包含 bearer token 或 headers,要把这个存储当作密钥存储对待,多租户场景下缓存 key 要按主体分命名空间。Claude Code 侧,文档写明 OAuth 的 client secret 存在系统 keychain(macOS)或一个凭据文件里,而不是写进配置;如果你的鉴权方式不是 OAuth,可以用 headersHelper 在连接时现生成请求头,文档同时写明它执行的是任意 shell 命令。两边都把「密钥可能落到磁盘上」摊开讲了,只是方向不同:一边是你自己选要不要缓存,一边是产品替你决定存到哪。

这几个维度我们不比

  • 超时与取消@openrouter/mcp 文档给的是往 createMCPTools({ signal })AbortSignal;Claude Code 文档另给了一整套按服务端、按调用的超时配置项。两边不在同一层,硬比会得出错误结论,不比。
  • 上下文占用:Claude Code 文档有一整节讲工具搜索与延迟加载;这一点我们在 OpenRouter 的文档里没有找到对应说明,不比。@openrouter/mcpincludeTools / excludeTools 这对按名字的允许与拒绝列表,但那是过滤,和延迟加载不是一回事。
  • 性能、稳定性、调用成功率:两边都是闭源商业产品,我们没有实测依据,一个字不写。

倒过来的决策路径

  1. 你只是想让写代码时的助手能查 OpenRouter 的实时信息、顺手试打一条消息 → 走第一端,在客户端里加那条 URL 就够了。别指望它改变你线上请求的走向,文档自己写明了让你继续直接调 API。
  2. 你的服务端 agent 要用别人家的 MCP 工具 → 走第二端,@openrouter/mcp,前提是那台 server 能用 HTTP 访问到。
  3. 你要接的是一台只有 stdio 的本地 server → Agent SDK 这条路文档明说不在范围内;吃得下 stdio 的是 Claude Code 这类客户端。
  4. 你要让 MCP 工具在无人值守的情况下跑 → 先确认那台 server 会不会 elicit,两边默认行为相反,这一条比传输协议更容易翻车。
  5. 你要把多台 server 拼进同一个 agent → @openrouter/mcp 文档写明用 toolNamePrefix 给每台 server 的工具名加前缀避免歧义,这个动作在代码侧要你自己做。

Windows 侧的三点提醒

两边文档给配置路径时用的都是 ~/ 这种写法:OpenRouter 那页在列各家客户端的接法时写的是 ~/.cursor/mcp.json~/.config/opencode/opencode.json,Claude Code 文档那边写的是 ~/.claude.json。这些路径在 Windows 上对应到哪里,这几页文档都没有说明,按你所用客户端自己的说明找。

Claude Code 文档里有两处明确提到平台:一是从 Claude Desktop 导入已配置 MCP server 的功能,文档写明只在 macOS 与 WSL 上可用;二是上面提到的 client secret 存放,文档写明 macOS 用系统 keychain,其余情况是一个凭据文件。

第三点属于 shell 的通用差异、不是这两个产品文档里的内容:文档中 claude mcp add-json 的示例用单引号包住整段 JSON,那是 bash 的写法,Windows PowerShell 的引号与转义规则不同;官方文档在这里只写了一句「确保 JSON 在你的 shell 里正确转义」。照抄示例前先按自己的 shell 调整。

以上为按官方文档中的字段语义组合的示例,未经实测,以官方文档与 API 的实际响应为准。这两个产品迭代都很频繁,文中涉及的字段、命令与默认值随版本变动,请以官方文档最新内容为准。


本文依据 OpenRouter 官方文档(openrouter.ai/docs)于 2026-08-18 的公开内容整理。 该平台闭源,本文只复述官方文档写明的机制,不推断其内部实现我们没有对文中涉及的功能做过实测,因此不涉及界面外观与运行表现的任何描述。 该平台的供应商、模型与路由策略随时变动,文中不列具体供应商名单与模型清单; 价格、额度与限流的具体数值请以官方定价页与用量说明为准。

本文涉及的另一方内容依据其官方文档整理(Claude Code:code.claude.com/docs)。 双方均为闭源商业产品,本文只对照各方公开写明的机制,不推断实现,也不对产品做优劣排名

安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。