UI de control (navegador)¶
La UI de control es una pequeña aplicación de una sola página Vite + Lit servida por el Gateway:
- predeterminado:
http://<host>:18789/ - prefijo opcional: configure
gateway.controlUi.basePath(p. ej.,/openclaw)
Se comunica directamente con el WebSocket del Gateway en el mismo puerto.
Apertura rápida (local)¶
Si el Gateway se está ejecutando en la misma computadora, abra:
Si la página no carga, inicie primero el Gateway: openclaw gateway.
La autenticación se proporciona durante el handshake de WebSocket mediante:
connect.params.auth.tokenconnect.params.auth.passwordEl panel de configuración del dashboard le permite almacenar un token; las contraseñas no se persisten. El asistente de incorporación genera un token del gateway de forma predeterminada, así que péguelo aquí en la primera conexión.
Emparejamiento de dispositivos (primera conexión)¶
Cuando se conecta a la UI de control desde un navegador o dispositivo nuevo, el Gateway
requiere una aprobación de emparejamiento única — incluso si está en la misma Tailnet
con gateway.auth.allowTailscale: true. Esto es una medida de seguridad para prevenir
accesos no autorizados.
Lo que verá: "disconnected (1008): pairing required"
Para aprobar el dispositivo:
# List pending requests
openclaw devices list
# Approve by request ID
openclaw devices approve <requestId>
Una vez aprobado, el dispositivo se recuerda y no requerirá re-aprobación a menos que
lo revoque con openclaw devices revoke --device <id> --role <role>. Consulte
Devices CLI para rotación y revocación de tokens.
Notas:
- Las conexiones locales (
127.0.0.1) se aprueban automáticamente. - Las conexiones remotas (LAN, Tailnet, etc.) requieren aprobación explícita.
- Cada perfil de navegador genera un ID de dispositivo único, por lo que cambiar de navegador o borrar los datos del navegador requerirá volver a emparejar.
Qué puede hacer (hoy)¶
- Chatear con el modelo vía Gateway WS (
chat.history,chat.send,chat.abort,chat.inject) - Transmitir llamadas a herramientas + tarjetas de salida de herramientas en vivo en Chat (eventos del agente)
- Canales: estado de WhatsApp/Telegram/Discord/Slack + canales de plugins (Mattermost, etc.) + inicio de sesión por QR + configuración por canal (
channels.status,web.login.*,config.patch) - Instancias: lista de presencia + actualización (
system-presence) - Sesiones: lista + sobrescrituras de thinking/verbose por sesión (
sessions.list,sessions.patch) - Tareas cron: listar/agregar/ejecutar/habilitar/deshabilitar + historial de ejecuciones (
cron.*) - Skills: estado, habilitar/deshabilitar, instalar, actualizaciones de claves de API (
skills.*) - Nodos: lista + capacidades (
node.list) - Aprobaciones de ejecución: editar listas de permitidos del gateway o del nodo + política de solicitud para
exec host=gateway/node(exec.approvals.*) - Configuración: ver/editar
~/.openclaw/openclaw.json(config.get,config.set) - Configuración: aplicar + reiniciar con validación (
config.apply) y reactivar la última sesión activa - Las escrituras de configuración incluyen una protección de hash base para evitar sobrescribir ediciones concurrentes
- Esquema de configuración + renderizado de formularios (
config.schema, incluidos esquemas de plugins + canales); el editor de JSON en bruto sigue disponible - Depuración: instantáneas de estado/salud/modelos + registro de eventos + llamadas RPC manuales (
status,health,models.list) - Registros: tail en vivo de los registros de archivos del gateway con filtro/exportación (
logs.tail) - Actualización: ejecutar una actualización de paquetes/git + reiniciar (
update.run) con un informe de reinicio
Notas del panel de tareas cron:
- Para tareas aisladas, la entrega predeterminada es anunciar un resumen. Puede cambiar a ninguno si desea ejecuciones solo internas.
- Los campos de canal/destino aparecen cuando se selecciona anunciar.
Comportamiento del chat¶
chat.sendes no bloqueante: confirma de inmediato con{ runId, status: "started" }y la respuesta se transmite mediante eventoschat.- Reenviar con el mismo
idempotencyKeydevuelve{ status: "in_flight" }mientras se ejecuta, y{ status: "ok" }tras la finalización. chat.injectagrega una nota del asistente al transcript de la sesión y difunde un eventochatpara actualizaciones solo de la UI (sin ejecución del agente, sin entrega a canales).- Detener:
- Haga clic en Stop (llama a
chat.abort) - Escriba
/stop(ostop|esc|abort|wait|exit|interrupt) para abortar fuera de banda chat.abortadmite{ sessionKey }(sinrunId) para abortar todas las ejecuciones activas de esa sesión
Acceso por Tailnet (recomendado)¶
Tailscale Serve integrado (preferido)¶
Mantenga el Gateway en loopback y deje que Tailscale Serve lo proxifique con HTTPS:
openclaw gateway --tailscale serve
Abra:
https://<magicdns>/(o sugateway.controlUi.basePathconfigurado)
De forma predeterminada, las solicitudes de Serve pueden autenticarse mediante encabezados de identidad de Tailscale
(tailscale-user-login) cuando gateway.auth.allowTailscale es true. OpenClaw
verifica la identidad resolviendo la dirección x-forwarded-for con
tailscale whois y comparándola con el encabezado, y solo acepta estas cuando la
solicitud llega a loopback con los encabezados x-forwarded-* de Tailscale. Configure
gateway.auth.allowTailscale: false (o fuerce gateway.auth.mode: "password")
si desea requerir un token/contraseña incluso para tráfico de Serve.
Vincular a tailnet + token¶
openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"
Luego abra:
http://<tailscale-ip>:18789/(o sugateway.controlUi.basePathconfigurado)
Pegue el token en la configuración de la UI (enviado como connect.params.auth.token).
HTTP inseguro¶
Si abre el dashboard sobre HTTP sin cifrar (http://<lan-ip> o http://<tailscale-ip>),
el navegador se ejecuta en un contexto no seguro y bloquea WebCrypto. De forma predeterminada,
OpenClaw bloquea las conexiones de la UI de control sin identidad de dispositivo.
Solución recomendada: use HTTPS (Tailscale Serve) o abra la UI localmente:
https://<magicdns>/(Serve)http://127.0.0.1:18789/(en el host del Gateway)
Ejemplo de degradación (solo token sobre HTTP):
{
gateway: {
controlUi: { allowInsecureAuth: true },
bind: "tailnet",
auth: { mode: "token", token: "replace-me" },
},
}
Esto deshabilita la identidad de dispositivo + el emparejamiento para la UI de control (incluso en HTTPS). Úselo solo si confía en la red.
Consulte Tailscale para obtener orientación sobre la configuración de HTTPS.
Construcción de la UI¶
El Gateway sirve archivos estáticos desde dist/control-ui. Compílelos con:
pnpm ui:build # auto-installs UI deps on first run
Base absoluta opcional (cuando desea URL de recursos fijas):
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
Para desarrollo local (servidor de desarrollo separado):
pnpm ui:dev # auto-installs UI deps on first run
Luego apunte la UI a la URL de WS de su Gateway (p. ej., ws://127.0.0.1:18789).
Depuración/pruebas: servidor de desarrollo + Gateway remoto¶
La UI de control son archivos estáticos; el destino de WebSocket es configurable y puede ser diferente del origen HTTP. Esto es útil cuando desea el servidor de desarrollo de Vite localmente pero el Gateway se ejecuta en otro lugar.
- Inicie el servidor de desarrollo de la UI:
pnpm ui:dev - Abra una URL como:
http://localhost:5173/?gatewayUrl=ws://<gateway-host>:18789
Autenticación única opcional (si es necesaria):
http://localhost:5173/?gatewayUrl=wss://<gateway-host>:18789&token=<gateway-token>
Notas:
gatewayUrlse almacena en localStorage después de la carga y se elimina de la URL.tokense almacena en localStorage;passwordse mantiene solo en memoria.- Cuando
gatewayUrlestá configurado, la UI no recurre a credenciales de configuración o de entorno. Proporcionetoken(opassword) explícitamente. La falta de credenciales explícitas es un error. - Use
wss://cuando el Gateway esté detrás de TLS (Tailscale Serve, proxy HTTPS, etc.). gatewayUrlsolo se acepta en una ventana de nivel superior (no incrustada) para prevenir clickjacking.- Para configuraciones de desarrollo de origen cruzado (p. ej.,
pnpm ui:devhacia un Gateway remoto), agregue el origen de la UI agateway.controlUi.allowedOrigins.
Ejemplo:
{
gateway: {
controlUi: {
allowedOrigins: ["http://localhost:5173"],
},
},
}
Detalles de configuración de acceso remoto: Acceso remoto.