Zum Inhalt springen

OpenClaw Control UI einrichten: Schneller Zugriff & Pairing

Kennst du das? Du hast dein Backend perfekt konfiguriert, aber ständig nur mit der CLI zu hantieren, kann auf Dauer mühsam sein. Manchmal braucht man einfach eine klare visuelle Übersicht, um den Status zu prüfen oder Konfigurationen schnell anzupassen, ohne sich durch Terminal-Logs zu wühlen. Hier kommt das Control UI ins Spiel.

Das Control UI ist eine kompakte Vite + Lit Single-Page App, die direkt vom Gateway bereitgestellt wird:

  • Standard: http://<host>:18789/
  • Optionaler Prefix: Über gateway.controlUi.basePath einstellbar (z. B. /openclaw)

Die App kommuniziert über denselben Port direkt mit dem Gateway WebSocket.

Wenn das Gateway auf demselben Rechner läuft, öffne einfach:

Falls die Seite nicht lädt, starte zuerst das Gateway: openclaw gateway.

Die Authentifizierung erfolgt beim WebSocket-Handshake über:

  • connect.params.auth.token
  • connect.params.auth.password

Das Dashboard-Einstellungs-Panel speichert einen Token für die aktuelle Browser-Tab-Session und die gewählte Gateway-URL; Passwörter werden nicht dauerhaft gespeichert. Beim Onboarding wird standardmäßig ein Gateway-Token generiert, den du bei der ersten Verbindung hier einfügen kannst.

Wenn du dich von einem neuen Browser oder Gerät mit dem Control UI verbindest, verlangt das Gateway eine einmalige Pairing-Freigabe. Das gilt auch, wenn du dich im selben Tailnet befindest und gateway.auth.allowTailscale: true gesetzt ist. Dies ist eine Sicherheitsmaßnahme, um unbefugten Zugriff zu verhindern.

Was du sehen wirst: “disconnected (1008): pairing required”

So bestätigst du das Gerät:

Terminal-Fenster
# List pending requests
openclaw devices list
# Approve by request ID
openclaw devices approve <requestId>

Falls der Browser das Pairing mit geänderten Auth-Details (Rollen/Scopes/Public Key) erneut versucht, wird die vorherige Anfrage ersetzt und eine neue requestId erstellt. Führe openclaw devices list vor der Bestätigung erneut aus.

Sobald das Gerät bestätigt ist, bleibt es gespeichert. Du musst es erst wieder freigeben, wenn du den Zugriff mit openclaw devices revoke --device <id> --role <role> entziehst. Details zu Token-Rotation findest du in der Devices CLI.

Hinweise:

  • Lokale Verbindungen (127.0.0.1) werden automatisch bestätigt.
  • Remote-Verbindungen (LAN, Tailnet, etc.) erfordern eine explizite Freigabe.
  • Jedes Browser-Profil generiert eine eindeutige Device ID; das Wechseln des Browsers oder Löschen von Browserdaten erfordert ein erneutes Pairing.
  • Du kannst bestehende Berechtigungen jederzeit über die CLI widerrufen.

