Control UI (Browser)
Die Control UI ist eine kleine Vite + Lit Single-Page-App, die vom Gateway bereitgestellt wird:
- Standard:
http://<host>:18789/ - Optionales Präfix: setze
gateway.controlUi.basePath(z.B./openclaw)
Sie kommuniziert direkt mit dem Gateway WebSocket auf demselben Port.
Schnell öffnen (lokal)
Wenn das Gateway auf demselben Computer läuft, öffne:
Falls die Seite nicht lädt, starte zuerst das Gateway: openclaw gateway.
Die Authentifizierung erfolgt während des WebSocket-Handshakes über:
connect.params.auth.tokenconnect.params.auth.password
Das Dashboard-Einstellungspanel ermöglicht das Speichern eines Tokens; Passwörter werden nicht gespeichert. Der Onboarding-Wizard generiert standardmäßig ein Gateway-Token – füge es beim ersten Verbinden hier ein.
Device Pairing (erste Verbindung)
Wenn du dich von einem neuen Browser oder Gerät mit der Control UI verbindest, verlangt das Gateway eine einmalige Pairing-Freigabe — selbst wenn du im selben Tailnet bist mit gateway.auth.allowTailscale: true. Das ist eine Sicherheitsmaßnahme gegen unbefugten Zugriff.
Was du siehst: “disconnected (1008): pairing required”
So gibst du das Gerät frei:
# Ausstehende Anfragen auflisten
openclaw devices list
# Nach Request-ID freigeben
openclaw devices approve <requestId>
Nach der Freigabe wird das Gerät gespeichert und benötigt keine erneute Freigabe, außer du widerrufst sie mit openclaw devices revoke --device <id> --role <role>. Siehe Devices CLI für Token-Rotation und Widerruf.
Hinweise:
- Lokale Verbindungen (
127.0.0.1) werden automatisch freigegeben. - Remote-Verbindungen (LAN, Tailnet, etc.) benötigen explizite Freigabe.
- Jedes Browser-Profil generiert eine eindeutige Device-ID, daher erfordert ein Browserwechsel oder das Löschen von Browser-Daten ein erneutes Pairing.
Was sie kann (aktuell)
- Chat mit dem Modell über Gateway WS (
chat.history,chat.send,chat.abort,chat.inject) - Streaming von Tool-Aufrufen + Live-Tool-Output-Karten im Chat (Agent-Events)
- Channels: WhatsApp/Telegram/Discord/Slack + Plugin-Channels (Mattermost, etc.) Status + QR-Login + Channel-spezifische Config (
channels.status,web.login.*,config.patch) - Instances: Presence-Liste + Refresh (
system-presence) - Sessions: Liste + Session-spezifische Thinking/Verbose-Overrides (
sessions.list,sessions.patch) - Cron-Jobs: Liste/Hinzufügen/Ausführen/Aktivieren/Deaktivieren + Ausführungsverlauf (
cron.*) - Skills: Status, Aktivieren/Deaktivieren, Installation, API-Key-Updates (
skills.*) - Nodes: Liste + Capabilities (
node.list) - Exec-Freigaben: Gateway- oder Node-Allowlists bearbeiten + Ask-Policy für
exec host=gateway/node(exec.approvals.*) - Config: Anzeigen/Bearbeiten von
~/.openclaw/openclaw.json(config.get,config.set) - Config: Anwenden + Neustart mit Validierung (
config.apply) und Aufwecken der zuletzt aktiven Session - Config-Schreibvorgänge enthalten einen Base-Hash-Guard, um gleichzeitige Bearbeitungen zu verhindern
- Config-Schema + Formular-Rendering (
config.schema, inkl. Plugin- + Channel-Schemas); Raw-JSON-Editor bleibt verfügbar - Debug: Status/Health/Models-Snapshots + Event-Log + manuelle RPC-Aufrufe (
status,health,models.list) - Logs: Live-Tail der Gateway-Datei-Logs mit Filter/Export (
logs.tail) - Update: Package/Git-Update ausführen + Neustart (
update.run) mit Neustart-Report
Chat-Verhalten
chat.sendist non-blocking: Es bestätigt sofort mit{ runId, status: "started" }und die Antwort wird überchat-Events gestreamt.- Erneutes Senden mit demselben
idempotencyKeygibt{ status: "in_flight" }während der Ausführung zurück und{ status: "ok" }nach Abschluss. chat.injectfügt eine Assistenten-Notiz zum Session-Transcript hinzu und sendet einchat-Event nur für UI-Updates (kein Agent-Run, keine Channel-Zustellung).- Stoppen:
- Klicke Stop (ruft
chat.abortauf) - Tippe
/stop(oderstop|esc|abort|wait|exit|interrupt), um out-of-band abzubrechen chat.abortunterstützt{ sessionKey }(ohnerunId), um alle aktiven Runs für diese Session abzubrechen
- Klicke Stop (ruft
Tailnet-Zugriff (empfohlen)
Integriertes Tailscale Serve (bevorzugt)
Halte das Gateway auf Loopback und lass Tailscale Serve es mit HTTPS proxyen:
openclaw gateway --tailscale serve
Öffne:
https://<magicdns>/(oder dein konfiguriertergateway.controlUi.basePath)
Standardmäßig können Serve-Anfragen sich über Tailscale-Identity-Header (tailscale-user-login) authentifizieren, wenn gateway.auth.allowTailscale auf true steht. OpenClaw verifiziert die Identität, indem es die x-forwarded-for-Adresse mit tailscale whois auflöst und mit dem Header abgleicht, und akzeptiert diese nur, wenn die Anfrage Loopback mit Tailscales x-forwarded-*-Headern erreicht. Setze gateway.auth.allowTailscale: false (oder erzwinge gateway.auth.mode: "password"), wenn du auch für Serve-Traffic ein Token/Passwort verlangen willst.
An Tailnet binden + Token
openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"
Dann öffne:
http://<tailscale-ip>:18789/(oder dein konfiguriertergateway.controlUi.basePath)
Füge das Token in die UI-Einstellungen ein (wird als connect.params.auth.token gesendet).
Unsicheres HTTP
Wenn du das Dashboard über einfaches HTTP öffnest (http://<lan-ip> oder http://<tailscale-ip>), läuft der Browser in einem non-secure context und blockiert WebCrypto. Standardmäßig blockiert OpenClaw Control-UI-Verbindungen ohne Device-Identity.
Empfohlene Lösung: Nutze HTTPS (Tailscale Serve) oder öffne die UI lokal:
https://<magicdns>/(Serve)http://127.0.0.1:18789/(auf dem Gateway-Host)
Downgrade-Beispiel (nur Token über HTTP):
{
gateway: {
controlUi: { allowInsecureAuth: true },
bind: "tailnet",
auth: { mode: "token", token: "replace-me" },
},
}
Das deaktiviert Device-Identity + Pairing für die Control UI (auch bei HTTPS). Nutze das nur, wenn du dem Netzwerk vertraust.
Siehe Tailscale für HTTPS-Setup-Anleitung.
UI bauen
Das Gateway stellt statische Dateien aus dist/control-ui bereit. Baue sie mit:
pnpm ui:build # installiert UI-Abhängigkeiten beim ersten Durchlauf automatisch
Optionale absolute Base (wenn du fixe Asset-URLs willst):
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
Für lokale Entwicklung (separater Dev-Server):
pnpm ui:dev # installiert UI-Abhängigkeiten beim ersten Durchlauf automatisch
Dann richte die UI auf deine Gateway-WS-URL aus (z.B. ws://127.0.0.1:18789).
Debugging/Testing: Dev-Server + Remote-Gateway
Die Control UI besteht aus statischen Dateien; das WebSocket-Ziel ist konfigurierbar und kann sich vom HTTP-Origin unterscheiden. Das ist praktisch, wenn du den Vite-Dev-Server lokal haben willst, aber das Gateway woanders läuft.
- Starte den UI-Dev-Server:
pnpm ui:dev - Öffne eine URL wie:
http://localhost:5173/?gatewayUrl=ws://<gateway-host>:18789
Optionale einmalige Authentifizierung (falls nötig):
http://localhost:5173/?gatewayUrl=wss://<gateway-host>:18789&token=<gateway-token>
Hinweise:
gatewayUrlwird nach dem Laden in localStorage gespeichert und aus der URL entfernt.tokenwird in localStorage gespeichert;passwordwird nur im Speicher gehalten.- Nutze
wss://, wenn das Gateway hinter TLS läuft (Tailscale Serve, HTTPS-Proxy, etc.).
Details zum Remote-Zugriff: Remote access.