Skip to main content
Glama

openclaw-mcp-bridge

OpenClaw as MCP — expose OpenClaw agents to any MCP-compatible agent. Example: Qwen glasses → Qoder → OpenClaw.

把本机 OpenClaw 的 agent 暴露成标准 MCP 工具,任何支持 MCP 的客户端都能调用;典型链路是千问眼镜 → Qoder CN → OpenClaw。

功能

  • 🎤 语音控制: 通过千问眼镜语音下发任务到 OpenClaw agent

  • 🔀 多 Agent 支持: agent 白名单、别名、权限等级全部在 config.json 里配置

  • 🎯 智能路由: 点名即执行;未点名时使用 defaultAgent(建议指向权限最小的 agent)

  • 📊 状态查询: 实时查询任务状态、读取历史、取消任务

  • 🔊 语音优化: 自动提取首句播报,长回复标记需要总结

  • 🔒 安全隔离: 会话锁、限流、审计、无 token 泄漏

Related MCP server: OpenClaw MCP Proxy

从零到能用

整条链路是这样的:

千问眼镜(语音)
  → Qoder CN 远程控制会话(跑在这台 Mac 上)
  → openclaw-mcp-bridge(stdio MCP)
  → openclaw CLI → OpenClaw Gateway → agent

1. 在 Mac 上装 Qoder CN

装 Qoder CN 桌面版,不是 Qoder 国际版——两者是独立产品,配置目录也不同(CN 是 ~/.qoder-cn/,国际版是 ~/.qoder/),本项目只在 CN 桌面端验证过。

登录后确认远程控制 / 远程会话可用:眼镜侧正是以这种会话的形式,把任务发到你这台 Mac 上执行。

会话必须在本机执行。如果 Qoder 把任务委派到云端,云端进程访问不到你本机的 stdio MCP,这条链路就断了。

2. 千问眼镜绑定 Qoder CN

在千问 App 或眼镜端按官方引导绑定 Qoder CN 账号(通常是扫码登录授权)。绑定后,你对眼镜说的话会变成一个 Qoder CN 远程控制会话。具体入口和按钮名称可能随版本变化,以千问和 Qoder 当前的引导为准。

绑好后先验证一次:对眼镜说一句话,确认 Qoder CN 里出现了对应会话,并且它是在这台 Mac 上执行的。

3. 在这台 Mac 上安装本项目

前置条件:

  • Node.js ≥ 20(本项目在 v23 上测试)

  • 本机已安装并登录 OpenClaw,且 Gateway 正在运行(openclaw gateway status)

  • 桥接本身不需要任何 token:它复用 openclaw CLI 的本机认证

git clone https://github.com/rainow/openclaw-mcp-bridge.git
cd openclaw-mcp-bridge
npm install
cp config.example.json config.json   # 然后按你的 agent 名单改 config.json

config.json 至少改这三处:allowedAgents 填 openclaw agents list 里真实存在的 agent ID;aliases 填语音里好念的名字;defaultAgent 建议指向权限最小的那个。

装完先手动跑一次,确认配置和 Gateway 都通:

npm start

看到 [openclaw-mcp-bridge] Server started (OpenClaw …) 就说明没问题,Ctrl+C 退出即可——正常使用时这个进程由 Qoder 拉起,不需要你手动常驻。

config.json 写的是你本人的 agent 名单、别名和权限,不要提交到版本库。缺少它时服务器会回退到 config.example.json 并在 stderr 提示。

4. 在 Qoder CN 里配置 MCP

设置 → 扩展(Extensions)→ 连接器(Connectors)→ 添加自定义 MCP,传输方式选 stdio:

  • 名称: openclaw-mcp-bridge

  • 命令: node 的绝对路径(如 /opt/homebrew/bin/node),不要只写 node

  • 参数: /绝对路径/openclaw-mcp-bridge/server.mjs

  • 工作目录: /绝对路径/openclaw-mcp-bridge

参数和工作目录都必须是绝对路径。保存后如果工具里没出现这 5 个工具,对该服务器执行一次 retry,或重开会话。改过 server.mjs / lib/openclaw.mjs 之后同理,运行中的进程不会热更新。

桥接进程由 Qoder 按需拉起,不需要、也不应该做成系统级自启动任务(stdio 服务器脱离父进程就没有意义)。需要常驻的是 OpenClaw Gateway,是否让它开机自启由你决定。

5. 验证

在 Qoder CN 的新会话里说"列出可用的 OpenClaw agent",或直接在眼镜上说"让助手看一下今天的安排"(把"助手"换成你 aliases 里的名字)。第一次调用会先读 MCP 工具目录,这是客户端的懒加载行为,正常现象。

为什么不用在每个会话里教它

这个桥接不需要你在每个会话里重复解释自己会什么,用法写在两个地方:

  • 服务器级 instructions:initialize 时就返回,告诉任意 MCP 客户端"先 oc_agents 拿本机 agent 名单,再 oc_run 派活,running 就 oc_wait,别重复下发"。

  • 每个工具的 description:把同一段协议拆开写进各自工具里,所以客户端只要列出工具就能读全用法。这两处是用法的主来源,改动时要一起更新,别只改其中一边。