Das Control UI kann sich beim ersten Laden automatisch an deine Browser-Sprache anpassen. Du kannst dies später über die Sprachauswahl in der Access-Card ändern.

  • Unterstützte Sprachen: en, zh-CN, zh-TW, pt-BR, de, es
  • Nicht-englische Übersetzungen werden im Browser per Lazy-Loading nachgeladen.
  • Die gewählte Sprache wird im Browser-Speicher gesichert und bei zukünftigen Besuchen wiederverwendet.
  • Fehlende Übersetzungsschlüssel fallen automatisch auf Englisch zurück.
  • Chat mit dem Modell via Gateway WS (chat.history, chat.send, chat.abort, chat.inject)
  • Streaming von Tool-Calls + Live-Tool-Output-Cards im Chat (Agent-Events)
  • Channels: Status von WhatsApp/Telegram/Discord/Slack + Plugin-Channels (Mattermost, etc.) + QR-Login + Konfiguration pro Channel (channels.status, web.login.*, config.patch)
  • Instances: Presence-Liste + Refresh (system-presence)
  • Sessions: Liste + Overrides pro Session für Thinking/Fast/Verbose/Reasoning (sessions.list, sessions.patch)
  • Cron-Jobs: Listen/Hinzufügen/Editieren/Ausführen/Aktivieren/Deaktivieren + Verlauf (cron.*)
  • Skills: Status, Aktivieren/Deaktivieren, Installieren, API-Key-Updates (skills.*)
  • Nodes: Liste + Caps (node.list)
  • Exec-Freigaben: Gateway- oder Node-Allowlists bearbeiten + Ask-Policy für exec host=gateway/node (exec.approvals.*)
  • Konfiguration: ~/.openclaw/openclaw.json ansehen und bearbeiten (config.get, config.set)
  • Konfiguration: Anwenden + Neustart mit Validierung (config.apply) und Reaktivierung der letzten Session
  • Schreibvorgänge in der Konfiguration nutzen einen Base-Hash-Schutz, um gleichzeitiges Überschreiben zu verhindern
  • Config-Writes (config.set/config.apply/config.patch) prüfen vorab die SecretRef-Auflösung; ungelöste Referenzen werden abgelehnt
  • Config-Schema + Formular-Rendering (config.schema, inklusive Plugin- + Channel-Schemas); der Raw-JSON-Editor ist nur verfügbar, wenn ein sicherer Round-Trip möglich ist
  • Wenn ein Snapshot keinen sicheren Round-Trip erlaubt, erzwingt das UI den Formular-Modus und deaktiviert den Raw-Modus
  • Strukturierte SecretRef-Objektwerte werden in Textfeldern schreibgeschützt angezeigt, um versehentliche Beschädigungen zu vermeiden
  • Debug: Snapshots für Status/Health/Modelle + Event-Log + manuelle RPC-Aufrufe (status, health, models.list)
  • Logs: Live-Tail der Gateway-Logs mit Filter und Export (logs.tail)
  • Update: Paket-/Git-Update ausführen + Neustart (update.run) mit Bericht

Hinweise zum Cron-Jobs-Panel:

  • Bei isolierten Jobs ist die Zustellung standardmäßig auf “Announce Summary” eingestellt. Du kannst dies auf “None” setzen, wenn du nur interne Durchläufe willst.
  • Channel- und Ziel-Felder erscheinen, wenn “Announce” ausgewählt ist.
  • Der Webhook-Modus nutzt delivery.mode = "webhook" mit einer gültigen HTTP(S)-URL in delivery.to.
  • Für Jobs in der Haupt-Session stehen die Modi “Webhook” und “None” zur Verfügung.
  • Erweiterte Optionen umfassen Delete-after-run, Agent-Overrides, Cron-Stagger-Optionen und Best-Effort-Zustellung.
  • Die Formular-Validierung erfolgt inline; ungültige Werte deaktivieren den Speichern-Button.
  • Setze cron.webhookToken für einen dedizierten Bearer-Token, ansonsten wird der Webhook ohne Auth-Header gesendet.
  • Veralteter Fallback: Gespeicherte Legacy-Jobs mit notify: true können cron.webhook weiterhin nutzen, bis sie migriert wurden.
  • chat.send ist non-blocking: Es bestätigt sofort mit { runId, status: "started" } und die Antwort streamt über chat Events.
  • Erneutes Senden mit demselben idempotencyKey gibt { status: "in_flight" } während der Laufzeit und { status: "ok" } nach Abschluss zurück.
  • chat.history Antworten sind für die UI-Stabilität in der Größe begrenzt. Bei zu großen Einträgen kann das Gateway Texte kürzen oder Metadaten weglassen und durch Platzhalter wie [chat.history omitted: message too large] ersetzen.
  • chat.inject fügt eine Assistant-Notiz zur Session hinzu und sendet ein chat Event für UI-Updates (kein Agent-Run, keine Channel-Zustellung).
  • Stoppen:
    • Klicke auf Stop (ruft chat.abort auf)
    • Tippe /stop (oder Phrasen wie stop, stop action, stop run, stop openclaw, please stop)
    • chat.abort unterstützt { sessionKey }, um alle aktiven Runs einer Session zu beenden
    • Beim Abbrechen bleibt bereits generierter Text in der UI und im Verlauf erhalten, inklusive entsprechender Metadaten

Lasse das Gateway auf Loopback laufen und nutze Tailscale Serve als HTTPS-Proxy:

Terminal-Fenster
openclaw gateway --tailscale serve

Öffne:

  • https://<magicdns>/ (oder deinen konfigurierten gateway.controlUi.basePath)

