Gateway Service Runbook
Zuletzt aktualisiert: 09.12.2025
Was ist das Gateway?
- Der dauerhaft laufende Prozess, der die Baileys/Telegram-Verbindung und die Control/Event-Ebene verwaltet.
- Ersetzt den alten
gateway-Befehl. CLI-Einstiegspunkt:openclaw gateway. - Läuft bis zum Stoppen; beendet sich mit Fehlercode bei fatalen Fehlern, damit der Supervisor neu startet.
Lokal starten
openclaw gateway --port 18789
# für vollständige Debug/Trace-Logs in stdio:
openclaw gateway --port 18789 --verbose
# wenn der Port belegt ist, Listener beenden und dann starten:
openclaw gateway --force
# Dev-Loop (Auto-Reload bei TS-Änderungen):
pnpm gateway:watch
- Config Hot Reload überwacht
~/.openclaw/openclaw.json(oderOPENCLAW_CONFIG_PATH).- Standardmodus:
gateway.reload.mode="hybrid"(sichere Änderungen hot-applyen, bei kritischen neu starten). - Hot Reload nutzt In-Process-Restart via SIGUSR1 wenn nötig.
- Deaktivieren mit
gateway.reload.mode="off".
- Standardmodus:
- Bindet WebSocket Control Plane an
127.0.0.1:<port>(Standard 18789). - Der gleiche Port bedient auch HTTP (Control UI, Hooks, A2UI). Single-Port-Multiplex.
- OpenAI Chat Completions (HTTP):
/v1/chat/completions. - OpenResponses (HTTP):
/v1/responses. - Tools Invoke (HTTP):
/tools/invoke.
- OpenAI Chat Completions (HTTP):
- Startet standardmäßig einen Canvas-Dateiserver auf
canvasHost.port(Standard18793), derhttp://<gateway-host>:18793/__openclaw__/canvas/aus~/.openclaw/workspace/canvasbereitstellt. Deaktivieren mitcanvasHost.enabled=falseoderOPENCLAW_SKIP_CANVAS_HOST=1. - Loggt nach stdout; nutze launchd/systemd um den Dienst am Leben zu halten und Logs zu rotieren.
- Mit
--verbosewerden Debug-Logs (Handshakes, req/res, Events) aus der Log-Datei auch in stdio gespiegelt — nützlich beim Troubleshooting. --forcenutztlsofum Listener auf dem gewählten Port zu finden, sendet SIGTERM, loggt was beendet wurde, und startet dann das Gateway (schlägt fehl wennlsoffehlt).- Wenn du unter einem Supervisor läufst (launchd/systemd/Mac-App Child-Process-Modus), sendet ein Stop/Restart typischerweise SIGTERM; ältere Builds zeigen das als
pnpmELIFECYCLEExit-Code 143 (SIGTERM), was ein normales Herunterfahren ist, kein Crash. - SIGUSR1 löst einen In-Process-Restart aus wenn autorisiert (Gateway Tool/Config Apply/Update, oder aktiviere
commands.restartfür manuelle Restarts). - Gateway-Auth ist standardmäßig erforderlich: setze
gateway.auth.token(oderOPENCLAW_GATEWAY_TOKEN) odergateway.auth.password. Clients müssenconnect.params.auth.token/passwordsenden, außer bei Tailscale Serve Identity. - Der Wizard generiert jetzt standardmäßig einen Token, auch auf Loopback.
- Port-Priorität:
--port>OPENCLAW_GATEWAY_PORT>gateway.port> Standard18789.
Remote-Zugriff
- Tailscale/VPN bevorzugt; ansonsten SSH-Tunnel:
ssh -N -L 18789:127.0.0.1:18789 user@host - Clients verbinden sich dann über den Tunnel zu
ws://127.0.0.1:18789. - Wenn ein Token konfiguriert ist, müssen Clients ihn in
connect.params.auth.tokenmitschicken, auch über den Tunnel.
Mehrere Gateways (gleicher Host)
Normalerweise nicht nötig: Ein Gateway kann mehrere Messaging-Channels und Agents bedienen. Nutze mehrere Gateways nur für Redundanz oder strikte Isolation (z.B. Rescue-Bot).
Möglich wenn du State + Config isolierst und eindeutige Ports verwendest. Vollständige Anleitung: Mehrere Gateways.
Service-Namen sind profilabhängig:
- macOS:
bot.molt.<profile>(Legacycom.openclaw.*kann noch existieren) - Linux:
openclaw-gateway-<profile>.service - Windows:
OpenClaw Gateway (<profile>)
Install-Metadaten sind in der Service-Config eingebettet:
OPENCLAW_SERVICE_MARKER=openclawOPENCLAW_SERVICE_KIND=gatewayOPENCLAW_SERVICE_VERSION=<version>
Rescue-Bot-Pattern: Halte ein zweites Gateway isoliert mit eigenem Profil, State-Verzeichnis, Workspace und Port-Abstand. Vollständige Anleitung: Rescue-Bot-Guide.
Dev-Profil (--dev)
Schneller Weg: Starte eine vollständig isolierte Dev-Instanz (Config/State/Workspace) ohne dein primäres Setup zu berühren.
openclaw --dev setup
openclaw --dev gateway --allow-unconfigured
# dann die Dev-Instanz ansprechen:
openclaw --dev status
openclaw --dev health
Standardwerte (können via env/flags/config überschrieben werden):
OPENCLAW_STATE_DIR=~/.openclaw-devOPENCLAW_CONFIG_PATH=~/.openclaw-dev/openclaw.jsonOPENCLAW_GATEWAY_PORT=19001(Gateway WS + HTTP)- Browser Control Service Port =
19003(abgeleitet:gateway.port+2, nur Loopback) canvasHost.port=19005(abgeleitet:gateway.port+4)agents.defaults.workspacewird standardmäßig~/.openclaw/workspace-devwenn dusetup/onboardunter--devausführst.
Abgeleitete Ports (Faustregeln):
- Basis-Port =
gateway.port(oderOPENCLAW_GATEWAY_PORT/--port) - Browser Control Service Port = Basis + 2 (nur Loopback)
canvasHost.port = Basis + 4(oderOPENCLAW_CANVAS_HOST_PORT/ Config-Override)- Browser-Profil CDP-Ports werden automatisch von
browser.controlPort + 9 .. + 108zugewiesen (pro Profil persistiert).
Checkliste pro Instanz:
- eindeutiger
gateway.port - eindeutiger
OPENCLAW_CONFIG_PATH - eindeutiger
OPENCLAW_STATE_DIR - eindeutiger
agents.defaults.workspace - separate WhatsApp-Nummern (wenn WA genutzt wird)
Service-Installation pro Profil:
openclaw --profile main gateway install
openclaw --profile rescue gateway install
Beispiel:
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json OPENCLAW_STATE_DIR=~/.openclaw-a openclaw gateway --port 19001
OPENCLAW_CONFIG_PATH=~/.openclaw/b.json OPENCLAW_STATE_DIR=~/.openclaw-b openclaw gateway --port 19002
Protokoll (Operator-Sicht)
- Vollständige Docs: Gateway-Protokoll und Bridge-Protokoll (Legacy).
- Pflicht-Frame vom Client zuerst:
req {type:"req", id, method:"connect", params:{minProtocol,maxProtocol,client:{id,displayName?,version,platform,deviceFamily?,modelIdentifier?,mode,instanceId?}, caps, auth?, locale?, userAgent? } }. - Gateway antwortet mit
res {type:"res", id, ok:true, payload:hello-ok }(oderok:falsemit Fehler, dann schließt es). - Nach dem Handshake:
- Requests:
{type:"req", id, method, params}→{type:"res", id, ok, payload|error} - Events:
{type:"event", event, payload, seq?, stateVersion?}
- Requests:
- Strukturierte Presence-Einträge:
{host, ip, version, platform?, deviceFamily?, modelIdentifier?, mode, lastInputSeconds?, ts, reason?, tags?[], instanceId? }(für WS-Clients kommtinstanceIdvonconnect.client.instanceId). agent-Responses sind zweistufig: erstresAck{runId,status:"accepted"}, dann ein finalesres{runId,status:"ok"|"error",summary}nach Abschluss des Runs; gestreamte Ausgabe kommt alsevent:"agent".
Methoden (initiales Set)
health— vollständiger Health-Snapshot (gleiche Form wieopenclaw health --json).status— kurze Zusammenfassung.system-presence— aktuelle Presence-Liste.system-event— Presence/System-Notiz posten (strukturiert).send— Nachricht über den/die aktiven Channel(s) senden.agent— Agent-Turn ausführen (streamt Events zurück auf derselben Verbindung).node.list— gepaarte + aktuell verbundene Nodes auflisten (enthältcaps,deviceFamily,modelIdentifier,paired,connectedund beworbenecommands).node.describe— Node beschreiben (Capabilities + unterstütztenode.invoke-Befehle; funktioniert für gepaarte Nodes und aktuell verbundene ungepaarte Nodes).node.invoke— Befehl auf einem Node ausführen (z.B.canvas.*,camera.*).node.pair.*— Pairing-Lifecycle (request,list,approve,reject,verify).
Siehe auch: Presence für wie Presence erzeugt/dedupliziert wird und warum eine stabile client.instanceId wichtig ist.
Events
agent— gestreamte Tool/Output-Events vom Agent-Run (seq-getaggt).presence— Presence-Updates (Deltas mit stateVersion) an alle verbundenen Clients gepusht.tick— periodischer Keepalive/No-Op um Liveness zu bestätigen.shutdown— Gateway beendet sich; Payload enthältreasonund optionalesrestartExpectedMs. Clients sollten reconnecten.
WebChat-Integration
- WebChat ist eine native SwiftUI-UI, die direkt mit dem Gateway WebSocket für History, Sends, Abort und Events kommuniziert.
- Remote-Nutzung geht durch denselben SSH/Tailscale-Tunnel; wenn ein Gateway-Token konfiguriert ist, schickt der Client ihn beim
connectmit. - Die macOS-App verbindet sich über einen einzelnen WS (geteilte Verbindung); sie hydratisiert Presence aus dem initialen Snapshot und lauscht auf
presence-Events um die UI zu aktualisieren.
Typing und Validierung
- Der Server validiert jeden eingehenden Frame mit AJV gegen JSON Schema, das aus den Protokoll-Definitionen generiert wird.
- Clients (TS/Swift) konsumieren generierte Types (TS direkt; Swift via den Generator des Repos).
- Protokoll-Definitionen sind die Source of Truth; Schema/Models neu generieren mit:
pnpm protocol:genpnpm protocol:gen:swift
Connection Snapshot
hello-okenthält einensnapshotmitpresence,health,stateVersionunduptimeMspluspolicy {maxPayload,maxBufferedBytes,tickIntervalMs}, damit Clients sofort rendern können ohne extra Requests.health/system-presencebleiben für manuelles Refresh verfügbar, sind aber beim Connect nicht erforderlich.
Fehlercodes (res.error-Form)
- Fehler nutzen
{ code, message, details?, retryable?, retryAfterMs? }. - Standard-Codes:
NOT_LINKED— WhatsApp nicht authentifiziert.AGENT_TIMEOUT— Agent hat nicht innerhalb der konfigurierten Deadline geantwortet.INVALID_REQUEST— Schema/Param-Validierung fehlgeschlagen.UNAVAILABLE— Gateway fährt herunter oder eine Dependency ist nicht verfügbar.
Keepalive-Verhalten
tick-Events (oder WS ping/pong) werden periodisch gesendet, damit Clients wissen, dass das Gateway lebt, auch wenn kein Traffic stattfindet.- Send/Agent-Acknowledgements bleiben separate Responses; überlade Ticks nicht für Sends.
Replay / Lücken
- Events werden nicht replayed. Clients erkennen seq-Lücken und sollten refreshen (
health+system-presence) bevor sie fortfahren. WebChat und macOS-Clients machen jetzt Auto-Refresh bei Lücken.
Supervision (macOS-Beispiel)
- Nutze launchd um den Service am Leben zu halten:
- Program: Pfad zu
openclaw - Arguments:
gateway - KeepAlive: true
- StandardOut/Err: Dateipfade oder
syslog
- Program: Pfad zu
- Bei Fehlern startet launchd neu; fatale Fehlkonfiguration sollte weiter exiten, damit der Operator es bemerkt.
- LaunchAgents sind pro User und erfordern eine eingeloggte Session; für Headless-Setups nutze einen eigenen LaunchDaemon (nicht mitgeliefert).
openclaw gateway installschreibt~/Library/LaunchAgents/bot.molt.gateway.plist(oderbot.molt.<profile>.plist; Legacycom.openclaw.*wird aufgeräumt).openclaw doctorprüft die LaunchAgent-Config und kann sie auf aktuelle Defaults aktualisieren.
Gateway Service Management (CLI)
Nutze die Gateway CLI für install/start/stop/restart/status:
openclaw gateway status
openclaw gateway install
openclaw gateway stop
openclaw gateway restart
openclaw logs --follow
Hinweise:
gateway statusprobt das Gateway RPC standardmäßig mit dem aufgelösten Port/Config des Services (überschreiben mit--url).gateway status --deepfügt System-Level-Scans hinzu (LaunchDaemons/System Units).gateway status --no-probeüberspringt den RPC-Probe (nützlich wenn Networking down ist).gateway status --jsonist stabil für Scripts.gateway statusmeldet Supervisor Runtime (launchd/systemd läuft) separat von RPC Reachability (WS Connect + Status RPC).gateway statusgibt Config-Pfad + Probe-Target aus um “localhost vs LAN bind”-Verwirrung und Profil-Mismatches zu vermeiden.gateway statuszeigt die letzte Gateway-Fehlerzeile wenn der Service läuft aber der Port geschlossen ist.logstailt das Gateway-Datei-Log via RPC (kein manuellestail/grepnötig).- Wenn andere Gateway-ähnliche Services erkannt werden, warnt die CLI, außer es sind OpenClaw-Profil-Services.
Wir empfehlen weiterhin ein Gateway pro Maschine für die meisten Setups; nutze isolierte Profile/Ports für Redundanz oder einen Rescue-Bot. Siehe Mehrere Gateways.
- Cleanup:
openclaw gateway uninstall(aktueller Service) undopenclaw doctor(Legacy-Migrationen).
- Cleanup:
gateway installist ein No-Op wenn bereits installiert; nutzeopenclaw gateway install --forcezum Reinstallieren (Profil/Env/Pfad-Änderungen).
Gebündelte Mac-App:
- OpenClaw.app kann ein Node-basiertes Gateway-Relay bündeln und einen pro-User LaunchAgent installieren mit Label
bot.molt.gateway(oderbot.molt.<profile>; Legacycom.openclaw.*-Labels werden sauber entladen). - Zum sauberen Stoppen nutze
openclaw gateway stop(oderlaunchctl bootout gui/$UID/bot.molt.gateway). - Zum Neustarten nutze
openclaw gateway restart(oderlaunchctl kickstart -k gui/$UID/bot.molt.gateway).launchctlfunktioniert nur wenn der LaunchAgent installiert ist; ansonsten nutze zuerstopenclaw gateway install.- Ersetze das Label durch
bot.molt.<profile>wenn du ein benanntes Profil nutzt.
Supervision (systemd User Unit)
OpenClaw installiert standardmäßig einen systemd User Service auf Linux/WSL2. Wir empfehlen User Services für Single-User-Maschinen (einfacheres Env, pro-User Config). Nutze einen System Service für Multi-User oder Always-On-Server (kein Lingering nötig, geteilte Supervision).
openclaw gateway install schreibt die User Unit. openclaw doctor prüft die Unit und kann sie auf die aktuell empfohlenen Defaults aktualisieren.
Erstelle ~/.config/systemd/user/openclaw-gateway[-<profile>].service:
[Unit]
Description=OpenClaw Gateway (profile: <profile>, v<version>)
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/openclaw gateway --port 18789
Restart=always
RestartSec=5
Environment=OPENCLAW_GATEWAY_TOKEN=
WorkingDirectory=/home/youruser
[Install]
WantedBy=default.target
Aktiviere Lingering (erforderlich damit der User Service Logout/Idle überlebt):
sudo loginctl enable-linger youruser
Onboarding führt das auf Linux/WSL2 aus (kann nach sudo fragen; schreibt /var/lib/systemd/linger).
Dann aktiviere den Service:
systemctl --user enable --now openclaw-gateway[-<profile>].service
Alternative (System Service) — für Always-On oder Multi-User-Server kannst du statt einer User Unit eine systemd System Unit installieren (kein Lingering nötig).
Erstelle /etc/systemd/system/openclaw-gateway[-<profile>].service (kopiere die Unit oben, ändere WantedBy=multi-user.target, setze User= + WorkingDirectory=), dann:
sudo systemctl daemon-reload
sudo systemctl enable --now openclaw-gateway[-<profile>].service
Windows (WSL2)
Windows-Installationen sollten WSL2 nutzen und dem Linux systemd-Abschnitt oben folgen.
Betriebsprüfungen
- Liveness: WS öffnen und
req:connectsenden → erwarteresmitpayload.type="hello-ok"(mit Snapshot). - Readiness:
healthaufrufen → erwarteok: trueund einen verlinkten Channel inlinkChannel(wenn zutreffend). - Debug: auf
tick- undpresence-Events subscriben; stelle sicher, dassstatuslinked/auth age zeigt; Presence-Einträge zeigen Gateway-Host und verbundene Clients.
Sicherheitsgarantien
- Gehe standardmäßig von einem Gateway pro Host aus; wenn du mehrere Profile nutzt, isoliere Ports/State und ziele auf die richtige Instanz.
- Kein Fallback zu direkten Baileys-Verbindungen; wenn das Gateway down ist, schlagen Sends schnell fehl.
- Non-Connect First Frames oder malformed JSON werden abgelehnt und der Socket wird geschlossen.
- Graceful Shutdown:
shutdown-Event vor dem Schließen senden; Clients müssen Close + Reconnect handhaben.
CLI-Helfer
openclaw gateway health|status— Health/Status über den Gateway WS anfragen.openclaw message send --target <num> --message "hi" [--media ...]— via Gateway senden (idempotent für WhatsApp).openclaw agent --message "hi" --to <num>— Agent-Turn ausführen (wartet standardmäßig auf Final).openclaw gateway call <method> --params '{"k":"v"}'— Raw Method Invoker zum Debuggen.openclaw gateway stop|restart— den supervisierten Gateway-Service stoppen/neustarten (launchd/systemd).- Gateway-Helfer-Subcommands setzen ein laufendes Gateway auf
--urlvoraus; sie spawnen keins mehr automatisch.
Migrations-Hinweise
- Stelle Nutzung von
openclaw gatewayund dem Legacy TCP Control Port ein. - Aktualisiere Clients auf das WS-Protokoll mit Pflicht-Connect und strukturierter Presence.