Nodos
Un nodo es un dispositivo complementario (macOS/iOS/Android/headless) que se conecta al WebSocket del Gateway (mismo puerto que los operadores) con role: "node" y expone una superficie de comandos (p. ej. canvas.*, camera.*, device.*, notifications.*, system.*) mediante node.invoke. Detalles del protocolo: Protocolo del Gateway.
Transporte legacy: Protocolo Bridge (TCP JSONL; deprecado/eliminado para los nodos actuales).
macOS también puede ejecutarse en modo nodo: la app de barra de menú se conecta al servidor WS del Gateway y expone sus comandos locales de canvas/cámara como un nodo (así openclaw nodes … funciona contra este Mac).
Notas:
- Los nodos son periféricos, no gateways. No ejecutan el servicio de gateway.
- Los mensajes de Telegram/WhatsApp/etc. llegan al gateway, no a los nodos.
- Guía de resolución de problemas: /nodes/troubleshooting
Vinculación y estado
Los nodos WS usan vinculación de dispositivos. Los nodos presentan una identidad de dispositivo durante connect; el Gateway
crea una solicitud de vinculación de dispositivo para role: node. Aprueba mediante el CLI de dispositivos (o la UI).
CLI rápido:
openclaw devices list
openclaw devices approve <requestId>
openclaw devices reject <requestId>
openclaw nodes status
openclaw nodes describe --node <idOrNameOrIp>
Notas:
nodes statusmarca un nodo como vinculado cuando su rol de vinculación de dispositivo incluyenode.node.pair.*(CLI:openclaw nodes pending/approve/reject) es un almacén de vinculación de nodos propiedad del gateway; no controla el handshake WSconnect.
Host de nodo remoto (system.run)
Usa un host de nodo cuando tu Gateway se ejecuta en una máquina y quieres que los comandos
se ejecuten en otra. El modelo sigue hablando con el gateway; el gateway
reenvía las llamadas exec al host de nodo cuando se selecciona host=node.
Qué se ejecuta dónde
- Host del Gateway: recibe mensajes, ejecuta el modelo, enruta llamadas de herramientas.
- Host del nodo: ejecuta
system.run/system.whichen la máquina del nodo. - Aprobaciones: se aplican en el host del nodo mediante
~/.openclaw/exec-approvals.json.
Nota sobre aprobaciones:
- Las ejecuciones respaldadas por aprobación en el nodo vinculan el contexto exacto de la solicitud.
- Para ejecuciones directas de shell/archivos en runtime, OpenClaw también intenta vincular best-effort un operando de archivo local concreto y deniega la ejecución si ese archivo cambia antes de la ejecución.
- Si OpenClaw no puede identificar exactamente un archivo local concreto para un comando de intérprete/runtime, la ejecución respaldada por aprobación se deniega en lugar de pretender cobertura completa del runtime. Usa sandboxing, hosts separados o una allowlist de confianza explícita para semánticas de intérprete más amplias.
Iniciar un host de nodo (primer plano)
En la máquina del nodo:
openclaw node run --host <gateway-host> --port 18789 --display-name "Build Node"
Gateway remoto vía túnel SSH (bind a loopback)
Si el Gateway se vincula a loopback (gateway.bind=loopback, por defecto en modo local),
los hosts de nodo remotos no pueden conectarse directamente. Crea un túnel SSH y apunta el
host de nodo al extremo local del túnel.
Ejemplo (host de nodo -> host del gateway):
# Terminal A (mantener ejecutando): reenviar local 18790 -> gateway 127.0.0.1:18789
ssh -N -L 18790:127.0.0.1:18789 user@gateway-host
# Terminal B: exportar el token del gateway y conectar a través del túnel
export OPENCLAW_GATEWAY_TOKEN="<gateway-token>"
openclaw node run --host 127.0.0.1 --port 18790 --display-name "Build Node"
Notas:
openclaw node runsoporta autenticación por token o contraseña.- Se prefieren variables de entorno:
OPENCLAW_GATEWAY_TOKEN/OPENCLAW_GATEWAY_PASSWORD. - Respaldo de configuración:
gateway.auth.token/gateway.auth.password. - En modo local, el host de nodo ignora intencionalmente
gateway.remote.token/gateway.remote.password. - En modo remoto,
gateway.remote.token/gateway.remote.passwordson elegibles según las reglas de precedencia remotas. - Si los SecretRefs activos de
gateway.auth.*están configurados pero no resueltos, la autenticación del host de nodo falla de forma cerrada. - Las variables de entorno legacy
CLAWDBOT_GATEWAY_*se ignoran intencionalmente en la resolución de autenticación del host de nodo.
Iniciar un host de nodo (servicio)
openclaw node install --host <gateway-host> --port 18789 --display-name "Build Node"
openclaw node restart
Vincular y nombrar
En el host del gateway:
openclaw devices list
openclaw devices approve <requestId>
openclaw nodes status
Opciones de nombre:
--display-nameenopenclaw node run/openclaw node install(persiste en~/.openclaw/node.jsonen el nodo).openclaw nodes rename --node <id|name|ip> --name "Build Node"(sobreescritura del gateway).
Allowlist de comandos
Las aprobaciones de ejecución son por host de nodo. Agrega entradas de allowlist desde el gateway:
openclaw approvals allowlist add --node <id|name|ip> "/usr/bin/uname"
openclaw approvals allowlist add --node <id|name|ip> "/usr/bin/sw_vers"
Las aprobaciones se almacenan en el host de nodo en ~/.openclaw/exec-approvals.json.
Apuntar exec al nodo
Configura los valores por defecto (configuración del gateway):
openclaw config set tools.exec.host node
openclaw config set tools.exec.security allowlist
openclaw config set tools.exec.node "<id-or-name>"
O por sesión:
/exec host=node security=allowlist node=<id-or-name>
Una vez configurado, cualquier llamada exec con host=node se ejecuta en el host de nodo (sujeto a la
allowlist/aprobaciones del nodo).
Relacionado:
Invocar comandos
Bajo nivel (RPC directo):
openclaw nodes invoke --node <idOrNameOrIp> --command canvas.eval --params '{"javaScript":"location.href"}'
Existen ayudantes de nivel superior para los flujos de trabajo comunes de “darle al agente un adjunto MEDIA”.
Capturas de pantalla (snapshots del canvas)
Si el nodo está mostrando el Canvas (WebView), canvas.snapshot devuelve { format, base64 }.
Ayudante CLI (escribe en un archivo temporal e imprime MEDIA:<ruta>):
openclaw nodes canvas snapshot --node <idOrNameOrIp> --format png
openclaw nodes canvas snapshot --node <idOrNameOrIp> --format jpg --max-width 1200 --quality 0.9
Controles del canvas
openclaw nodes canvas present --node <idOrNameOrIp> --target https://example.com
openclaw nodes canvas hide --node <idOrNameOrIp>
openclaw nodes canvas navigate https://example.com --node <idOrNameOrIp>
openclaw nodes canvas eval --node <idOrNameOrIp> --js "document.title"
Notas:
canvas presentacepta URLs o rutas de archivo locales (--target), más opciones opcionales--x/--y/--width/--heightpara posicionamiento.canvas evalacepta JS inline (--js) o un argumento posicional.
A2UI (Canvas)
openclaw nodes canvas a2ui push --node <idOrNameOrIp> --text "Hello"
openclaw nodes canvas a2ui push --node <idOrNameOrIp> --jsonl ./payload.jsonl
openclaw nodes canvas a2ui reset --node <idOrNameOrIp>
Notas:
- Solo se soporta A2UI v0.8 JSONL (v0.9/createSurface se rechaza).
Fotos y videos (cámara del nodo)
Fotos (jpg):
openclaw nodes camera list --node <idOrNameOrIp>
openclaw nodes camera snap --node <idOrNameOrIp> # por defecto: ambas orientaciones (2 líneas MEDIA)
openclaw nodes camera snap --node <idOrNameOrIp> --facing front
Clips de video (mp4):
openclaw nodes camera clip --node <idOrNameOrIp> --duration 10s
openclaw nodes camera clip --node <idOrNameOrIp> --duration 3000 --no-audio
Notas:
- El nodo debe estar en primer plano para
canvas.*ycamera.*(las llamadas en segundo plano devuelvenNODE_BACKGROUND_UNAVAILABLE). - La duración de clips está limitada (actualmente
<= 60s) para evitar payloads base64 sobredimensionados. - Android solicitará permisos de
CAMERA/RECORD_AUDIOcuando sea posible; los permisos denegados fallan con*_PERMISSION_REQUIRED.
Grabaciones de pantalla (nodos)
Los nodos compatibles exponen screen.record (mp4). Ejemplo:
openclaw nodes screen record --node <idOrNameOrIp> --duration 10s --fps 10
openclaw nodes screen record --node <idOrNameOrIp> --duration 10s --fps 10 --no-audio
Notas:
- La disponibilidad de
screen.recorddepende de la plataforma del nodo. - Las grabaciones de pantalla están limitadas a
<= 60s. --no-audiodesactiva la captura de micrófono en plataformas compatibles.- Usa
--screen <index>para seleccionar una pantalla cuando hay múltiples monitores disponibles.
Ubicación (nodos)
Los nodos exponen location.get cuando la ubicación está habilitada en los ajustes.
Ayudante CLI:
openclaw nodes location get --node <idOrNameOrIp>
openclaw nodes location get --node <idOrNameOrIp> --accuracy precise --max-age 15000 --location-timeout 10000
Notas:
- La ubicación está desactivada por defecto.
- “Siempre” requiere permiso del sistema; la obtención en segundo plano es best-effort.
- La respuesta incluye lat/lon, precisión (metros) y marca de tiempo.
SMS (nodos Android)
Los nodos Android pueden exponer sms.send cuando el usuario concede el permiso de SMS y el dispositivo soporta telefonía.
Invocación de bajo nivel:
openclaw nodes invoke --node <idOrNameOrIp> --command sms.send --params '{"to":"+15555550123","message":"Hello from OpenClaw"}'
Notas:
- El aviso de permiso debe ser aceptado en el dispositivo Android antes de que la capacidad se anuncie.
- Los dispositivos solo Wi-Fi sin telefonía no anunciarán
sms.send.
Comandos de dispositivo y datos personales en Android
Los nodos Android pueden anunciar familias de comandos adicionales cuando las capacidades correspondientes están habilitadas.
Familias disponibles:
device.status,device.info,device.permissions,device.healthnotifications.list,notifications.actionsphotos.latestcontacts.search,contacts.addcalendar.events,calendar.addmotion.activity,motion.pedometer
Ejemplos de invocación:
openclaw nodes invoke --node <idOrNameOrIp> --command device.status --params '{}'
openclaw nodes invoke --node <idOrNameOrIp> --command notifications.list --params '{}'
openclaw nodes invoke --node <idOrNameOrIp> --command photos.latest --params '{"limit":1}'
Notas:
- Los comandos de movimiento están controlados por la disponibilidad de sensores.
Comandos del sistema (host de nodo / nodo Mac)
El nodo macOS expone system.run, system.notify y system.execApprovals.get/set.
El host de nodo headless expone system.run, system.which y system.execApprovals.get/set.
Ejemplos:
openclaw nodes run --node <idOrNameOrIp> -- echo "Hello from mac node"
openclaw nodes notify --node <idOrNameOrIp> --title "Ping" --body "Gateway ready"
Notas:
system.rundevuelve stdout/stderr/código de salida en el payload.system.notifyrespeta el estado de permiso de notificaciones en la app macOS.- Metadatos de nodo con
platform/deviceFamilyno reconocidos usan una allowlist conservadora por defecto que excluyesystem.runysystem.which. Si necesitas esos comandos para una plataforma desconocida, agrégalos explícitamente mediantegateway.nodes.allowCommands. system.runsoporta--cwd,--env KEY=VAL,--command-timeouty--needs-screen-recording.- Para wrappers de shell (
bash|sh|zsh ... -c/-lc), los valores--envcon alcance de solicitud se reducen a una allowlist explícita (TERM,LANG,LC_*,COLORTERM,NO_COLOR,FORCE_COLOR). - Para decisiones de “permitir siempre” en modo allowlist, los wrappers de despacho conocidos (
env,nice,nohup,stdbuf,timeout) persisten rutas de ejecutables internos en lugar de rutas de wrappers. Si el unwrapping no es seguro, no se persiste ninguna entrada de allowlist automáticamente. - En hosts de nodo Windows en modo allowlist, las ejecuciones de wrappers de shell vía
cmd.exe /crequieren aprobación (la entrada de allowlist sola no auto-permite la forma wrapper). system.notifysoporta--priority <passive|active|timeSensitive>y--delivery <system|overlay|auto>.- Los hosts de nodo ignoran las sobreescrituras de
PATHy eliminan claves peligrosas de inicio/shell (DYLD_*,LD_*,NODE_OPTIONS,PYTHON*,PERL*,RUBYOPT,SHELLOPTS,PS4). Si necesitas entradas extra de PATH, configura el entorno del servicio del host de nodo (o instala herramientas en ubicaciones estándar) en lugar de pasarPATHmediante--env. - En modo nodo de macOS,
system.runestá controlado por aprobaciones exec en la app macOS (Ajustes → Aprobaciones Exec). Ask/allowlist/full se comportan igual que el host de nodo headless; los avisos denegados devuelvenSYSTEM_RUN_DENIED. - En el host de nodo headless,
system.runestá controlado por aprobaciones exec (~/.openclaw/exec-approvals.json).
Vinculación de exec a nodo
Cuando hay múltiples nodos disponibles, puedes vincular exec a un nodo específico.
Esto establece el nodo por defecto para exec host=node (y puede sobreescribirse por agente).
Por defecto global:
openclaw config set tools.exec.node "node-id-or-name"
Sobreescritura por agente:
openclaw config get agents.list
openclaw config set agents.list[0].tools.exec.node "node-id-or-name"
Desconfigurar para permitir cualquier nodo:
openclaw config unset tools.exec.node
openclaw config unset agents.list[0].tools.exec.node
Mapa de permisos
Los nodos pueden incluir un mapa permissions en node.list / node.describe, indexado por nombre de permiso (p. ej. screenRecording, accessibility) con valores booleanos (true = concedido).
Host de nodo headless (multiplataforma)
OpenClaw puede ejecutar un host de nodo headless (sin UI) que se conecta al
WebSocket del Gateway y expone system.run / system.which. Esto es útil en Linux/Windows
o para ejecutar un nodo mínimo junto a un servidor.
Iniciarlo:
openclaw node run --host <gateway-host> --port 18789
Notas:
- La vinculación sigue siendo necesaria (el Gateway mostrará un aviso de vinculación de dispositivo).
- El host de nodo almacena su id de nodo, token, nombre de visualización e información de conexión del gateway en
~/.openclaw/node.json. - Las aprobaciones exec se aplican localmente mediante
~/.openclaw/exec-approvals.json(ver Aprobaciones Exec). - En macOS, el host de nodo headless ejecuta
system.runlocalmente por defecto. ConfiguraOPENCLAW_NODE_EXEC_HOST=apppara enrutarsystem.runa través del host exec de la app complementaria; agregaOPENCLAW_NODE_EXEC_FALLBACK=0para requerir el host de la app y fallar de forma cerrada si no está disponible. - Agrega
--tls/--tls-fingerprintcuando el WS del Gateway usa TLS.
Modo nodo en Mac
- La app de barra de menú de macOS se conecta al servidor WS del Gateway como un nodo (así
openclaw nodes …funciona contra este Mac). - En modo remoto, la app abre un túnel SSH para el puerto del Gateway y se conecta a
localhost.