将 OpenClaw 作为 MCP 服务器运行
本页介绍 openclaw mcp serve 路径:OpenClaw 通过 stdio 作为 MCP 服务器运行,并介绍其工具、事件模型及限制。
OpenClaw 作为 MCP 服务器¶
这是 openclaw mcp serve 路径。
何时使用 serve¶
在以下情况下使用 openclaw mcp serve:
- Codex、Claude Code 或其他 MCP 客户端需要直接与 OpenClaw 支持的渠道会话进行交互
- 你已经拥有带路由会话的本地或远程 OpenClaw Gateway
- 你希望一个 MCP 服务器即可跨 OpenClaw 的渠道后端工作,而不是为每个渠道分别运行桥接器
当 OpenClaw 需要自行托管编码运行时并将 agent 会话保留在 OpenClaw 内部时,请改用 openclaw acp。
工作原理¶
openclaw mcp serve 启动一个 stdio MCP 服务器。该进程由 MCP 客户端持有。当客户端保持 stdio 会话打开时,桥接器通过 WebSocket 连接到本地或远程 OpenClaw Gateway,并通过 MCP 暴露路由渠道会话。
1. 客户端启动桥接器
MCP 客户端启动 openclaw mcp serve。
2. 桥接器连接 Gateway
桥接器通过 WebSocket 连接到 OpenClaw Gateway。
3. 会话成为 MCP 对话
路由会话成为 MCP 对话,并转化为 transcript/历史工具。
4. 实时事件排队
桥接器连接期间,实时事件在内存中排队。
5. 可选的 Claude 推送
如果启用了 Claude 渠道模式,同一会话还可以接收 Claude 专属推送通知。
重要行为
- 实时队列状态在桥接器连接时开始
- 较早的 transcript 历史通过
messages_read读取 - Claude 推送通知仅在 MCP 会话存活期间存在
- 客户端断开连接时,桥接器退出,实时队列随之消失
- 取消
events_wait请求会立即释放其服务端等待与超时 - 桥接器或 MCP 传输关闭失败会使
openclaw mcp serve失败,而非报告正常关闭 - 一次性 agent 入口点(如
openclaw agent和openclaw infer model run)在回复完成时会回收它们打开的所有捆绑 MCP 运行时,因此重复的脚本化运行不会累积 stdio MCP 子进程 - 由 OpenClaw 启动的 stdio MCP 服务器(捆绑或用户配置)在关闭时作为进程树被拆除,因此服务器启动的子进程不会在父 stdio 客户端退出后继续存活
- 删除或重置会话会通过共享的运行时清理路径释放该会话的 MCP 客户端,因此不会存在与被移除会话关联的残留 stdio 连接
选择客户端模式¶
仅使用标准 MCP 工具。使用 conversations_list、messages_read、events_poll、events_wait、messages_send 以及审批工具。
标准 MCP 工具外加 Claude 专属渠道适配器。启用 --claude-channel-mode on 或保持默认的 auto。
Note
auto 的行为与 on 相同。不存在客户端能力检测。
serve 暴露的内容¶
桥接器使用 Gateway 现有的会话路由元数据来暴露基于渠道的对话。当 OpenClaw 已经拥有带已知路由的会话状态时,对话即会出现,例如:
channel- 接收方或目的地元数据
- 可选的
accountId - 可选的
threadId
这为 MCP 客户端提供了一个统一入口,用于:
- 列出最近的已路由对话
- 读取最近的 transcript 历史
- 等待新的入站事件
- 通过相同路由发送回复
- 查看桥接器连接期间到达的审批请求
用法¶
桥接器工具¶
conversations_list
列出 Gateway 会话状态中已具有路由元数据的、基于会话的近期对话。
筛选条件:limit(最大 500)、search、channel、includeDerivedTitles、includeLastMessage。
conversation_get
使用直接的 Gateway 会话查找,通过 session_key 返回一个对话。
messages_read
读取一个基于会话的对话的近期 transcript 消息。limit 默认为 20,最大 200。
attachments_fetch
从一条 transcript 消息中提取非文本消息内容块和规范的持久化媒体元数据。通过 Gateway 直接查找 message_id,因此该消息无需出现在近期历史窗口中。持久化条目使用 { "type": "openclaw_media", "media": { ... } },其中 media 可包含 url、contentType、kind、fileName、尺寸、时长或大小。这是一个元数据视图,而非独立的持久化附件 blob 存储。
events_poll
从数值游标开始读取已排队的实时事件。limit 最大 200。如果请求的游标早于保留的队列历史,结果还会包含 gap.requested_after_cursor 和 gap.oldest_available_cursor。
events_wait
长轮询直到下一个匹配的排队事件到达或超时到期(默认 30 秒,最大 300 秒)。
当通用 MCP 客户端需要近实时投递而无需 Claude 专属推送协议时,请使用此工具。
已知的游标间隙会立即返回,并附带相同的附加 gap 元数据,即使当前没有保留匹配的事件。
messages_send
通过会话上已记录的相同路由发送文本回复。
当前行为:
- 需要已有会话路由
- 使用会话的渠道、接收方、账户 ID 和线程 ID
- 仅发送文本
permissions_list_open
列出桥接器自连接到 Gateway 以来观察到的待处理 exec/plugin 审批请求。
permissions_respond
处理一个待处理的 exec/plugin 审批请求,使用:
allow-onceallow-alwaysdeny
事件模型¶
桥接器在连接期间维护一个内存事件队列。
当前事件类型:
messageexec_approval_requestedexec_approval_resolvedplugin_approval_requestedplugin_approval_resolvedclaude_permission_request
Warning
- 队列仅实时;它在 MCP 桥接器启动时开始
events_poll和events_wait不会自行重放较旧的 Gateway 历史- 队列是有界的;当存在
gap时,使用messages_read读取持久化历史,然后将after_cursor设置为比gap.oldest_available_cursor小 1 以继续 - 持久化积压消息应使用
messages_read读取
Claude 频道通知¶
桥接器还可以暴露 Claude 专用的频道通知。这是 OpenClaw 对 Claude Code 频道适配器的等价实现:标准 MCP 工具仍然可用,但实时入站消息也可以作为 Claude 专用的 MCP 通知到达。
--claude-channel-mode off:仅标准 MCP 工具。
--claude-channel-mode on:启用 Claude 频道通知。
--claude-channel-mode auto:当前默认值;与 on 的桥接器行为相同。
当 Claude 频道模式启用时,服务器会通告 Claude 实验性能力,并可以发出:
notifications/claude/channelnotifications/claude/channel/permission
当前桥接器行为:
- 入站
user转录消息将作为notifications/claude/channel转发 - 通过 MCP 收到的 Claude 权限请求会在内存中跟踪
- 如果链接会话中的命令所有者随后发送
yes <id>或no <id>(<id>是 5 个字母的请求 ID,不含l),桥接器会将其转换为notifications/claude/channel/permission - 这些通知仅限实时会话;如果 MCP 客户端断开连接,则没有推送目标
这是有意设计为客户端专用的。通用 MCP 客户端应依赖标准轮询工具。
MCP 客户端配置¶
stdio 客户端配置示例:
{
"mcpServers": {
"openclaw": {
"command": "openclaw",
"args": [
"mcp",
"serve",
"--url",
"wss://gateway-host:18789",
"--token-file",
"/path/to/gateway.token"
]
}
}
}
对于大多数通用 MCP 客户端,请从标准工具界面开始,并忽略 Claude 模式。仅对真正理解 Claude 专用通知方法的客户端启用 Claude 模式。
选项¶
openclaw mcp serve 支持:
--urlstring (path)- Gateway WebSocket URL。配置后默认为
gateway.remote.url。 --tokenstring (path)- Gateway 令牌。
--token-filestring (path)- 从文件读取令牌。
--passwordstring (path)- Gateway 密码。
--password-filestring (path)- 从文件读取密码。
--claude-channel-mode"auto" | "on" | "off" (path)- Claude 通知模式。默认为
auto。 -v, --verboseboolean (path)- 在 stderr 上输出详细日志。
Tip
尽可能优先使用 --token-file 或 --password-file,而不是内联密钥。
安全与信任边界¶
桥接器不会凭空创建路由。它只暴露 Gateway 已经知道如何路由的会话。
这意味着:
- 发送者允许列表、配对和频道级信任仍然属于底层 OpenClaw 频道配置
messages_send只能通过现有存储的路由进行回复- 审批状态仅存在于当前桥接器会话的实时内存中
- 桥接器身份验证应使用与任何其他远程 Gateway 客户端相同的 Gateway 令牌或密码控制
如果某个会话在 conversations_list 中缺失,通常原因不是 MCP 配置。而是底层 Gateway 会话中缺少或不完整的路由元数据。
测试¶
OpenClaw 为此桥接器提供了一个确定性的 Docker 冒烟测试:
该冒烟测试运行单个容器:它预置会话状态,启动 Gateway,然后将 openclaw mcp serve 作为 stdio 子进程启动,并作为 MCP 客户端驱动它。它验证会话发现、转录读取、附件元数据读取、实时事件队列行为,以及通过真实 stdio MCP 桥接器的 Claude 风格频道和权限通知。出站发送路由(messages_send 重用存储的会话路由)由 src/mcp/channel-server.test.ts 中的单元测试另行覆盖。
这是在测试运行中无需接入真实的 Telegram、Discord 或 iMessage 账户即可证明桥接器工作的最快方式。
有关更广泛的测试上下文,请参阅 测试。
故障排除¶
没有返回会话
通常意味着 Gateway 会话尚不可路由。请确认底层会话已存储频道/提供者、接收者以及可选的账户/线程路由元数据。
events_poll 或 events_wait 遗漏较旧消息
实时队列在桥接器连接时启动,并保留一个有界窗口。如果结果包含 gap,请使用 messages_read 读取持久化转录历史,然后将 after_cursor 设置为比 gap.oldest_available_cursor 小 1 以继续。
Claude 通知不显示
请检查以下所有项:
- 客户端保持 stdio MCP 会话打开
--claude-channel-mode为on或auto- 客户端确实理解 Claude 专用的通知方法
- 入站消息发生在桥接器连接之后
审批缺失
permissions_list_open 只显示桥接器连接期间观察到的审批请求。它不是持久的审批历史 API。
当前限制¶
该桥接存在以下限制:
- 会话发现依赖于现有的 Gateway 会话路由元数据
- 除 Claude 专用适配器外,没有通用推送协议
- 没有消息编辑或表情回应工具
- HTTP/SSE/streamable-http 传输连接到单个远程服务器;上游连接不会多路复用
permissions_list_open仅包含桥接连接期间观察到的审批
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw