Skip to content

Gateway 协议(WebSocket)

Gateway WS 协议是 OpenClaw 的唯一控制面 + 节点传输通道。所有客户端(CLI、Web UI、macOS 应用、iOS/Android 节点、无头节点)均通过 WebSocket 连接,并在握手时声明自己的角色(role)作用域(scope)

传输层

  • WebSocket,文本帧,JSON 载荷。
  • 第一帧必须connect 请求。

握手(connect)

Gateway → 客户端(预连接挑战):

json
{
  "type": "event",
  "event": "connect.challenge",
  "payload": { "nonce": "…", "ts": 1737264000000 }
}

客户端 → Gateway:

json
{
  "type": "req",
  "id": "…",
  "method": "connect",
  "params": {
    "minProtocol": 3,
    "maxProtocol": 3,
    "client": {
      "id": "cli",
      "version": "1.2.3",
      "platform": "macos",
      "mode": "operator"
    },
    "role": "operator",
    "scopes": ["operator.read", "operator.write"],
    "caps": [],
    "commands": [],
    "permissions": {},
    "auth": { "token": "…" },
    "locale": "en-US",
    "userAgent": "openclaw-cli/1.2.3",
    "device": {
      "id": "device_fingerprint",
      "publicKey": "…",
      "signature": "…",
      "signedAt": 1737264000000,
      "nonce": "…"
    }
  }
}

Gateway → 客户端:

json
{
  "type": "res",
  "id": "…",
  "ok": true,
  "payload": { "type": "hello-ok", "protocol": 3, "policy": { "tickIntervalMs": 15000 } }
}

颁发设备 token 时,hello-ok 还会包含:

json
{
  "auth": {
    "deviceToken": "…",
    "role": "operator",
    "scopes": ["operator.read", "operator.write"]
  }
}

节点连接示例

json
{
  "type": "req",
  "id": "…",
  "method": "connect",
  "params": {
    "minProtocol": 3,
    "maxProtocol": 3,
    "client": {
      "id": "ios-node",
      "version": "1.2.3",
      "platform": "ios",
      "mode": "node"
    },
    "role": "node",
    "scopes": [],
    "caps": ["camera", "canvas", "screen", "location", "voice"],
    "commands": ["camera.snap", "canvas.navigate", "screen.record", "location.get"],
    "permissions": { "camera.capture": true, "screen.record": false },
    "auth": { "token": "…" },
    "locale": "en-US",
    "userAgent": "openclaw-ios/1.2.3",
    "device": {
      "id": "device_fingerprint",
      "publicKey": "…",
      "signature": "…",
      "signedAt": 1737264000000,
      "nonce": "…"
    }
  }
}

帧格式

  • 请求(Request){type:"req", id, method, params}
  • 响应(Response){type:"res", id, ok, payload|error}
  • 事件(Event){type:"event", event, payload, seq?, stateVersion?}

有副作用的方法需要携带幂等性 key(参见 schema)。

角色与作用域

角色

  • operator = 控制面客户端(CLI/UI/自动化)。
  • node = 能力宿主(摄像头/屏幕/画布/system.run)。

作用域(operator)

常用作用域:

  • operator.read
  • operator.write
  • operator.admin
  • operator.approvals
  • operator.pairing

方法作用域只是第一道门禁。通过 chat.send 触发的部分 slash 命令还会在此之上执行更严格的命令级别检查。例如,持久写入操作 /config set/config unset 需要 operator.admin 作用域。

能力/命令/权限(node)

节点在连接时声明能力:

  • caps:高层能力类别。
  • commands:调用允许的命令白名单。
  • permissions:细粒度开关(如 screen.recordcamera.capture)。

Gateway 将这些视为声明并在服务端执行白名单校验。

在线状态

  • system-presence 返回以设备身份为 key 的条目。
  • 在线条目包含 deviceIdrolesscopes,UI 可据此为同时以 operatornode 两种角色连接的设备显示单行记录。

节点辅助方法

  • 节点可调用 skills.bins 获取当前技能可执行文件列表,用于自动允许检查。

Operator 辅助方法

  • Operator 可调用 tools.catalog(需 operator.read)获取 Agent 的运行时工具目录。响应包含分组工具及来源元数据:
    • sourcecoreplugin
    • pluginIdsource="plugin" 时的插件所有者
    • optional:插件工具是否为可选
  • Operator 可调用 tools.effective(需 operator.read)获取会话的运行时有效工具清单。
    • 必须提供 sessionKey
    • Gateway 从服务端的会话中推导受信运行时上下文,而不接受调用方提供的 auth 或投递上下文。
    • 响应以会话为范围,反映当前对话可使用的所有工具(包括 core、plugin 和 channel 工具)。

Exec 审批

  • 当 exec 请求需要审批时,Gateway 会广播 exec.approval.requested
  • Operator 客户端通过调用 exec.approval.resolve(需 operator.approvals 作用域)来解决审批。
  • 对于 host=node 的情况,exec.approval.request 必须包含 systemRunPlan(包含规范 argv/cwd/rawCommand/会话元数据)。缺少 systemRunPlan 的请求会被拒绝。

版本管理

  • PROTOCOL_VERSION 定义在 src/gateway/protocol/schema.ts
  • 客户端发送 minProtocol + maxProtocol;服务端拒绝不匹配的版本。
  • Schema 和模型由 TypeBox 定义生成:
    • pnpm protocol:gen
    • pnpm protocol:gen:swift
    • pnpm protocol:check

认证

  • 若设置了 OPENCLAW_GATEWAY_TOKEN(或 --token),connect.params.auth.token 必须匹配,否则连接关闭。
  • 配对后,Gateway 颁发设备 token,其作用域绑定到连接角色和作用域。token 在 hello-ok.auth.deviceToken 中返回,客户端应持久化以供后续连接使用。
  • 设备 token 可通过 device.token.rotatedevice.token.revoke 轮换/吊销(需 operator.pairing 作用域)。
  • 认证失败时,error.details.code 包含错误码及恢复提示:
    • error.details.canRetryWithDeviceToken(boolean)
    • error.details.recommendedNextStepretry_with_device_tokenupdate_auth_configurationupdate_auth_credentialswait_then_retryreview_auth_configuration
  • 客户端处理 AUTH_TOKEN_MISMATCH 的行为:
    • 受信客户端可尝试使用缓存的设备 token 进行一次有限重试。
    • 若重试失败,客户端应停止自动重连循环,并提示 operator 采取行动。

设备身份与配对

  • 节点应携带从密钥对指纹派生的稳定设备身份(device.id)。
  • Gateway 按设备 + 角色颁发 token。
  • 新设备 ID 需要经过配对审批,除非本地自动审批已启用。
  • 本地连接包括 loopback 和 gateway 宿主机自身的 tailnet 地址(因此同主机的 tailnet 绑定仍可自动审批)。
  • 所有 WS 客户端在 connect 时必须包含 device 身份(operator 和 node 均如此)。控制 UI 仅在以下模式下可省略:
    • gateway.controlUi.allowInsecureAuth=true(仅限 localhost 的不安全 HTTP 兼容模式)。
    • gateway.controlUi.dangerouslyDisableDeviceAuth=true(紧急方案,严重安全降级)。
  • 所有连接必须对服务端提供的 connect.challenge nonce 进行签名。

设备认证迁移诊断

对于仍使用挑战签名之前旧版行为的遗留客户端,connect 现在会在 error.details.code 中返回 DEVICE_AUTH_* 详细码,并在 error.details.reason 中提供稳定原因。

常见迁移失败情况:

错误消息details.codedetails.reason含义
device nonce requiredDEVICE_AUTH_NONCE_REQUIREDdevice-nonce-missing客户端未提供 device.nonce(或为空)
device nonce mismatchDEVICE_AUTH_NONCE_MISMATCHdevice-nonce-mismatch客户端使用了过期/错误的 nonce 进行签名
device signature invalidDEVICE_AUTH_SIGNATURE_INVALIDdevice-signature签名载荷与 v2 载荷格式不匹配
device signature expiredDEVICE_AUTH_SIGNATURE_EXPIREDdevice-signature-stale签名时间戳超出允许的时钟偏差范围
device identity mismatchDEVICE_AUTH_DEVICE_ID_MISMATCHdevice-id-mismatchdevice.id 与公钥指纹不匹配
device public key invalidDEVICE_AUTH_PUBLIC_KEY_INVALIDdevice-public-key公钥格式或规范化失败