Standardmäßig können Control UI/WebSocket-Anfragen über Tailscale-Identitäts-Header (tailscale-user-login) authentifiziert werden, wenn gateway.auth.allowTailscale auf true steht. OpenClaw verifiziert die Identität via tailscale whois über die x-forwarded-for Adresse. Setze gateway.auth.allowTailscale: false, wenn du trotzdem ein Passwort verlangen willst. Die tokenlose Authentifizierung setzt voraus, dass der Host vertrauenswürdig ist.

Terminal-Fenster
openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"

Öffne dann:

  • http://<tailscale-ip>:18789/ (oder deinen konfigurierten gateway.controlUi.basePath)

Kopiere den Token in die UI-Einstellungen (wird als connect.params.auth.token gesendet).

Wenn du das Dashboard über einfaches HTTP öffnest (http://<lan-ip> oder http://<tailscale-ip>), läuft der Browser in einem unsicheren Kontext und blockiert WebCrypto. Standardmäßig blockiert OpenClaw Control UI-Verbindungen ohne Geräte-Identität.

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)

Verhalten des Insecure-Auth-Schalters:

{
gateway: {
controlUi: { allowInsecureAuth: true },
bind: "tailnet",
auth: { mode: "token", token: "replace-me" },
},
}

allowInsecureAuth ist nur ein lokaler Kompatibilitäts-Schalter:

  • Er erlaubt localhost-Sessions ohne Geräte-Identität in unsicheren HTTP-Kontexten.
  • Er umgeht keine Pairing-Prüfungen.
  • Er lockert keine Anforderungen für Remote-Geräte-Identitäten auf.
  • Verwende ihn nur, wenn lokale Kompatibilität zwingend erforderlich ist.

Nur für den Notfall:

{
gateway: {
controlUi: { dangerouslyDisableDeviceAuth: true },
bind: "tailnet",
auth: { mode: "token", token: "replace-me" },
},
}

dangerouslyDisableDeviceAuth deaktiviert die Identitätsprüfung komplett und ist ein erhebliches Sicherheitsrisiko. Mache dies nach der Nutzung sofort rückgängig.

Siehe Tailscale für die HTTPS-Einrichtung.

Das Gateway liefert statische Dateien aus dist/control-ui aus. Erstelle diese mit:

Terminal-Fenster
pnpm ui:build # auto-installs UI deps on first run

Optionaler absoluter Basis-Pfad (für feste Asset-URLs):

Terminal-Fenster
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build

Für die lokale Entwicklung (separater Dev-Server):

Terminal-Fenster
pnpm ui:dev # auto-installs UI deps on first run

Verbinde die UI dann mit deiner Gateway WS-URL (z. B. ws://127.0.0.1:18789).

Das Control UI besteht aus statischen Dateien; das WebSocket-Ziel ist konfigurierbar. Das ist praktisch, wenn der Vite-Dev-Server lokal läuft, das Gateway aber woanders.

  1. Starte den UI-Dev-Server: pnpm ui:dev
  2. Öffne eine URL wie:
http://localhost:5173/?gatewayUrl=ws://<gateway-host>:18789

Optionale einmalige Authentifizierung:

http://localhost:5173/?gatewayUrl=wss://<gateway-host>:18789#token=<gateway-token>

Hinweise:

  • gatewayUrl wird im localStorage gespeichert und aus der URL entfernt.
  • token sollte nach Möglichkeit über den URL-Fragment (#token=...) übergeben werden, da Fragmente nicht an den Server gesendet werden.
  • password wird nur im Arbeitsspeicher gehalten.
  • Wenn gatewayUrl gesetzt ist, nutzt die UI keine Fallback-Credentials aus der Config.
  • Nutze wss://, wenn das Gateway hinter TLS (Tailscale Serve, HTTPS-Proxy) läuft.
  • gatewayUrl wird nur im Top-Level-Fenster akzeptiert (kein Embedding), um Clickjacking zu verhindern.
  • Remote-Deployments müssen gateway.controlUi.allowedOrigins explizit setzen.
  • Nutze gateway.controlUi.allowedOrigins: ["*"] niemals außerhalb von kontrollierten Testumgebungen.
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true ist ein gefährlicher Sicherheitsmodus.

Beispiel:

{
gateway: {
controlUi: {
allowedOrigins: ["http://localhost:5173"],
},
},
}

Details zum Fernzugriff: Remote access.

AI Setup Assistant

OpenClaw

OpenClaw Expert

Noch festgefahren?

Wenn diese Seite nicht hilft, frage OpenClaw Expert nach Schritt-fuer-Schritt-Loesungen.