Gateway
Gateway-Protokoll
Das Gateway-WS-Protokoll ist die einzige Steuerungsebene + Node-Transport für OpenClaw. Alle Clients (CLI, Web-UI, macOS-App, iOS-/Android-Nodes, headless Nodes) verbinden sich über WebSocket und deklarieren beim Handshake ihre Rolle + ihren Scope.
Transport
- WebSocket, Text-Frames mit JSON-Payloads.
- Der erste Frame muss eine
connect-Anfrage sein. - Pre-Connect-Frames sind auf 64 KiB begrenzt. Nach einem erfolgreichen Handshake sollten Clients
die Grenzwerte
hello-ok.policy.maxPayloadundhello-ok.policy.maxBufferedByteseinhalten. Wenn Diagnosen aktiviert sind, erzeugen übergroße eingehende Frames und langsame ausgehende Pufferpayload.large-Ereignisse, bevor das Gateway den betroffenen Frame schließt oder verwirft. Diese Ereignisse enthalten Größen, Grenzwerte, Oberflächen und sichere Ursachencodes. Sie enthalten nicht den Nachrichtentext, Inhalte von Anhängen, den rohen Frame-Body, Tokens, Cookies oder geheime Werte.
Handshake (connect)
Gateway → Client (Pre-Connect-Challenge):
{
"type": "event",
"event": "connect.challenge",
"payload": { "nonce": "…", "ts": 1737264000000 }
}
Client → Gateway:
{
"type": "req",
"id": "…",
"method": "connect",
"params": {
"minProtocol": 4,
"maxProtocol": 4,
"client": {
"id": "cli",
"version": "1.2.3",
"platform": "macos",
"mode": "operator"
},
"role": "operator",
"scopes": ["operator.read", "operator.write"],
"caps": [],
"commands": [],
"permissions": {},
"auth": { "token": "…" },
"locale": "en-US",
"userAgent": "openclaw-cli/1.2.3",
"device": {
"id": "device_fingerprint",
"publicKey": "…",
"signature": "…",
"signedAt": 1737264000000,
"nonce": "…"
}
}
}
Gateway → Client:
{
"type": "res",
"id": "…",
"ok": true,
"payload": {
"type": "hello-ok",
"protocol": 4,
"server": { "version": "…", "connId": "…" },
"features": { "methods": ["…"], "events": ["…"] },
"snapshot": { "…": "…" },
"auth": {
"role": "operator",
"scopes": ["operator.read", "operator.write"]
},
"policy": {
"maxPayload": 26214400,
"maxBufferedBytes": 52428800,
"tickIntervalMs": 15000
}
}
}
Während das Gateway den Start von Sidecars noch abschließt, kann die connect-Anfrage
einen wiederholbaren UNAVAILABLE-Fehler zurückgeben, bei dem details.reason auf
"startup-sidecars" und retryAfterMs gesetzt ist. Clients sollten diese Antwort
innerhalb ihres gesamten Verbindungsbudgets erneut versuchen, statt sie als endgültigen
Handshake-Fehler anzuzeigen.
server, features, snapshot und policy sind alle durch das Schema erforderlich
(src/gateway/protocol/schema/frames.ts). auth ist ebenfalls erforderlich und meldet
die ausgehandelte Rolle/die ausgehandelten Scopes. pluginSurfaceUrls ist optional und ordnet Plugin-
Oberflächennamen wie canvas scoped gehosteten URLs zu.
Scoped Plugin-Oberflächen-URLs können ablaufen. Nodes können
node.pluginSurface.refresh mit { "surface": "canvas" } aufrufen, um einen frischen
Eintrag in pluginSurfaceUrls zu erhalten. Das experimentelle Refactoring des Canvas-Plugins
unterstützt nicht den veralteten Kompatibilitätspfad canvasHostUrl, canvasCapability oder
node.canvas.capability.refresh; aktuelle native Clients und Gateways müssen Plugin-Oberflächen verwenden.
Wenn kein Geräte-Token ausgegeben wird, meldet hello-ok.auth die ausgehandelten
Berechtigungen ohne Token-Felder:
{
"auth": {
"role": "operator",
"scopes": ["operator.read", "operator.write"]
}
}
Vertrauenswürdige Same-Process-Backend-Clients (client.id: "gateway-client",
client.mode: "backend") dürfen device bei direkten Loopback-Verbindungen weglassen, wenn
sie sich mit dem gemeinsam genutzten Gateway-Token/Passwort authentifizieren. Dieser Pfad ist für
interne RPCs der Steuerungsebene reserviert und verhindert, dass veraltete CLI-/Gerätekopplungs-Baselines
lokale Backend-Arbeit wie Aktualisierungen von Subagent-Sitzungen blockieren. Remote-Clients,
Clients mit Browser-Origin, Node-Clients und explizite Geräte-Token-/Geräteidentitäts-
Clients verwenden weiterhin die normalen Kopplungs- und Scope-Upgrade-Prüfungen.
Wenn ein Geräte-Token ausgegeben wird, enthält hello-ok außerdem:
{
"auth": {
"deviceToken": "…",
"role": "operator",
"scopes": ["operator.read", "operator.write"]
}
}
Während der vertrauenswürdigen Bootstrap-Übergabe kann hello-ok.auth auch zusätzliche
begrenzte Rolleneinträge in deviceTokens enthalten:
{
"auth": {
"deviceToken": "…",
"role": "node",
"scopes": [],
"deviceTokens": [
{
"deviceToken": "…",
"role": "operator",
"scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]
}
]
}
}
Für den integrierten Node-/Operator-Bootstrap-Ablauf bleibt das primäre Node-Token
bei scopes: [], und jedes übergebene Operator-Token bleibt auf die Bootstrap-
Operator-Allowlist begrenzt (operator.approvals, operator.read,
operator.talk.secrets, operator.write). Bootstrap-Scope-Prüfungen bleiben
rollenpräfixiert: Operator-Einträge erfüllen nur Operator-Anfragen, und Nicht-Operator-
Rollen benötigen weiterhin Scopes unter ihrem eigenen Rollenpräfix.
Node-Beispiel
{
"type": "req",
"id": "…",
"method": "connect",
"params": {
"minProtocol": 4,
"maxProtocol": 4,
"client": {
"id": "ios-node",
"version": "1.2.3",
"platform": "ios",
"mode": "node"
},
"role": "node",
"scopes": [],
"caps": ["camera", "canvas", "screen", "location", "voice"],
"commands": ["camera.snap", "canvas.navigate", "screen.record", "location.get"],
"permissions": { "camera.capture": true, "screen.record": false },
"auth": { "token": "…" },
"locale": "en-US",
"userAgent": "openclaw-ios/1.2.3",
"device": {
"id": "device_fingerprint",
"publicKey": "…",
"signature": "…",
"signedAt": 1737264000000,
"nonce": "…"
}
}
}
Framing
- Anfrage:
{type:"req", id, method, params} - Antwort:
{type:"res", id, ok, payload|error} - Ereignis:
{type:"event", event, payload, seq?, stateVersion?}
Methoden mit Seiteneffekten erfordern Idempotenzschlüssel (siehe Schema).
Rollen + Scopes
Das vollständige Operator-Scope-Modell, Prüfungen zum Genehmigungszeitpunkt und die Semantik geteilter Geheimnisse finden Sie unter Operator-Scopes.
Rollen
operator= Client der Steuerungsebene (CLI/UI/Automatisierung).node= Capability-Host (camera/screen/canvas/system.run).
Scopes (Operator)
Häufige Scopes:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config mit includeSecrets: true erfordert operator.talk.secrets
(oder operator.admin).
Vom Plugin registrierte Gateway-RPC-Methoden können ihren eigenen Operator-Scope anfordern, aber
reservierte Kern-Admin-Präfixe (config.*, exec.approvals.*, wizard.*,
update.*) werden immer zu operator.admin aufgelöst.
Der Methoden-Scope ist nur die erste Schranke. Einige Slash-Commands, die über
chat.send erreicht werden, wenden zusätzlich strengere Prüfungen auf Command-Ebene an. Zum Beispiel erfordern persistente
/config set- und /config unset-Schreibvorgänge operator.admin.
node.pair.approve hat zusätzlich zum Basis-Methoden-Scope eine zusätzliche Scope-Prüfung zum Genehmigungszeitpunkt:
- Anfragen ohne Commands:
operator.pairing - Anfragen mit Nicht-Exec-Node-Commands:
operator.pairing+operator.write - Anfragen, die
system.run,system.run.prepareodersystem.whichenthalten:operator.pairing+operator.admin
Caps/Commands/Berechtigungen (Node)
Nodes deklarieren Capability-Claims beim Verbindungsaufbau:
caps: übergeordnete Capability-Kategorien wiecamera,canvas,screen,location,voiceundtalk.commands: Command-Allowlist für Invoke.permissions: granulare Umschalter (z. B.screen.record,camera.capture).
Das Gateway behandelt diese als Claims und erzwingt serverseitige Allowlists.
Präsenz
system-presencegibt Einträge zurück, die nach Geräteidentität geschlüsselt sind.- Präsenzeinträge enthalten
deviceId,rolesundscopes, damit UIs eine einzelne Zeile pro Gerät anzeigen können, selbst wenn es sich sowohl als Operator als auch als Node verbindet. node.listenthält optionale FelderlastSeenAtMsundlastSeenReason. Verbundene Nodes melden ihre aktuelle Verbindungszeit alslastSeenAtMsmit dem Grundconnect; gekoppelte Nodes können auch dauerhafte Hintergrundpräsenz melden, wenn ein vertrauenswürdiges Node-Ereignis ihre Kopplungsmetadaten aktualisiert.
Node-Hintergrund-Alive-Ereignis
Nodes können node.event mit event: "node.presence.alive" aufrufen, um festzuhalten, dass ein gekoppelter Node
während eines Hintergrund-Wake aktiv war, ohne ihn als verbunden zu markieren.
{
"event": "node.presence.alive",
"payloadJSON": "{\"trigger\":\"silent_push\",\"sentAtMs\":1737264000000,\"displayName\":\"Peter's iPhone\",\"version\":\"2026.4.28\",\"platform\":\"iOS 18.4.0\",\"deviceFamily\":\"iPhone\",\"modelIdentifier\":\"iPhone17,1\",\"pushTransport\":\"relay\"}"
}
trigger ist ein geschlossenes Enum: background, silent_push, bg_app_refresh,
significant_location, manual oder connect. Unbekannte Trigger-Strings werden vom
Gateway vor der Persistierung zu background normalisiert. Das Ereignis ist nur für authentifizierte Node-
Gerätesitzungen dauerhaft; gerätelose oder nicht gekoppelte Sitzungen geben handled: false zurück.
Erfolgreiche Gateways geben ein strukturiertes Ergebnis zurück:
{
"ok": true,
"event": "node.presence.alive",
"handled": true,
"reason": "persisted"
}
Ältere Gateways können für node.event weiterhin { "ok": true } zurückgeben; Clients sollten dies als
bestätigten RPC behandeln, nicht als dauerhafte Präsenzpersistierung.
Scoping von Broadcast-Ereignissen
Serverseitig gepushte WebSocket-Broadcast-Ereignisse sind scope-gated, damit Sitzungen mit Pairing-Scope oder nur Node-Sitzungen keine Sitzungsinhalte passiv empfangen.
- Chat-, Agent- und Tool-Ergebnis-Frames (einschließlich gestreamter
agent-Ereignisse und Tool-Call-Ergebnisse) erfordern mindestensoperator.read. Sitzungen ohneoperator.readüberspringen diese Frames vollständig. - Vom Plugin definierte
plugin.*-Broadcasts werden je nach Registrierung durch das Plugin aufoperator.writeoderoperator.adminbeschränkt. - Status- und Transportereignisse (
heartbeat,presence,tick, Connect-/Disconnect-Lebenszyklus usw.) bleiben uneingeschränkt, damit die Transportintegrität für jede authentifizierte Sitzung beobachtbar bleibt. - Unbekannte Broadcast-Ereignisfamilien sind standardmäßig scope-gated (fail-closed), sofern ein registrierter Handler sie nicht ausdrücklich lockert.
Jede Client-Verbindung behält ihre eigene Sequenznummer pro Client, sodass Broadcasts die monotone Reihenfolge auf diesem Socket beibehalten, selbst wenn verschiedene Clients unterschiedliche scope-gefilterte Teilmengen des Ereignisstroms sehen.
Häufige RPC-Methodenfamilien
Die öffentliche WS-Oberfläche ist breiter als die obigen Handshake-/Auth-Beispiele. Dies
ist kein generierter Dump — hello-ok.features.methods ist eine konservative
Discovery-Liste, die aus src/gateway/server-methods-list.ts plus geladenen
Plugin-/Channel-Methodenexporten erstellt wird. Behandeln Sie sie als Feature-Discovery, nicht als vollständige
Aufzählung von src/gateway/server-methods/*.ts.
System und Identität
healthgibt den zwischengespeicherten oder frisch geprüften Gateway-Health-Snapshot zurück.diagnostics.stabilitygibt den aktuellen begrenzten Diagnose-Stabilitätsrekorder zurück. Er speichert betriebliche Metadaten wie Ereignisnamen, Zählwerte, Bytegrößen, Speicherwerte, Queue-/Sitzungsstatus, Channel-/Plugin-Namen und Sitzungs-IDs. Er speichert keinen Chat-Text, Webhook-Bodies, Tool-Ausgaben, rohe Anfrage- oder Antwort-Bodies, Tokens, Cookies oder geheime Werte. Operator-Read-Scope ist erforderlich.statusgibt die Gateway-Zusammenfassung im Stil von/statuszurück; sensible Felder werden nur für Operator-Clients mit Admin-Scope einbezogen.gateway.identity.getgibt die Gateway-Geräteidentität zurück, die von Relay- und Pairing-Flows verwendet wird.system-presencegibt den aktuellen Präsenz-Snapshot für verbundene Operator-/Node-Geräte zurück.system-eventfügt ein Systemereignis an und kann Präsenzkontext aktualisieren/broadcasten.last-heartbeatgibt das zuletzt persistierte Heartbeat-Ereignis zurück.set-heartbeatsschaltet die Heartbeat-Verarbeitung auf dem Gateway um.
Modelle und Nutzung
models.listgibt den zur Laufzeit zugelassenen Modellkatalog zurück. Übergeben Sie{ "view": "configured" }für auswahlgerechte konfigurierte Modelle (agents.defaults.modelszuerst, dannmodels.providers.*.models) oder{ "view": "all" }für den vollständigen Katalog.usage.statusgibt Provider-Nutzungsfenster und Zusammenfassungen des verbleibenden Kontingents zurück.usage.costgibt aggregierte Kostennutzungszusammenfassungen für einen Datumsbereich zurück.doctor.memory.statusgibt die Bereitschaft von Vektorspeicher / zwischengespeicherten Embeddings für den aktiven Standard-Agenten-Arbeitsbereich zurück. Übergeben Sie{ "probe": true }oder{ "deep": true }nur, wenn der Aufrufer ausdrücklich einen Live-Ping an den Embedding-Provider wünscht.doctor.memory.remHarnessgibt eine begrenzte, schreibgeschützte REM-Harness-Vorschau für Remote-Control-Plane-Clients zurück. Sie kann Arbeitsbereichspfade, Speicherausschnitte, gerendertes fundiertes Markdown und Kandidaten für Deep-Promotion enthalten, daher benötigen Aufruferoperator.read.sessions.usagegibt Nutzungszusammenfassungen pro Sitzung zurück.sessions.usage.timeseriesgibt Zeitreihen zur Nutzung für eine Sitzung zurück.sessions.usage.logsgibt Nutzungsprotokolleinträge für eine Sitzung zurück.
Kanäle und Login-Hilfen
channels.statusgibt Statuszusammenfassungen für eingebaute + gebündelte Kanäle/Plugins zurück.channels.logoutmeldet einen bestimmten Kanal/ein bestimmtes Konto ab, sofern der Kanal die Abmeldung unterstützt.web.login.startstartet einen QR-/Web-Login-Ablauf für den aktuellen QR-fähigen Web-Kanal-Provider.web.login.waitwartet, bis dieser QR-/Web-Login-Ablauf abgeschlossen ist, und startet den Kanal bei Erfolg.push.testsendet einen Test-APNs-Push an einen registrierten iOS-Node.voicewake.getgibt die gespeicherten Wake-Word-Auslöser zurück.voicewake.setaktualisiert Wake-Word-Auslöser und sendet die Änderung.
Messaging und Protokolle
sendist der direkte RPC für ausgehende Zustellung für kanal-/konto-/threadbezogene Sends außerhalb des Chat-Runners.logs.tailgibt den konfigurierten Gateway-Dateiprotokoll-Tail mit Cursor-/Limit- und Max-Byte-Steuerung zurück.
Talk und TTS
talk.cataloggibt den schreibgeschützten Talk-Provider-Katalog für Sprache, Streaming-Transkription und Echtzeitstimme zurück. Er enthält Provider-IDs, Labels, konfigurierten Zustand, offengelegte Modell-/Voice-IDs, kanonische Modi, Transporte, Brain-Strategien und Echtzeit-Audio-/Capability-Flags, ohne Provider-Secrets zurückzugeben oder die globale Konfiguration zu verändern.talk.configgibt die effektive Talk-Konfigurationsnutzlast zurück;includeSecretserfordertoperator.talk.secrets(oderoperator.admin).talk.session.createerstellt eine Gateway-eigene Talk-Sitzung fürrealtime/gateway-relay,transcription/gateway-relayoderstt-tts/managed-room.brain: "direct-tools"erfordertoperator.admin.talk.session.joinvalidiert ein Managed-Room-Sitzungstoken, gibt bei Bedarfsession.ready- odersession.replaced-Ereignisse aus und gibt Raum-/Sitzungsmetadaten sowie aktuelle Talk-Ereignisse ohne Klartexttoken oder gespeicherten Token-Hash zurück.talk.session.appendAudiohängt base64-PCM-Eingabeaudio an Gateway-eigene Echtzeit-Relay- und Transkriptionssitzungen an.talk.session.startTurn,talk.session.endTurnundtalk.session.cancelTurnsteuern den Managed-Room-Turn-Lebenszyklus mit Ablehnung veralteter Turns, bevor der Zustand gelöscht wird.talk.session.cancelOutputstoppt die Audioausgabe des Assistenten, vor allem für VAD-gesteuertes Barge-in in Gateway-Relay-Sitzungen.talk.session.submitToolResultschließt einen Provider-Toolaufruf ab, der von einer Gateway-eigenen Echtzeit-Relay-Sitzung ausgegeben wurde.talk.session.closeschließt eine Gateway-eigene Relay-, Transkriptions- oder Managed-Room-Sitzung und gibt terminale Talk-Ereignisse aus.talk.modesetzt/sendert den aktuellen Talk-Moduszustand für WebChat-/Control-UI-Clients.talk.client.createerstellt eine client-eigene Echtzeit-Provider-Sitzung mitwebrtcoderprovider-websocket, während das Gateway Konfiguration, Anmeldedaten, Anweisungen und Tool-Richtlinie besitzt.talk.client.toolCallermöglicht client-eigenen Echtzeittransporten, Provider-Toolaufrufe an die Gateway-Richtlinie weiterzuleiten. Das erste unterstützte Tool istopenclaw_agent_consult; Clients erhalten eine Run-ID und warten auf normale Chat-Lebenszyklusereignisse, bevor sie das providerspezifische Tool-Ergebnis einreichen.talk.eventist der zentrale Talk-Ereigniskanal für Echtzeit, Transkription, STT/TTS, Managed-Room, Telefonie und Meeting-Adapter.talk.speaksynthetisiert Sprache über den aktiven Talk-Sprach-Provider.tts.statusgibt den TTS-aktiviert-Zustand, den aktiven Provider, Fallback-Provider und den Provider-Konfigurationszustand zurück.tts.providersgibt das sichtbare TTS-Provider-Inventar zurück.tts.enableundtts.disableschalten den TTS-Einstellungszustand um.tts.setProvideraktualisiert den bevorzugten TTS-Provider.tts.convertführt eine einmalige Text-zu-Sprache-Konvertierung aus.
Secrets, Konfiguration, Update und Assistent
secrets.reloadlöst aktive SecretRefs erneut auf und tauscht den Laufzeit-Secret-Zustand nur bei vollständigem Erfolg aus.secrets.resolvelöst befehlsbezogene Secret-Zuweisungen für eine bestimmte Befehls-/Zielmenge auf.config.getgibt den aktuellen Konfigurations-Snapshot und Hash zurück.config.setschreibt eine validierte Konfigurationsnutzlast.config.patchführt ein partielles Konfigurationsupdate zusammen.config.applyvalidiert + ersetzt die vollständige Konfigurationsnutzlast.config.schemagibt die Live-Konfigurationsschema-Nutzlast zurück, die von Control UI und CLI-Tools verwendet wird: Schema,uiHints, Version und Generierungsmetadaten, einschließlich Plugin- + Kanalschema-Metadaten, wenn die Laufzeit sie laden kann. Das Schema enthält Feldmetadaten fürtitle/description, die aus denselben Labels und Hilfetexten abgeleitet sind, die von der UI verwendet werden, einschließlich verschachtelter Objekt-, Wildcard-, Array-Element- undanyOf- /oneOf- /allOf-Kompositionszweige, wenn passende Felddokumentation vorhanden ist.config.schema.lookupgibt eine pfadbezogene Lookup-Nutzlast für einen Konfigurationspfad zurück: normalisierter Pfad, ein flacher Schemaknoten, passender Hinweis +hintPathund unmittelbare Zusammenfassungen untergeordneter Elemente für UI-/CLI-Drill-down. Lookup-Schemaknoten behalten die benutzerseitige Dokumentation und gängige Validierungsfelder (title,description,type,enum,const,format,pattern, numerische/String-/Array-/Objektgrenzen und Flags wieadditionalProperties,deprecated,readOnly,writeOnly). Untergeordnete Zusammenfassungen legenkey, normalisiertenpath,type,required,hasChildrensowie den passendenhint/hintPathoffen.update.runführt den Gateway-Update-Ablauf aus und plant einen Neustart nur, wenn das Update selbst erfolgreich war; Aufrufer mit einer Sitzung könnencontinuationMessageeinschließen, damit der Start einen Folge-Agenten-Turn über die Neustart-Fortsetzungswarteschlange fortsetzt. Paketmanager-Updates erzwingen nach dem Pakettausch einen nicht verzögerten Update-Neustart ohne Cooldown, damit der alte Gateway-Prozess nicht weiter Lazy-Loading aus einem ersetztendist-Baum ausführt.update.statusgibt den neuesten zwischengespeicherten Update-Neustart-Sentinel zurück, einschließlich der nach dem Neustart ausgeführten Version, sofern verfügbar.wizard.start,wizard.next,wizard.statusundwizard.cancelstellen den Onboarding-Assistenten über WS RPC bereit.
Agenten- und Arbeitsbereichshilfen
agents.listgibt konfigurierte Agenteneinträge zurück, einschließlich effektivem Modell und Laufzeitmetadaten.agents.create,agents.updateundagents.deleteverwalten Agentendatensätze und Arbeitsbereichsverdrahtung.agents.files.list,agents.files.getundagents.files.setverwalten die Bootstrap-Arbeitsbereichsdateien, die für einen Agenten offengelegt werden.artifacts.list,artifacts.getundartifacts.downloadstellen aus Transkripten abgeleitete Artefaktzusammenfassungen und Downloads für einen explizitensessionKey-,runId- odertaskId-Scope bereit. Run- und Task-Abfragen lösen die besitzende Sitzung serverseitig auf und geben nur Transkriptmedien mit passender Provenienz zurück; unsichere oder lokale URL-Quellen geben nicht unterstützte Downloads zurück, statt serverseitig abgerufen zu werden.environments.listundenvironments.statusstellen schreibgeschützte Gateway-lokale und Node-Umgebungserkennung für SDK-Clients bereit.agent.identity.getgibt die effektive Assistentenidentität für einen Agenten oder eine Sitzung zurück.agent.waitwartet, bis ein Run abgeschlossen ist, und gibt den terminalen Snapshot zurück, sofern verfügbar.
Sitzungssteuerung
sessions.listgibt den aktuellen Sitzungsindex zurück, einschließlichagentRuntime-Metadaten pro Zeile, wenn ein Agenten-Laufzeit-Backend konfiguriert ist.sessions.subscribeundsessions.unsubscribeschalten Sitzungsänderungsereignis-Abonnements für den aktuellen WS-Client um.sessions.messages.subscribeundsessions.messages.unsubscribeschalten Transkript-/Nachrichtenereignis-Abonnements für eine Sitzung um.sessions.previewgibt begrenzte Transkriptvorschauen für bestimmte Sitzungsschlüssel zurück.sessions.describegibt eine Gateway-Sitzungszeile für einen exakten Sitzungsschlüssel zurück.sessions.resolvelöst ein Sitzungsziel auf oder kanonisiert es.sessions.createerstellt einen neuen Sitzungseintrag.sessions.sendsendet eine Nachricht in eine vorhandene Sitzung.sessions.steerist die Unterbrechen-und-Steuern-Variante für eine aktive Sitzung.sessions.abortbricht aktive Arbeit für eine Sitzung ab. Ein Aufrufer kannkeyplus optionalrunIdübergeben oder nurrunIdfür aktive Runs übergeben, die das Gateway zu einer Sitzung auflösen kann.sessions.patchaktualisiert Sitzungsmetadaten/-Overrides und meldet das aufgelöste kanonische Modell sowie die effektiveagentRuntime.sessions.reset,sessions.deleteundsessions.compactführen Sitzungswartung aus.sessions.getgibt die vollständige gespeicherte Sitzungszeile zurück.- Die Chat-Ausführung verwendet weiterhin
chat.history,chat.send,chat.abortundchat.inject.chat.historyist für UI-Clients anzeige-normalisiert: Inline-Direktiv-Tags werden aus sichtbarem Text entfernt, Nur-Text-Toolaufruf-XML-Nutzlasten (einschließlich<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>und abgeschnittener Toolaufruf-Blöcke) und durchgesickerte ASCII-/Vollbreiten-Modellsteuerungstokens werden entfernt, reine Silent-Token-Assistentenzeilen wie exaktesNO_REPLY/no_replywerden ausgelassen, und übergroße Zeilen können durch Platzhalter ersetzt werden.
Gerätekopplung und Gerätetokens
device.pair.listgibt ausstehende und genehmigte gekoppelte Geräte zurück.device.pair.approve,device.pair.rejectunddevice.pair.removeverwalten Gerätekopplungsdatensätze.device.token.rotaterotiert ein gekoppeltes Gerätetoken innerhalb seiner genehmigten Rollen- und Aufrufer-Scope-Grenzen.device.token.revokewiderruft ein gekoppeltes Gerätetoken innerhalb seiner genehmigten Rollen- und Aufrufer-Scope-Grenzen.
Node-Kopplung, Aufruf und ausstehende Arbeit
node.pair.request,node.pair.list,node.pair.approve,node.pair.reject,node.pair.removeundnode.pair.verifydecken Node-Kopplung und Bootstrap-Verifizierung ab.node.listundnode.describegeben den bekannten/verbundenen Node-Zustand zurück.node.renameaktualisiert ein gekoppeltes Node-Label.node.invokeleitet einen Befehl an einen verbundenen Node weiter.node.invoke.resultgibt das Ergebnis für eine Aufrufanforderung zurück.node.eventtransportiert vom Node ausgehende Ereignisse zurück in das Gateway.node.pending.pullundnode.pending.acksind die Warteschlangen-APIs für verbundene Nodes.node.pending.enqueueundnode.pending.drainverwalten dauerhafte ausstehende Arbeit für Offline-/getrennte Nodes.
Genehmigungsfamilien
exec.approval.request,exec.approval.get,exec.approval.listundexec.approval.resolvedecken einmalige Exec-Genehmigungsanfragen sowie das Nachschlagen/Wiedergeben ausstehender Genehmigungen ab.exec.approval.waitDecisionwartet auf eine ausstehende Exec-Genehmigung und gibt die endgültige Entscheidung zurück (odernullbei Zeitüberschreitung).exec.approvals.getundexec.approvals.setverwalten Snapshots der Exec-Genehmigungsrichtlinie des Gateway.exec.approvals.node.getundexec.approvals.node.setverwalten die node-lokale Exec-Genehmigungsrichtlinie über Node-Relay-Befehle.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisionundplugin.approval.resolvedecken Plugin-definierte Genehmigungsabläufe ab.
Automatisierung, Skills und Tools
- Automatisierung:
wakeplant eine sofortige oder beim nächsten Heartbeat erfolgende Wake-Textinjektion;cron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runsverwalten geplante Arbeit. - Skills und Tools:
commands.list,skills.*,tools.catalog,tools.effective,tools.invoke.
Häufige Ereignisfamilien
chat: UI-Chat-Updates wiechat.injectund andere rein transkriptbezogene Chat- Ereignisse.session.messageundsession.tool: Transkript-/Ereignisstream-Updates für eine abonnierte Sitzung.sessions.changed: Sitzungsindex oder Metadaten geändert.presence: Updates des Systempräsenz-Snapshots.tick: periodisches Keepalive-/Liveness-Ereignis.health: Update des Gateway-Health-Snapshots.heartbeat: Update des Heartbeat-Ereignisstreams.cron: Änderungsereignis für Cron-Lauf/-Job.shutdown: Benachrichtigung zum Herunterfahren des Gateway.node.pair.requested/node.pair.resolved: Node-Pairing-Lebenszyklus.node.invoke.request: Broadcast einer Node-Aufrufanfrage.device.pair.requested/device.pair.resolved: Lebenszyklus gekoppelter Geräte.voicewake.changed: Wake-Word-Trigger-Konfiguration geändert.exec.approval.requested/exec.approval.resolved: Exec-Genehmigungs- Lebenszyklus.plugin.approval.requested/plugin.approval.resolved: Plugin-Genehmigungs- Lebenszyklus.
Node-Hilfsmethoden
- Nodes können
skills.binsaufrufen, um die aktuelle Liste der ausführbaren Skill-Dateien für Auto-Allow-Prüfungen abzurufen.
Operator-Hilfsmethoden
- Operatoren können
commands.list(operator.read) aufrufen, um das Laufzeit- Befehlsinventar für einen Agenten abzurufen.agentIdist optional; lassen Sie es weg, um den Standard-Agent-Arbeitsbereich zu lesen.scopesteuert, welche Oberfläche das primärenameadressiert:textgibt das primäre Textbefehlstoken ohne führendes/zurücknativeund der standardmäßigeboth-Pfad geben Provider-bewusste native Namen zurück, wenn verfügbar
textAliasesenthält exakte Slash-Aliasse wie/modelund/m.nativeNameenthält den Provider-bewussten nativen Befehlsnamen, wenn einer vorhanden ist.providerist optional und wirkt sich nur auf native Benennung sowie native Plugin- Befehlsverfügbarkeit aus.includeArgs=falselässt serialisierte Argumentmetadaten in der Antwort weg.
- Operatoren können
tools.catalog(operator.read) aufrufen, um den Laufzeit-Toolkatalog für einen Agenten abzurufen. Die Antwort enthält gruppierte Tools und Herkunftsmetadaten:source:coreoderpluginpluginId: Plugin-Eigentümer, wennsource="plugin"optional: ob ein Plugin-Tool optional ist
- Operatoren können
tools.effective(operator.read) aufrufen, um das zur Laufzeit wirksame Tool- Inventar für eine Sitzung abzurufen.sessionKeyist erforderlich.- Das Gateway leitet vertrauenswürdigen Laufzeitkontext serverseitig aus der Sitzung ab, statt vom Aufrufer bereitgestellten Authentifizierungs- oder Auslieferungskontext zu akzeptieren.
- Die Antwort ist sitzungsbezogen und spiegelt wider, was die aktive Konversation aktuell verwenden kann, einschließlich Kern-, Plugin- und Kanal-Tools.
- Operatoren können
tools.invoke(operator.write) aufrufen, um ein verfügbares Tool über denselben Gateway-Richtlinienpfad wie/tools/invokeaufzurufen.nameist erforderlich.args,sessionKey,agentId,confirmundidempotencyKeysind optional.- Wenn sowohl
sessionKeyals auchagentIdvorhanden sind, muss der aufgelöste Sitzungsagent mitagentIdübereinstimmen. - Die Antwort ist ein SDK-seitiger Umschlag mit
ok,toolName, optionalemoutputund typisiertenerror-Feldern. Genehmigungs- oder Richtlinienablehnungen gebenok:falsein der Nutzlast zurück, statt die Gateway-Toolrichtlinien-Pipeline zu umgehen.
- Operatoren können
skills.status(operator.read) aufrufen, um das sichtbare Skill-Inventar für einen Agenten abzurufen.agentIdist optional; lassen Sie es weg, um den Standard-Agent-Arbeitsbereich zu lesen.- Die Antwort enthält Eignung, fehlende Anforderungen, Konfigurationsprüfungen und bereinigte Installationsoptionen, ohne rohe Geheimwerte offenzulegen.
- Operatoren können
skills.searchundskills.detail(operator.read) für ClawHub-Erkennungsmetadaten aufrufen. - Operatoren können
skills.install(operator.admin) in zwei Modi aufrufen:- ClawHub-Modus:
{ source: "clawhub", slug, version?, force? }installiert einen Skill-Ordner in das Verzeichnisskills/des Standard-Agent-Arbeitsbereichs. - Gateway-Installer-Modus:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }führt eine deklariertemetadata.openclaw.install-Aktion auf dem Gateway-Host aus.
- ClawHub-Modus:
- Operatoren können
skills.update(operator.admin) in zwei Modi aufrufen:- Der ClawHub-Modus aktualisiert einen nachverfolgten Slug oder alle nachverfolgten ClawHub-Installationen im Standard-Agent-Arbeitsbereich.
- Der Konfigurationsmodus patcht
skills.entries.<skillKey>-Werte wieenabled,apiKeyundenv.
models.list-Ansichten
models.list akzeptiert einen optionalen view-Parameter:
- Weggelassen oder
"default": aktuelles Laufzeitverhalten. Wennagents.defaults.modelskonfiguriert ist, ist die Antwort der zulässige Katalog; andernfalls ist die Antwort der vollständige Gateway-Katalog. "configured": Verhalten in Picker-Größe. Wennagents.defaults.modelskonfiguriert ist, hat es weiterhin Vorrang. Andernfalls verwendet die Antwort explizitemodels.providers.*.models-Einträge und fällt nur dann auf den vollständigen Katalog zurück, wenn keine konfigurierten Modellzeilen vorhanden sind."all": vollständiger Gateway-Katalog, wobeiagents.defaults.modelsumgangen wird. Verwenden Sie dies für Diagnose- und Erkennungs-UIs, nicht für normale Modell-Picker.
Exec-Genehmigungen
- Wenn eine Exec-Anfrage eine Genehmigung benötigt, sendet das Gateway
exec.approval.requested. - Operator-Clients lösen sie durch Aufruf von
exec.approval.resolveauf (erfordert den Scopeoperator.approvals). - Für
host=nodemussexec.approval.requestsystemRunPlanenthalten (kanonischeargv/cwd/rawCommand/Sitzungsmetadaten). Anfragen ohnesystemRunPlanwerden abgelehnt. - Nach der Genehmigung verwenden weitergeleitete
node.invoke system.run-Aufrufe diesen kanonischensystemRunPlanals maßgeblichen Befehls-/cwd-/Sitzungskontext. - Wenn ein Aufrufer
command,rawCommand,cwd,agentIdodersessionKeyzwischen Vorbereitung und der endgültig genehmigtensystem.run-Weiterleitung mutiert, lehnt das Gateway den Lauf ab, statt der mutierten Nutzlast zu vertrauen.
Agent-Auslieferungs-Fallback
agent-Anfragen könnendeliver=trueenthalten, um ausgehende Auslieferung anzufordern.bestEffortDeliver=falsebehält striktes Verhalten bei: nicht auflösbare oder nur interne Auslieferungsziele gebenINVALID_REQUESTzurück.bestEffortDeliver=trueerlaubt den Fallback auf reine Sitzungsausführung, wenn keine extern auslieferbare Route aufgelöst werden kann (zum Beispiel interne/Webchat-Sitzungen oder mehrdeutige Mehrkanal-Konfigurationen).
Versionierung
PROTOCOL_VERSIONbefindet sich insrc/gateway/protocol/version.ts.- Clients senden
minProtocol+maxProtocol; der Server lehnt Nichtübereinstimmungen ab. - Schemas + Modelle werden aus TypeBox-Definitionen generiert:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Client-Konstanten
Der Referenzclient in src/gateway/client.ts verwendet diese Standardwerte. Die Werte sind
über Protokoll v4 hinweg stabil und bilden die erwartete Basis für Drittanbieter-Clients.
| Konstante | Standardwert | Quelle |
|---|---|---|
PROTOCOL_VERSION |
4 |
src/gateway/protocol/version.ts |
| Anfrage-Timeout (pro RPC) | 30_000 ms |
src/gateway/client.ts (requestTimeoutMs) |
| Preauth-/Connect-Challenge-Timeout | 15_000 ms |
src/gateway/handshake-timeouts.ts (config/env kann das gekoppelte Server-/Client-Budget erhöhen) |
| Initialer Reconnect-Backoff | 1_000 ms |
src/gateway/client.ts (backoffMs) |
| Maximaler Reconnect-Backoff | 30_000 ms |
src/gateway/client.ts (scheduleReconnect) |
| Fast-Retry-Begrenzung nach Device-Token-Close | 250 ms |
src/gateway/client.ts |
Force-Stop-Kulanz vor terminate() |
250 ms |
FORCE_STOP_TERMINATE_GRACE_MS |
Standard-Timeout von stopAndWait() |
1_000 ms |
STOP_AND_WAIT_TIMEOUT_MS |
Standardmäßiges Tick-Intervall (vor hello-ok) |
30_000 ms |
src/gateway/client.ts |
| Tick-Timeout-Close | Code 4000, wenn Stille tickIntervalMs * 2 überschreitet |
src/gateway/client.ts |
MAX_PAYLOAD_BYTES |
25 * 1024 * 1024 (25 MB) |
src/gateway/server-constants.ts |
Der Server kündigt die wirksamen policy.tickIntervalMs, policy.maxPayload
und policy.maxBufferedBytes in hello-ok an; Clients sollten diese Werte
statt der Vor-Handshake-Standardwerte beachten.
Auth
- Shared-Secret-Gateway-Authentifizierung verwendet je nach konfiguriertem Authentifizierungsmodus
connect.params.auth.tokenoderconnect.params.auth.password. - Identitätstragende Modi wie Tailscale Serve
(
gateway.auth.allowTailscale: true) oder nicht über Loopback laufendesgateway.auth.mode: "trusted-proxy"erfüllen die Authentifizierungsprüfung fürconnectüber Anfrage-Header statt überconnect.params.auth.*. - Private-Ingress
gateway.auth.mode: "none"überspringt die Shared-Secret-Authentifizierung fürconnectvollständig; setzen Sie diesen Modus nicht an öffentlichem/nicht vertrauenswürdigem Ingress ein. - Nach dem Pairing stellt der Gateway ein Gerätetoken aus, das auf die Verbindungsrolle
- Scopes begrenzt ist. Es wird in
hello-ok.auth.deviceTokenzurückgegeben und sollte vom Client für zukünftige Verbindungen dauerhaft gespeichert werden.
- Scopes begrenzt ist. Es wird in
- Clients sollten das primäre
hello-ok.auth.deviceTokennach jeder erfolgreichen Verbindung dauerhaft speichern. - Eine erneute Verbindung mit diesem gespeicherten Gerätetoken sollte auch die gespeicherte genehmigte Scope-Menge für dieses Token wiederverwenden. Dadurch bleibt bereits gewährter Lese-/Probe-/Statuszugriff erhalten, und erneute Verbindungen werden nicht unbemerkt auf einen engeren impliziten Nur-Admin-Scope reduziert.
- Clientseitige Zusammenstellung der Authentifizierung für
connect(selectConnectAuthinsrc/gateway/client.ts):auth.passwordist unabhängig und wird immer weitergeleitet, wenn es gesetzt ist.auth.tokenwird in Prioritätsreihenfolge befüllt: zuerst explizites gemeinsames Token, dann ein explizitesdeviceToken, dann ein gespeichertes Token pro Gerät (indiziert nachdeviceId+role).auth.bootstrapTokenwird nur gesendet, wenn keiner der oben genannten Werte einauth.tokenergeben hat. Ein gemeinsames Token oder ein aufgelöstes Gerätetoken unterdrückt es.- Die automatische Heraufstufung eines gespeicherten Gerätetokens beim einmaligen
AUTH_TOKEN_MISMATCH-Wiederholungsversuch ist auf vertrauenswürdige Endpunkte beschränkt — Loopback oderwss://mit angeheftetemtlsFingerprint. Öffentlicheswss://ohne Pinning qualifiziert sich nicht.
- Zusätzliche Einträge in
hello-ok.auth.deviceTokenssind Bootstrap-Übergabetokens. Speichern Sie sie nur dauerhaft, wenn die Verbindung Bootstrap-Authentifizierung über einen vertrauenswürdigen Transport wiewss://oder Loopback/lokales Pairing verwendet hat. - Wenn ein Client ein explizites
deviceTokenoder explizitescopesbereitstellt, bleibt diese vom Aufrufer angeforderte Scope-Menge maßgeblich; zwischengespeicherte Scopes werden nur wiederverwendet, wenn der Client das gespeicherte Token pro Gerät wiederverwendet. - Gerätetokens können über
device.token.rotateunddevice.token.revokerotiert/widerrufen werden (erfordert Scopeoperator.pairing). device.token.rotategibt Rotationsmetadaten zurück. Es gibt das Ersatz-Bearer-Token nur bei Aufrufen desselben Geräts aus, die bereits mit diesem Gerätetoken authentifiziert sind, damit reine Token-Clients ihren Ersatz vor einer erneuten Verbindung dauerhaft speichern können. Shared-/Admin-Rotationen geben das Bearer-Token nicht aus.- Token-Ausstellung, -Rotation und -Widerruf bleiben auf die genehmigte Rollenmenge beschränkt, die im Pairing-Eintrag dieses Geräts aufgezeichnet ist; Token-Mutationen können keine Geräterolle erweitern oder als Ziel wählen, die durch die Pairing-Genehmigung nie gewährt wurde.
- Bei Token-Sitzungen gekoppelter Geräte ist die Geräteverwaltung selbstbegrenzt, es sei denn,
der Aufrufer hat zusätzlich
operator.admin: Nicht-Admin-Aufrufer können nur ihren eigenen Geräteeintrag entfernen/widerrufen/rotieren. device.token.rotateunddevice.token.revokeprüfen außerdem die Scope-Menge des Ziel-Operator-Tokens gegen die aktuellen Sitzungsscopes des Aufrufers. Nicht-Admin-Aufrufer können kein umfassenderes Operator-Token rotieren oder widerrufen, als sie bereits besitzen.- Authentifizierungsfehler enthalten
error.details.codesowie Hinweise zur Wiederherstellung:error.details.canRetryWithDeviceToken(boolean)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- Clientverhalten bei
AUTH_TOKEN_MISMATCH:- Vertrauenswürdige Clients können einen begrenzten Wiederholungsversuch mit einem zwischengespeicherten Token pro Gerät ausführen.
- Wenn dieser Wiederholungsversuch fehlschlägt, sollten Clients automatische Wiederverbindungsschleifen beenden und Hinweise für Operator-Maßnahmen anzeigen.
Geräteidentität + Pairing
- Nodes sollten eine stabile Geräteidentität (
device.id) enthalten, die aus einem Schlüsselpaar-Fingerprint abgeleitet ist. - Gateways stellen Tokens pro Gerät + Rolle aus.
- Pairing-Genehmigungen sind für neue Geräte-IDs erforderlich, sofern die lokale automatische Genehmigung nicht aktiviert ist.
- Die automatische Pairing-Genehmigung ist auf direkte lokale Loopback-Verbindungen ausgerichtet.
- OpenClaw hat außerdem einen engen backend-/containerlokalen Selbstverbindungspfad für vertrauenswürdige Shared-Secret-Hilfsabläufe.
- Tailnet- oder LAN-Verbindungen desselben Hosts werden für das Pairing weiterhin als remote behandelt und erfordern Genehmigung.
- WS-Clients enthalten während
connectnormalerweise einedevice-Identität (Operator + Node). Die einzigen gerätelosen Operator-Ausnahmen sind explizite Vertrauenspfade:gateway.controlUi.allowInsecureAuth=truefür localhost-only unsichere HTTP-Kompatibilität.- erfolgreiche Operator-Control-UI-Authentifizierung mit
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(Notfalloption, erhebliche Sicherheitsabsenkung).- direkte Loopback-
gateway-client-Backend-RPCs, die mit dem gemeinsamen Gateway-Token/-Passwort authentifiziert sind.
- Alle Verbindungen müssen die vom Server bereitgestellte Nonce
connect.challengesignieren.
Migrationsdiagnosen für Geräteauthentifizierung
Für Legacy-Clients, die noch das Signierverhalten vor der Challenge verwenden, gibt connect jetzt
DEVICE_AUTH_*-Detailcodes unter error.details.code mit einem stabilen error.details.reason zurück.
Häufige Migrationsfehler:
| Meldung | details.code | details.reason | Bedeutung |
|---|---|---|---|
device nonce required |
DEVICE_AUTH_NONCE_REQUIRED |
device-nonce-missing |
Client hat device.nonce ausgelassen (oder leer gesendet). |
device nonce mismatch |
DEVICE_AUTH_NONCE_MISMATCH |
device-nonce-mismatch |
Client hat mit einer veralteten/falschen Nonce signiert. |
device signature invalid |
DEVICE_AUTH_SIGNATURE_INVALID |
device-signature |
Signatur-Payload entspricht nicht dem v2-Payload. |
device signature expired |
DEVICE_AUTH_SIGNATURE_EXPIRED |
device-signature-stale |
Signierter Zeitstempel liegt außerhalb der zulässigen Abweichung. |
device identity mismatch |
DEVICE_AUTH_DEVICE_ID_MISMATCH |
device-id-mismatch |
device.id stimmt nicht mit dem Public-Key-Fingerprint überein. |
device public key invalid |
DEVICE_AUTH_PUBLIC_KEY_INVALID |
device-public-key |
Public-Key-Format/Kanonisierung fehlgeschlagen. |
Migrationsziel:
- Warten Sie immer auf
connect.challenge. - Signieren Sie den v2-Payload, der die Server-Nonce enthält.
- Senden Sie dieselbe Nonce in
connect.params.device.nonce. - Bevorzugter Signatur-Payload ist
v3, der zusätzlich zu den Feldern für Gerät/Client/Rolle/Scopes/Token/NonceplatformunddeviceFamilybindet. - Legacy-
v2-Signaturen werden aus Kompatibilitätsgründen weiterhin akzeptiert, aber das Metadaten-Pinning gekoppelter Geräte steuert weiterhin die Befehlsrichtlinie bei erneuter Verbindung.
TLS + Pinning
- TLS wird für WS-Verbindungen unterstützt.
- Clients können optional den Gateway-Zertifikat-Fingerprint anheften (siehe
gateway.tls- Konfiguration plusgateway.remote.tlsFingerprintoder CLI--tls-fingerprint).
Scope
Dieses Protokoll stellt die vollständige Gateway-API bereit (Status, Kanäle, Modelle, Chat,
Agent, Sitzungen, Nodes, Genehmigungen usw.). Die genaue Oberfläche wird durch die
TypeBox-Schemas in src/gateway/protocol/schema.ts definiert.