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 status marca un nodo como vinculado cuando su rol de vinculación de dispositivo incluye node.
  • node.pair.* (CLI: openclaw nodes pending/approve/reject) es un almacén de vinculación de nodos propiedad del gateway; no controla el handshake WS connect.

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.which en 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 run soporta 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.password son 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-name en openclaw node run / openclaw node install (persiste en ~/.openclaw/node.json en 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 present acepta URLs o rutas de archivo locales (--target), más opciones opcionales --x/--y/--width/--height para posicionamiento.
  • canvas eval acepta 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.* y camera.* (las llamadas en segundo plano devuelven NODE_BACKGROUND_UNAVAILABLE).
  • La duración de clips está limitada (actualmente <= 60s) para evitar payloads base64 sobredimensionados.
  • Android solicitará permisos de CAMERA/RECORD_AUDIO cuando 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.record depende de la plataforma del nodo.
  • Las grabaciones de pantalla están limitadas a <= 60s.
  • --no-audio desactiva 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.health
  • notifications.list, notifications.actions
  • photos.latest
  • contacts.search, contacts.add
  • calendar.events, calendar.add
  • motion.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.run devuelve stdout/stderr/código de salida en el payload.
  • system.notify respeta el estado de permiso de notificaciones en la app macOS.
  • Metadatos de nodo con platform / deviceFamily no reconocidos usan una allowlist conservadora por defecto que excluye system.run y system.which. Si necesitas esos comandos para una plataforma desconocida, agrégalos explícitamente mediante gateway.nodes.allowCommands.
  • system.run soporta --cwd, --env KEY=VAL, --command-timeout y --needs-screen-recording.
  • Para wrappers de shell (bash|sh|zsh ... -c/-lc), los valores --env con 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 /c requieren aprobación (la entrada de allowlist sola no auto-permite la forma wrapper).
  • system.notify soporta --priority <passive|active|timeSensitive> y --delivery <system|overlay|auto>.
  • Los hosts de nodo ignoran las sobreescrituras de PATH y 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 pasar PATH mediante --env.
  • En modo nodo de macOS, system.run está 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 devuelven SYSTEM_RUN_DENIED.
  • En el host de nodo headless, system.run está 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.run localmente por defecto. Configura OPENCLAW_NODE_EXEC_HOST=app para enrutar system.run a través del host exec de la app complementaria; agrega OPENCLAW_NODE_EXEC_FALLBACK=0 para requerir el host de la app y fallar de forma cerrada si no está disponible.
  • Agrega --tls / --tls-fingerprint cuando 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.