实测差异(Qoder CN 桌面端 0.x,2026-10-22):服务器 instructions 会正常出现在 initialize 响应里,但 Qoder 不会把它注入会话上下文;它注入的是"服务器名 + 工具名"的延迟目录。真正起作用的是工具 description —— 一个全新会话在完全没被提示的情况下,自己走 mcp_list / mcp_get 读到用法,再调 oc_agents 定位到本机的 agent,然后完成任务。所以配完就能用,但你依然可以直接说"让某某去做某事"。

MCP 工具

oc_agents

列出所有可用的 OpenClaw agent。

参数:

  • refresh (boolean, 可选): 强制刷新缓存

返回:

{
  "openclawVersion": "2026.6.11",
  "gatewayOk": true,
  "agents": [...],
  "defaultAgent": "main",
  "cached": false
}

oc_run

向指定 agent 下发任务。

参数:

  • message (string, 必填): 任务消息

  • agent (string, 可选): Agent 名字或 ID,默认取 config.json 的 defaultAgent

  • wait_seconds (number, 可选): 同步等待秒数,默认 20,最大 120

  • idempotency_key (string, 可选): 幂等键,5 秒内相同 key 不重复下发

返回:

{
  "status": "done",
  "runId": "req-xxx",
  "agentId": "main",
  "sessionKey": "agent:main:glasses",
  "reply": "任务回复内容",
  "voice": {
    "speak": "播报文本(≤150 字符)",
    "kind": "text",
    "needsSummary": false,
    "textLength": 100
  },
  "replyTruncated": false
}

oc_wait

查询或等待任务状态。

参数:

  • runId (string, 必填): 任务 runId

  • timeout_seconds (number, 可选): 等待秒数,0 表示立即返回

返回:

{
  "status": "done",
  "runId": "req-xxx",
  "stopReason": "stop",
  "startedAt": 1700000000000,
  "endedAt": 1700000005000,
  "voice": {...}
}

oc_last

读取指定 agent 的 glasses 会话历史。

参数:

  • agent (string, 可选): Agent 名字或 ID,默认取 config.json 的 defaultAgent

  • limit (number, 可选): 返回消息条数,默认 10

返回:

{
  "agentId": "main",
  "sessionKey": "agent:main:glasses",
  "messages": [...],
  "reply": "最后一条 assistant 回复",
  "voice": {...},
  "replyTruncated": false
}

oc_cancel

取消指定任务。

参数:

  • runId (string, 必填): 任务 runId

返回:

{
  "ok": true,
  "status": "aborted",
  "abortedRunId": "req-xxx"
}

配置

config.example.json 是最小可用配置,复制成 config.json 后按需修改:

{
  "defaultAgent": "main",
  "allowedAgents": ["main", "coder"],
  "disabledAgents": [],
  "aliases": { "助手": "main", "coder": "coder" },
  "execRisk": { "main": "allow", "coder": "allow" },
  "session": { "suffix": "glasses", "maxKeyLength": 200 },
  "rateLimit": { "perMinute": 6, "perHour": 60 },
  "voice": { "maxSpeakChars": 150, "summaryThreshold": 400 },
  "run": { "defaultWaitSeconds": 20, "maxWaitSeconds": 120, "cliTimeoutMs": 30000, "rpcTimeoutMs": 15000 },
  "dedupe": { "windowSeconds": 5 },
  "audit": { "dir": "~/Library/Application Support/openclaw-mcp-bridge" }
}

几个字段的含义:

  • allowedAgents / disabledAgents: 允许、禁止通过桥接下发的 agent ID(ID 来自 openclaw agents list)。

  • aliases: 语音里更好念的名字 → agent ID。前缀匹配也能命中。

  • execRisk: 仅作提示位,记录该 agent 是否有 exec 权限;桥接不会修改 OpenClaw 的权限策略。

  • run.rpcTimeoutMs / maxWaitSeconds: 每次 gateway call 显式带 --timeout,等待时长由请求换算(见 DESIGN §超时)。

  • session.suffix: 会话键后缀,把眼镜侧的会话和其他来源隔离开。

环境变量

  • OPENCLAW_BIN: OpenClaw 可执行文件路径(默认 /opt/homebrew/bin/openclaw)

  • OPENCLAW_NODE_BIN: Node.js 可执行文件路径(默认 process.execPath)

  • OPENCLAW_BRIDGE_HOME: 审计日志目录(默认 ~/Library/Application Support/openclaw-mcp-bridge)

安全

  • ✅ 不暴露 Gateway token、exec-approvals token

  • ✅ 不修改 OpenClaw agent 权限

  • ✅ 审计日志本地存储,权限 0700/0600

  • ✅ 无公网入口

已知限制

  • 会话锁是内存状态:Gateway 重启或桥接进程重启后会丢失,需要重新下发。

  • 回复可能被 Gateway 截断(replyTruncated)或读取失败(replyUnavailable),此时用 oc_last 再取一次。

  • 语音分类走启发式,极简的无文件头 diff 可能被判成普通文本;voice.kind 只作播报提示。

  • 真实提交响应丢失时,桥接会用已知的 runId 对账并按 running 处理——健康的 Gateway 无法区分"从未受理"和"仍在排队",此时用 oc_cancel 是可靠的恢复手段。

许可证

MIT

Related MCP Connectors

Related MCP Servers