Gateway Runbook (Guía de Operaciones)
Servicio Gateway, ciclo de vida y operaciones
Última actualización: 2025-12-09
Qué es esto
- El proceso siempre activo que posee la única conexión Baileys/Telegram y el plano de control/eventos.
- Reemplaza el comando legacy
gateway. Punto de entrada CLI:openclaw gateway. - Corre hasta que se detiene; sale con código non-zero en errores fatales para que el supervisor lo reinicie.
Cómo ejecutar (local)
openclaw gateway --port 18789 openclaw gateway --port 18789 --verbose openclaw gateway --force pnpm gateway:watch
- La recarga en caliente de config observa
~/.openclaw/openclaw.json(oOPENCLAW_CONFIG_PATH). - Modo predeterminado:
gateway.reload.mode="hybrid"(aplicar en caliente cambios seguros, reiniciar en críticos). - La recarga en caliente usa reinicio in-process vía SIGUSR1 cuando es necesario.
- Deshabilita con
gateway.reload.mode="off". - Vincula el plano de control WebSocket a
127.0.0.1:<port>(predeterminado 18789). - El mismo puerto también sirve HTTP (UI de control, hooks, A2UI). Multiplexación de puerto único.
- OpenAI Chat Completions(HTTP):
/v1/chat/completions。 - OpenResponses(HTTP):
/v1/responses。 - Toolscall(HTTP):
/tools/invoke。 - Inicia un servidor de archivos Canvas por defecto en
canvasHost.port(predeterminado18793), sirviendohttp://<gateway-host>:18793/__openclaw__/canvas/desde~/.openclaw/workspace/canvas. Deshabilita concanvasHost.enabled=falseoOPENCLAW_SKIP_CANVAS_HOST=1. - Logs a stdout; usa launchd/systemd para mantenerlo vivo y rotar logs.
- Pasa
--verbosepara duplicar logging debug (handshakes, req/res, eventos) desde el archivo de log a stdio al resolver problemas. --forceusalsofpara encontrar listeners en el puerto elegido, envía SIGTERM, loggea lo que mató, luego inicia el gateway (falla rápido si faltalsof).- Si ejecutas bajo un supervisor (launchd/systemd/mac app child-process mode), un stop/restart típicamente envía SIGTERM; builds antiguos pueden mostrar esto como
pnpmELIFECYCLEcódigo de salida 143 (SIGTERM), que es un apagado normal, no un crash. - SIGUSR1 dispara un reinicio in-process cuando está autorizado (herramienta gateway/config apply/update, o habilita
commands.restartpara reinicios manuales). - La autenticación del Gateway es requerida por defecto: establece
gateway.auth.token(oOPENCLAW_GATEWAY_TOKEN) ogateway.auth.password. Los clientes deben enviarconnect.params.auth.token/passworda menos que usen identidad Tailscale Serve. - El wizard ahora genera un token por defecto, incluso en loopback.
- Precedencia de puerto:
--port>OPENCLAW_GATEWAY_PORT>gateway.port> predeterminado18789.
Acceso Remoto
Tailscale/VPN preferido; de lo contrario tunnel SSH:
ssh -N -L 18789:127.0.0.1:18789 user@host
- Los clientes entonces se conectan a
ws://127.0.0.1:18789a través del tunnel. - Si un token está configurado, los clientes deben incluirlo en
connect.params.auth.tokenincluso sobre el tunnel.
Múltiples gateways (mismo host)
Generalmente innecesario: un Gateway puede servir múltiples canales de mensajería y agentes. Usa múltiples Gateways solo para redundancia o aislamiento estricto (ej: rescue bot).
Soportado si aíslas estado + config y usas puertos únicos. Guía completa: Múltiples gateways.
Los nombres de servicio son conscientes del perfil:
- macOS:
bot.molt.<profile>(legacycom.openclaw.*puede todavía existir) - Linux:
openclaw-gateway-<profile>.service - Windows:
OpenClaw Gateway (<profile>)
Los metadatos de instalación están embebidos en la config del servicio:
OPENCLAW_SERVICE_MARKER=openclawOPENCLAW_SERVICE_KIND=gatewayOPENCLAW_SERVICE_VERSION=<version>
Patrón Rescue-Bot: mantiene un segundo Gateway aislado con su propio perfil, directorio de estado, workspace, y espaciado de puerto base. Guía completa: Guía rescue-bot.
Dev profile (`--dev`)
Fast path: run a fully-isolated dev instance (config/state/workspace) without touching your primary setup.
openclaw --dev setup openclaw --dev gateway --allow-unconfigured openclaw --dev status openclaw --dev health
Defaults (can be overridden via env/flags/config):
OPENCLAW_STATE_DIR=~/.openclaw-devOPENCLAW_CONFIG_PATH=~/.openclaw-dev/openclaw.jsonOPENCLAW_GATEWAY_PORT=19001(Gateway WS + HTTP)- browser control service port =
19003(derived:gateway.port+2, loopback only) canvasHost.port=19005(derived:gateway.port+4)--devwithsetup/onboardmakesagents.defaults.workspacedefault to~/.openclaw/workspace-dev.
Derived ports (rules of thumb):
- Base port =
gateway.port(orOPENCLAW_GATEWAY_PORT/--port) - browser control service port = base + 2 (loopback only)
canvasHost.port = base + 4(orOPENCLAW_CANVAS_HOST_PORT/ config override)- Browser profile CDP ports auto-allocate from
browser.controlPort + 9 .. + 108(persisted per profile).
Checklist per instance:
- unique
gateway.port - unique
OPENCLAW_CONFIG_PATH - unique
OPENCLAW_STATE_DIR - unique
agents.defaults.workspace - separate WhatsApp numbers (if using WA)
Service install per profile:
openclaw --profile main gateway install openclaw --profile rescue gateway install
Example:
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json OPENCLAW_STATE_DIR=~/.openclaw-a openclaw gateway --port 19001 OPENCLAW_CONFIG_PATH=~/.openclaw/b.json OPENCLAW_STATE_DIR=~/.openclaw-b openclaw gateway --port 19002
Protocol (operator view)
Full docs: Gateway protocol and Bridge protocol (legacy).
- Mandatory first frame from client: <code>req {type:"req", id, method:"connect", params:{minProtocol,maxProtocol,client:{id,displayName?,version,platform,deviceFamily?,modelIdentifier?,mode,instanceId?}, caps, auth?, locale?, userAgent? } }'</code>.
- Gateway replies <code>res {type:"res", id, ok:true, payload:hello-ok }'</code> (or <code>ok:false</code> with an error, then closes).
- After handshake:
- Requests: <code>'{type:"req", id, method, params}'</code> → <code>'{type:"res", id, ok, payload|error}'</code>
- event:<code>'{type:"event", event, payload, seq?, stateVersion?}'</code>
- Structured presence entries: <code>'{host, ip, version, platform?, deviceFamily?, modelIdentifier?, mode, lastInputSeconds?, ts, reason?, tags?[], instanceId? }'</code> (for WS clients, <code>instanceId</code> comes from <code>connect.client.instanceId</code>).
- <code>agent</code> responses are two-stage: first <code>res</code> ack <code>'{runId,status:"accepted"}'</code>, then a final <code>res</code> <code>'{runId,status:"ok"|"error",summary}'</code> after the run finishes; streamed output arrives as <code>event:"agent"</code>.
Métodos (conjunto inicial)
health— snapshot completo de salud (misma forma queopenclaw health --json).status— resumen corto.system-presence— lista de presencia actual.system-event— publicar una nota de presencia/sistema (estructurada).send— enviar un mensaje vía canal(es) activo(s).agent— ejecutar un turno de agente (transmite eventos de vuelta en la misma conexión).node.list— listar nodos emparejados + actualmente conectados (incluyecaps,deviceFamily,modelIdentifier,paired,connected, ycommandsanunciados).node.describe— describir un nodo (capacidades + comandosnode.invokesoportados; funciona para nodos emparejados y para nodos no emparejados actualmente conectados).node.invoke— invocar un comando en un nodo (ej.canvas.*,camera.*).node.pair.*— ciclo de vida de emparejamiento (request,list,approve,reject,verify).
Ver también: Presencia para cómo se produce/desduplica la presencia y por qué un client.instanceId estable importa.
Eventos
agent— eventos de tool/output transmitidos desde la ejecución del agente (etiquetados con seq).presence— actualizaciones de presencia (deltas con stateVersion) enviadas a todos los clientes conectados.tick— keepalive/no-op periódico para confirmar vitalidad.shutdown— el Gateway está saliendo; payload incluyereasony opcionalrestartExpectedMs. Los clientes deben reconectar.
Integración WebChat
- WebChat es una UI SwiftUI nativa que habla directamente al WebSocket del Gateway para historial, envíos, abort y eventos.
- Uso remoto va a través del mismo túnel SSH/Tailscale; si un token de gateway está configurado, el cliente lo incluye durante
connect. - La app macOS conecta vía un único WS (conexión compartida); hidrata presencia desde el snapshot inicial y escucha eventos
presencepara actualizar la UI.
Tipado y validación
- El servidor valida cada frame entrante con AJV contra JSON Schema emitido desde las definiciones de protocolo.
- Los clientes (TS/Swift) consumen tipos generados (TS directamente; Swift vía el generador del repo).
- Las definiciones de protocolo son la fuente de verdad; regenera schema/models con:
pnpm protocol:genpnpm protocol:gen:swift
Snapshot de conexión
- <code>hello-ok</code> incluye un <code>snapshot</code> con <code>presence</code>, <code>health</code>, <code>stateVersion</code>, y <code>uptimeMs</code> más <code>policy {maxPayload,maxBufferedBytes,tickIntervalMs}'</code> para que los clientes puedan renderizar inmediatamente sin solicitudes extra.
health/system-presencepermanecen disponibles para refresh manual, pero no se requieren al momento de conectar.
Códigos de error (forma res.error)
Los errores usan <code>'{ code, message, details?, retryable?, retryAfterMs? }'</code>.
Códigos estándar:
NOT_LINKED— WhatsApp no autenticado.AGENT_TIMEOUT— el agente no respondió dentro del deadline configurado.INVALID_REQUEST— validación de schema/param falló.UNAVAILABLE— el Gateway se está apagando o una dependencia no está disponible.
Comportamiento de keepalive
- Eventos
tick(o WS ping/pong) se emiten periódicamente para que los clientes sepan que el Gateway está vivo incluso cuando no ocurre tráfico. - Los acks de envío/agente permanecen como respuestas separadas; no sobrecargues ticks para envíos.
Replay / gaps
Los eventos no se reproducen. Los clientes detectan gaps de seq y deben hacer refresh (health + system-presence) antes de continuar. Los clientes WebChat y macOS ahora auto-refrescan en gap.
Supervisión (ejemplo macOS)
Usa launchd para mantener el servicio vivo:
- Program: ruta a
openclaw - Arguments:
gateway - KeepAlive: true
- StandardOut/Err: rutas de archivo o
syslog - En fallo, launchd reinicia; misconfig fatal debería seguir saliendo para que el operador note.
- LaunchAgents son por usuario y requieren sesión iniciada; para configuraciones headless usa un LaunchDaemon personalizado (no incluido).
openclaw gateway installescribe~/Library/LaunchAgents/bot.molt.gateway.plist(obot.molt.<profile>.plist; legacycom.openclaw.*se limpia).openclaw doctoraudita la config del LaunchAgent y puede actualizarla a defaults actuales.
Gestión del servicio Gateway (CLI)
Usa el CLI del Gateway para install/start/stop/restart/status:
openclaw gateway status openclaw gateway install openclaw gateway stop openclaw gateway restart openclaw logs --follow
Notas:
gateway statusprueba el RPC del Gateway por defecto usando el puerto/config resuelto del servicio (anula con--url).gateway status --deepañade escaneos a nivel de sistema (LaunchDaemons/system units).gateway status --no-probesalta la prueba RPC (útil cuando la red está caída).gateway status --jsones estable para scripts.gateway statusreporta runtime del supervisor (launchd/systemd corriendo) separado de accesibilidad RPC (WS connect + status RPC).- <code>gateway status</code> imprime ruta de config + objetivo de prueba para evitar confusión "localhost vs bind LAN" y mismatches de perfil.
- <code>gateway status</code> incluye la última línea de error del gateway cuando el servicio parece correr pero el puerto está cerrado.
logshace tail del archivo de log del Gateway vía RPC (no necesitastail/grepmanual).- Si se detectan otros servicios tipo gateway, el CLI advierte a menos que sean servicios de perfil OpenClaw.
- Todavía recomendamos un gateway por máquina para la mayoría de configuraciones; usa perfiles/puertos aislados para redundancia o rescue bot. Ver Múltiples gateways.
- Limpieza:
openclaw gateway uninstall(servicio actual) yopenclaw doctor(migraciones legacy). gateway installes no-op cuando ya está instalado; usaopenclaw gateway install --forcepara reinstalar (cambios de perfil/env/path).
App mac incluida:
- OpenClaw.app puede incluir un relay gateway basado en Node e instalar un LaunchAgent por usuario etiquetado
bot.molt.gateway(obot.molt.<profile>; labels legacycom.openclaw.*todavía se descargan limpiamente). - Para detenerlo limpiamente, usa
openclaw gateway stop(olaunchctl bootout gui/$UID/bot.molt.gateway). - Para reiniciar, usa
openclaw gateway restart(olaunchctl kickstart -k gui/$UID/bot.molt.gateway). launchctlsolo funciona si el LaunchAgent está instalado; de lo contrario usaopenclaw gateway installprimero.- Reemplaza el label con
bot.molt.<profile>cuando ejecutes un perfil con nombre.
Supervisión (unidad de usuario systemd)
OpenClaw instala un servicio de usuario systemd por defecto en Linux/WSL2. Recomendamos servicios de usuario para máquinas de usuario único (env más simple, config por usuario). Usa un servicio de sistema para servidores multi-usuario o siempre encendidos (no requiere lingering, supervisión compartida).
openclaw gateway install escribe la unidad de usuario. openclaw doctor audita la unidad y puede actualizarla para coincidir con los defaults recomendados actuales.
Crea ~/.config/systemd/user/openclaw-gateway[-<profile>].service:
[Unit] Description=OpenClaw Gateway (profile: <profile>, v<version>) After=network-online.target Wants=network-online.target [Service] ExecStart=/usr/local/bin/openclaw gateway --port 18789 Restart=always RestartSec=5 Environment=OPENCLAW_GATEWAY_TOKEN= WorkingDirectory=/home/youruser [Install] WantedBy=default.target
Habilita lingering (requerido para que el servicio de usuario sobreviva logout/idle):
sudo loginctl enable-linger youruser
Onboarding ejecuta esto en Linux/WSL2 (puede pedir sudo; escribe /var/lib/systemd/linger). Luego habilita el servicio:
<strong>Alternativa (servicio de sistema)</strong> - para servidores siempre encendidos o multi-usuario, puedes instalar una unidad de <strong>sistema</strong> systemd en lugar de una unidad de usuario (no se necesita lingering).
systemctl --user enable --now openclaw-gateway[-<profile>].service
Alternativa (servicio de sistema): Para servidores siempre encendidos/multi-usuario, usa instalación de unidad de sistema systemd (no requiere linger).
Crea /etc/systemd/system/openclaw-gateway[-<profile>].service (copia la unidad arriba, cambia WantedBy=multi-user.target, establece User= + WorkingDirectory=) y ejecuta:
sudo systemctl daemon-reload sudo systemctl enable --now openclaw-gateway[-<profile>].service
Windows(WSL2)
En Windows, usa WSL2 y sigue la sección de systemd Linux arriba.
Operational checks
- Liveness: open WS and expect
req:connect→payload.type="hello-ok"(with snapshot)res. - Readiness: expect
health→ok: trueandlinkChannelhas linked channels (if applicable). - Debug: subscribe to
tick/presence, checkstatuslink/auth age, and confirm presence gateway host / connected clients.
Safety guarantees
- Por defecto asume un Gateway por host. Si ejecutas múltiples perfiles, aísla puerto/estado y especifica la instancia correcta.
- Sin fallback directo a conexión Baileys. Si el Gateway está caído, los envíos fallan inmediatamente.
- Rechaza primeros frames no conectados y JSON inválido, cerrando el socket.
- Apagado graceful: envía
shutdownantes de cerrar. Los clientes manejan cierre + reconexión.
CLI helpers
openclaw gateway health|status— Get health/status via Gateway WS.openclaw message send --target <num> --message "hi" [--media ...]— Send via Gateway (WhatsApp is idempotent).openclaw agent --message "hi" --to <num>— Run an agent turn (waits for final by default).openclaw gateway call <method> --params {"k":"v"}— Raw method call for debugging.openclaw gateway stop|restart— Stop/restart the supervised Gateway service (launchd/systemd).- Gateway helpers assume
--urlis running; they do not auto-start.
Migration guidance
- Deja de usar el antiguo
openclaw gatewayy el antiguo puerto de control TCP. - Actualizar clientes para conectar requerido y presencia estructurada con su propio protocolo WS.