Conecta OpenClaw mediante WebSocket: Guía de protocolo
¿Alguna vez has intentado sincronizar una CLI, una interfaz web y varios nodos remotos sin que la comunicación se vuelva un caos? Gestionar diferentes protocolos para cada cliente suele ser un dolor de cabeza que complica el mantenimiento y la escalabilidad de cualquier sistema distribuido.
El protocolo de Gateway por WebSocket (WS) de OpenClaw soluciona esto actuando como el único plano de control y transporte de nodos. Todos los clientes, ya sea la CLI, la UI web o los nodos de iOS y Android, se conectan mediante WebSocket y declaran su función y permisos al iniciar la conexión.
Transporte
Sección titulada «Transporte»- WebSocket, frames de texto con payloads JSON.
- El primer frame debe ser una solicitud
connect.
Handshake (conexión)
Sección titulada «Handshake (conexión)»Gateway → Client (desafío previo a la conexión):
{ "type": "event", "event": "connect.challenge", "payload": { "nonce": "…", "ts": 1737264000000 }}Client → Gateway:
{ "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 → Client:
{ "type": "res", "id": "…", "ok": true, "payload": { "type": "hello-ok", "protocol": 3, "policy": { "tickIntervalMs": 15000 } }}Cuando se emite un token de dispositivo, hello-ok también incluye:
{ "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] }}Ejemplo de nodo
Sección titulada «Ejemplo de nodo»{ "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": "…" } }}Estructura de mensajes (Framing)
Sección titulada «Estructura de mensajes (Framing)»- Request:
{type:"req", id, method, params} - Response:
{type:"res", id, ok, payload|error} - Event:
{type:"event", event, payload, seq?, stateVersion?}
Los métodos que generan efectos secundarios requieren idempotency keys (consulta el schema).
Roles y alcances (scopes)
Sección titulada «Roles y alcances (scopes)»operator: cliente del plano de control (CLI, UI o automatización).node: host de capacidades (camera, screen, canvas, system.run).
Scopes (operator)
Sección titulada «Scopes (operator)»Alcances comunes:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairing
El scope del método es solo el primer filtro. Algunos comandos de barra ejecutados mediante chat.send aplican verificaciones más estrictas. Por ejemplo, las escrituras persistentes de /config set y /config unset requieren operator.admin.
Presencia
Sección titulada «Presencia»system-presencedevuelve entradas indexadas por la identidad del dispositivo.- Las entradas incluyen
deviceId,rolesyscopes. Esto permite que las interfaces muestren una sola fila por dispositivo aunque esté conectado como operator y node a la vez.
Métodos de ayuda para nodos
Sección titulada «Métodos de ayuda para nodos»- Los nodos pueden llamar a
skills.binspara obtener la lista actual de ejecutables de habilidades y realizar verificaciones automáticas.
Métodos de ayuda para operadores
Sección titulada «Métodos de ayuda para operadores»- Los operadores pueden llamar a
tools.catalog(operator.read) para obtener el catálogo de herramientas en tiempo real de un agente. La respuesta incluye herramientas agrupadas y metadatos de procedencia:source:coreopluginpluginId: propietario del plugin sisource="plugin"optional: indica si una herramienta de plugin es opcional
- Los operadores pueden llamar a
tools.effective(operator.read) para obtener el inventario de herramientas efectivas de una sesión.- Se requiere
sessionKey. - El Gateway deriva el contexto de ejecución confiable desde la sesión en el servidor.
- La respuesta está limitada a la sesión y refleja lo que la conversación activa puede usar en ese momento.
- Se requiere
Aprobaciones de ejecución
Sección titulada «Aprobaciones de ejecución»- Cuando una solicitud de ejecución necesita aprobación, el Gateway emite
exec.approval.requested. - Los clientes de tipo operator resuelven esto llamando a
exec.approval.resolve(requiere el scopeoperator.approvals). - Para
host=node,exec.approval.requestdebe incluirsystemRunPlan(conargv,cwd,rawCommandy metadatos de sesión). Si falta, la solicitud se rechaza.
Fallback de entrega del agente
Sección titulada «Fallback de entrega del agente»- Las solicitudes de
agentpueden incluirdeliver=truepara pedir una entrega externa. bestEffortDeliver=falsemantiene un comportamiento estricto: si el destino no se resuelve o es solo interno, devuelveINVALID_REQUEST.bestEffortDeliver=truepermite ejecutar solo en la sesión cuando no se encuentra una ruta de entrega externa (útil en chats web o configuraciones multicanal ambiguas).
Versiones
Sección titulada «Versiones»PROTOCOL_VERSIONse define ensrc/gateway/protocol/schema.ts.- Los clientes envían
minProtocolymaxProtocol; el servidor rechaza si no hay coincidencia. - Los esquemas y modelos se generan con TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Autenticación
Sección titulada «Autenticación»- Si
OPENCLAW_GATEWAY_TOKEN(o--token) está configurado,connect.params.auth.tokendebe coincidir o el socket se cerrará. - Tras el emparejamiento, el Gateway emite un device token limitado al rol y alcances de la conexión. Se devuelve en
hello-ok.auth.deviceTokeny el cliente debe guardarlo. - Los tokens de dispositivo se pueden rotar o revocar mediante
device.token.rotateydevice.token.revoke(requiereoperator.pairing). - Los fallos de autenticación incluyen
error.details.codey sugerencias de recuperación:error.details.canRetryWithDeviceToken(booleano)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,wait_then_retry, etc.)
Si ocurre un AUTH_TOKEN_MISMATCH, los clientes confiables pueden reintentar una vez con el token de dispositivo guardado. Si falla, deben detener los reintentos automáticos y guiar al usuario.
Identidad de dispositivo y emparejamiento
Sección titulada «Identidad de dispositivo y emparejamiento»- Los nodos deben incluir una identidad estable (
device.id) basada en la huella de un par de claves. - El Gateway emite tokens por dispositivo y rol.
- Se requiere aprobación para nuevos IDs de dispositivo, a menos que la auto-aprobación local esté activa.
- Las conexiones locales incluyen loopback y la dirección de tailnet del host del Gateway.
- Todos los clientes WS deben incluir la identidad
deviceal conectar. La UI de control solo puede omitirlo si:gateway.controlUi.allowInsecureAuth=true(para compatibilidad con HTTP inseguro en localhost).gateway.controlUi.dangerouslyDisableDeviceAuth=true(solo para emergencias, reduce drásticamente la seguridad).
Diagnóstico de migración de identidad
Sección titulada «Diagnóstico de migración de identidad»Para clientes antiguos, connect devuelve códigos en error.details.code con una razón estable en error.details.reason.
Errores comunes de migración:
| Mensaje | details.code | details.reason | Significado |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | Falta device.nonce. |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | El nonce es antiguo o incorrecto. |
device signature invalid | DEVICE_AUTH_SIGNATURE_INVALID | device-signature | La firma no coincide con el payload v2. |
device signature expired | DEVICE_AUTH_SIGNATURE_EXPIRED | device-signature-stale | El timestamp firmado está fuera de rango. |
device identity mismatch | DEVICE_AUTH_DEVICE_ID_MISMATCH | device-id-mismatch | device.id no coincide con la clave pública. |
device public key invalid | DEVICE_AUTH_PUBLIC_KEY_INVALID | device-public-key | Error en el formato de la clave pública. |
Para una migración correcta, espera siempre a connect.challenge, firma el payload v3 (que incluye platform y deviceFamily) y envía el mismo nonce en los parámetros de conexión.
TLS y pinning
Sección titulada «TLS y pinning»- Las conexiones WS admiten TLS.
- Puedes hacer pinning de la huella del certificado del Gateway mediante la configuración
gateway.tlso el flag--tls-fingerprint.
Alcance del protocolo
Sección titulada «Alcance del protocolo»Este protocolo expone toda la API del Gateway (estado, canales, modelos, chat, agentes, sesiones, nodos y aprobaciones). La superficie exacta está definida por los esquemas TypeBox en src/gateway/protocol/schema.ts.
Siguientes pasos
Sección titulada «Siguientes pasos»OpenClaw Expert
Sigues atascado?
Si esta pagina no resolvio tu caso, pregunta a OpenClaw Expert para pasos concretos.