迁移目标:

  • 始终等待 connect.challenge
  • 使用包含服务端 nonce 的 v2 载荷进行签名。
  • connect.params.device.nonce 中发送相同的 nonce。
  • 推荐使用 v3 签名载荷,它在 device/client/role/scopes/token/nonce 字段之外还绑定了 platformdeviceFamily
  • 向后兼容:v2 签名仍被接受,但配对后设备元数据固定仍会在重连时控制命令策略。

TLS 与证书固定

  • WS 连接支持 TLS。
  • 客户端可选择性地固定 gateway 证书指纹(参见 gateway.tls 配置,以及 gateway.remote.tlsFingerprint 或 CLI --tls-fingerprint)。

接口范围

本协议暴露了完整的 Gateway API(状态、频道、模型、对话、Agent、会话、节点、审批等)。确切接口范围由 src/gateway/protocol/schema.ts 中的 TypeBox schema 定义。

常用 RPC 方法系列

本页不是自动生成的完整转储,但公开的 WS 接口比上方握手/认证示例范围更广。以下是 Gateway 当前暴露的主要方法系列。

hello-ok.features.methods 是从 src/gateway/server-methods-list.ts 加上已加载的插件/渠道方法导出构建的保守发现列表,用于功能发现,而非 src/gateway/server-methods/*.ts 中每个可调用助手的完整转储。

系统与身份

  • health:返回缓存或新探测的 Gateway 健康快照
  • status:返回 /status 风格的 Gateway 摘要;敏感字段仅向 admin 作用域的运营者客户端开放
  • gateway.identity.get:返回 relay 和配对流程使用的 Gateway 设备身份
  • system-presence:返回已连接运营者/节点设备的当前 Presence 快照
  • system-event:追加系统事件,可更新/广播 Presence 上下文
  • last-heartbeat:返回最新持久化的心跳事件
  • set-heartbeats:切换 Gateway 上的心跳处理

模型与用量

  • models.list:返回运行时允许的模型目录
  • usage.status:返回提供商用量窗口/剩余配额摘要
  • usage.cost:返回日期范围内的聚合成本摘要
  • doctor.memory.status:返回默认 Agent 工作区的向量记忆/embedding 就绪状态
  • sessions.usage:返回每会话用量摘要
  • sessions.usage.timeseries:返回某会话的时序用量
  • sessions.usage.logs:返回某会话的用量日志条目

渠道与登录助手

  • channels.status:返回内置 + 捆绑渠道/插件的状态摘要
  • channels.logout:注销支持注销的特定渠道/账号
  • web.login.start:启动当前支持 QR/网页登录的渠道提供商的登录流程
  • web.login.wait:等待 QR/网页登录流程完成,成功后启动渠道
  • push.test:向已注册的 iOS 节点发送测试 APNs 推送
  • voicewake.get:返回存储的唤醒词触发器
  • voicewake.set:更新唤醒词触发器并广播变更

消息与日志

  • send:在聊天执行器外,直接向渠道/账号/线程发送消息的出站投递 RPC
  • logs.tail:返回带游标/限制和最大字节控制的 Gateway 文件日志尾

Talk 与 TTS

  • talk.config:返回有效的 Talk 配置载荷;includeSecrets 需要 operator.talk.secrets(或 operator.admin
  • talk.mode:设置/广播当前 Talk 模式状态(用于 WebChat/控制 UI 客户端)
  • talk.speak:通过当前激活的 Talk 语音提供商合成语音
  • tts.status:返回 TTS 启用状态、当前提供商、回退提供商和提供商配置状态
  • tts.providers:返回可见的 TTS 提供商清单
  • tts.enable / tts.disable:切换 TTS 偏好状态
  • tts.setProvider:更新首选 TTS 提供商
  • tts.convert:运行一次性文本转语音转换

Secrets、配置、更新与向导

  • secrets.reload:重新解析活跃 SecretRef,仅在完全成功时替换运行时密钥状态
  • secrets.resolve:解析特定命令/目标集的命令目标密钥分配
  • config.get:返回当前配置快照和哈希
  • config.set:写入已验证的配置载荷
  • config.patch:合并部分配置更新
  • config.apply:验证并替换完整配置载荷
  • config.schema:返回控制 UI 和 CLI 工具使用的实时配置 Schema 载荷(含字段 title/description 元数据)
  • config.schema.lookup:返回某配置路径的路径作用域查找载荷:归一化路径、浅层 schema 节点、匹配的 hint/hintPath,以及用于 UI/CLI 下钻的直接子摘要
  • update.run:运行 Gateway 更新流程,仅在更新本身成功时才安排重启
  • wizard.startwizard.nextwizard.statuswizard.cancel:通过 WS RPC 暴露引导向导

Agent 与工作区助手

  • agents.list:返回已配置的 Agent 条目
  • agents.createagents.updateagents.delete:管理 Agent 记录和工作区接线
  • agents.files.listagents.files.getagents.files.set:管理某 Agent 暴露的 Bootstrap 工作区文件
  • agent.identity.get:返回某 Agent 或会话的有效助手身份
  • agent.wait:等待运行完成并在可用时返回终态快照

会话控制

  • sessions.list:返回当前会话索引
  • sessions.subscribe / sessions.unsubscribe:切换当前 WS 客户端的会话变更事件订阅
  • sessions.messages.subscribe / sessions.messages.unsubscribe:切换某会话的转录/消息事件订阅
  • sessions.preview:返回特定会话 key 的有界转录预览
  • sessions.resolve:解析或规范化会话目标
  • sessions.create:创建新会话条目
  • sessions.send:向已有会话发送消息
  • sessions.steer:活跃会话的中断并重定向变体
  • sessions.abort:中止会话的活跃工作
  • sessions.patch:更新会话元数据/覆盖
  • sessions.resetsessions.deletesessions.compact:执行会话维护
  • sessions.get:返回完整的存储会话行
  • 聊天执行仍使用 chat.historychat.sendchat.abortchat.inject

设备配对与设备 Token

  • device.pair.list:返回待审批和已审批的配对设备
  • device.pair.approvedevice.pair.rejectdevice.pair.remove:管理设备配对记录
  • device.token.rotate:在已审批的角色和作用域边界内轮换配对设备 token
  • device.token.revoke:撤销配对设备 token

节点配对、调用与待处理工作

  • node.pair.requestnode.pair.listnode.pair.approvenode.pair.rejectnode.pair.verify:节点配对与 Bootstrap 验证
  • node.list / node.describe:返回已知/已连接的节点状态
  • node.rename:更新配对节点标签
  • node.invoke:将命令转发给已连接的节点
  • node.invoke.result:返回调用请求的结果
  • node.event:将节点发起的事件回传到 Gateway
  • node.canvas.capability.refresh:刷新作用域 Canvas 能力 token
  • node.pending.pull / node.pending.ack:已连接节点的队列 API
  • node.pending.enqueue / node.pending.drain:管理离线/已断开节点的持久待处理工作

审批系列

  • exec.approval.request / exec.approval.resolve:单次 exec 审批请求
  • exec.approval.waitDecision:等待一个待处理 exec 审批并返回最终决定(超时返回 null
  • exec.approvals.get / exec.approvals.set:管理 Gateway exec 审批策略快照
  • exec.approvals.node.get / exec.approvals.node.set:通过节点中继命令管理节点本地 exec 审批策略
  • plugin.approval.requestplugin.approval.waitDecisionplugin.approval.resolve:插件定义的审批流程

其他主要系列

  • 自动化:wake(调度即时或下次心跳的唤醒文本注入)、cron.listcron.statuscron.addcron.updatecron.removecron.runcron.runs
  • Skills/工具:skills.*tools.catalogtools.effective

常见事件系列

  • chat:UI 聊天更新(如 chat.inject 和其他仅转录的聊天事件)
  • session.message / session.tool:已订阅会话的转录/事件流更新
  • sessions.changed:会话索引或元数据变更
  • presence:系统 Presence 快照更新
  • tick:周期性 keepalive / 存活事件
  • health:Gateway 健康快照更新
  • heartbeat:心跳事件流更新
  • cron:Cron 运行/任务变更事件
  • shutdown:Gateway 关闭通知
  • node.pair.requested / node.pair.resolved:节点配对生命周期
  • node.invoke.request:节点调用请求广播
  • device.pair.requested / device.pair.resolved:配对设备生命周期
  • voicewake.changed:唤醒词触发配置变更
  • exec.approval.requested / exec.approval.resolved:exec 审批生命周期
  • plugin.approval.requested / plugin.approval.resolved:插件审批生命周期

节点辅助方法

  • 节点可调用 skills.bins 获取当前 Skill 可执行文件列表(用于自动允许检查)