Protocolo do Gateway (WebSocket)
O protocolo WS do Gateway é o plano de controle único + transporte de nó do OpenClaw. Todos os clientes (CLI, UI web, app macOS, nós iOS/Android, nós headless) se conectam por WebSocket e declaram seu papel + escopo no momento do handshake.Transporte
- WebSocket, frames de texto com payloads JSON.
- O primeiro frame deve ser uma solicitação
connect.
Handshake (connect)
Gateway → Cliente (desafio pré-conexão):
hello-ok também inclui:
hello-ok.auth também pode incluir entradas adicionais
de papel limitado em deviceTokens:
scopes: [] e qualquer token de operador transferido continua limitado à allowlist
de operador do bootstrap (operator.approvals, operator.read,
operator.talk.secrets, operator.write). As verificações de escopo do bootstrap permanecem
com prefixo de papel: entradas de operador só satisfazem solicitações de operador, e papéis que não sejam de operador
ainda precisam de escopos sob o prefixo do próprio papel.
Exemplo de nó
Enquadramento
- Solicitação:
{type:"req", id, method, params} - Resposta:
{type:"res", id, ok, payload|error} - Evento:
{type:"event", event, payload, seq?, stateVersion?}
Papéis + escopos
Papéis
operator= cliente do plano de controle (CLI/UI/automação).node= host de capacidades (camera/screen/canvas/system.run).
Escopos (operator)
Escopos comuns:operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config com includeSecrets: true requer operator.talk.secrets
(ou operator.admin).
Métodos RPC do gateway registrados por plugin podem solicitar seu próprio escopo de operator, mas
prefixos administrativos centrais reservados (config.*, exec.approvals.*, wizard.*,
update.*) sempre são resolvidos para operator.admin.
O escopo do método é apenas a primeira barreira. Alguns comandos de barra alcançados por
chat.send aplicam verificações mais rígidas no nível do comando além disso. Por exemplo, gravações persistentes de
/config set e /config unset exigem operator.admin.
node.pair.approve também tem uma verificação extra de escopo no momento da aprovação além do
escopo base do método:
- solicitações sem comando:
operator.pairing - solicitações com comandos de nó que não sejam exec:
operator.pairing+operator.write - solicitações que incluem
system.run,system.run.prepareousystem.which:operator.pairing+operator.admin
Caps/commands/permissions (node)
Nós declaram reivindicações de capacidade no momento da conexão:caps: categorias de capacidade de alto nível.commands: allowlist de comandos para invoke.permissions: alternâncias granulares (por exemploscreen.record,camera.capture).
Presença
system-presenceretorna entradas indexadas pela identidade do dispositivo.- Entradas de presença incluem
deviceId,rolesescopes, para que UIs possam mostrar uma única linha por dispositivo mesmo quando ele se conecta tanto como operator quanto como node.
Famílias comuns de métodos RPC
Esta página não é um dump completo gerado, mas a superfície WS pública é mais ampla do que os exemplos de handshake/autenticação acima. Estas são as principais famílias de métodos que o Gateway expõe hoje.hello-ok.features.methods é uma lista conservadora de descoberta construída a partir de
src/gateway/server-methods-list.ts mais exportações de métodos de plugin/canal carregados.
Trate isso como descoberta de recursos, não como um dump gerado de todos os helpers chamáveis
implementados em src/gateway/server-methods/*.ts.
Sistema e identidade
healthretorna o snapshot de integridade do gateway em cache ou recém-sondado.statusretorna o resumo do gateway no estilo de/status; campos sensíveis são incluídos somente para clientes operator com escopo de admin.gateway.identity.getretorna a identidade do dispositivo do gateway usada por fluxos de relay e pareamento.system-presenceretorna o snapshot de presença atual para dispositivos operator/node conectados.system-eventacrescenta um evento do sistema e pode atualizar/transmitir contexto de presença.last-heartbeatretorna o evento de heartbeat persistido mais recente.set-heartbeatsativa/desativa o processamento de heartbeat no gateway.
Modelos e uso
models.listretorna o catálogo de modelos permitido em runtime.usage.statusretorna janelas de uso do provedor/resumos de cota restante.usage.costretorna resumos agregados de uso de custo para um intervalo de datas.doctor.memory.statusretorna prontidão de memória vetorial / embedding para o workspace ativo do agente padrão.sessions.usageretorna resumos de uso por sessão.sessions.usage.timeseriesretorna séries temporais de uso para uma sessão.sessions.usage.logsretorna entradas de log de uso para uma sessão.
Canais e helpers de login
channels.statusretorna resumos de status de canal/plugin integrados + empacotados.channels.logoutfaz logout de um canal/conta específico onde o canal oferece suporte a logout.web.login.startinicia um fluxo de login QR/web para o provedor de canal web atual com suporte a QR.web.login.waitaguarda esse fluxo de login QR/web concluir e inicia o canal em caso de sucesso.push.testenvia um push APNs de teste para um nó iOS registrado.voicewake.getretorna os gatilhos de wake-word armazenados.voicewake.setatualiza os gatilhos de wake-word e transmite a alteração.
Mensagens e logs
sendé o RPC direto de entrega de saída para envios direcionados por canal/conta/thread fora do executor de chat.logs.tailretorna o tail do log de arquivo configurado do gateway com cursor/limite e controles de bytes máximos.
Talk e TTS
talk.configretorna o payload efetivo de configuração do Talk;includeSecretsrequeroperator.talk.secrets(ouoperator.admin).talk.modedefine/transmite o estado atual do modo Talk para clientes WebChat/UI de controle.talk.speaksintetiza fala pelo provedor de fala Talk ativo.tts.statusretorna estado de TTS ativado, provedor ativo, provedores de fallback e estado de configuração do provedor.tts.providersretorna o inventário visível de provedores de TTS.tts.enableetts.disablealternam o estado das preferências de TTS.tts.setProvideratualiza o provedor preferido de TTS.tts.convertexecuta uma conversão pontual de texto para fala.
Segredos, configuração, update e assistente
secrets.reloadresolve novamente SecretRefs ativas e troca o estado de segredos em runtime somente com sucesso total.secrets.resolveresolve atribuições de segredos para comandos-alvo para um conjunto específico de comando/alvo.config.getretorna o snapshot atual da configuração e o hash.config.setgrava um payload de configuração validado.config.patchmescla uma atualização parcial da configuração.config.applyvalida + substitui o payload completo da configuração.config.schemaretorna o payload do schema de configuração ativo usado pela UI de controle e ferramentas da CLI: schema,uiHints, versão e metadados de geração, incluindo metadados de schema de plugin + canal quando o runtime consegue carregá-los. O schema inclui metadadostitle/descriptionde campo derivados dos mesmos rótulos e texto de ajuda usados pela UI, incluindo ramos de composição de objeto aninhado, curinga, item de array eanyOf/oneOf/allOfquando existir documentação de campo correspondente.config.schema.lookupretorna um payload de busca com escopo de caminho para um caminho de configuração: caminho normalizado, um nó de schema superficial,hint+hintPathcorrespondentes e resumos imediatos dos filhos para navegação detalhada em UI/CLI.- Nós de schema de lookup mantêm a documentação voltada ao usuário e campos de validação comuns:
title,description,type,enum,const,format,pattern, limites numéricos/de string/de array/de objeto e flags booleanas comoadditionalProperties,deprecated,readOnly,writeOnly. - Resumos dos filhos expõem
key,pathnormalizado,type,required,hasChildren, além dehint/hintPathcorrespondentes.
- Nós de schema de lookup mantêm a documentação voltada ao usuário e campos de validação comuns:
update.runexecuta o fluxo de atualização do gateway e agenda um reinício somente quando a própria atualização foi bem-sucedida.wizard.start,wizard.next,wizard.statusewizard.cancelexpõem o assistente de onboarding via WS RPC.
Famílias principais existentes
Helpers de agente e workspace
agents.listretorna entradas de agentes configurados.agents.create,agents.updateeagents.deletegerenciam registros de agente e vínculo de workspace.agents.files.list,agents.files.geteagents.files.setgerenciam os arquivos bootstrap do workspace expostos para um agente.agent.identity.getretorna a identidade efetiva do assistente para um agente ou sessão.agent.waitaguarda uma execução terminar e retorna o snapshot terminal quando disponível.
Controle de sessão
sessions.listretorna o índice atual de sessões.sessions.subscribeesessions.unsubscribealternam assinaturas de alterações de sessão para o cliente WS atual.sessions.messages.subscribeesessions.messages.unsubscribealternam assinaturas de eventos de transcrição/mensagem para uma sessão.sessions.previewretorna prévias limitadas da transcrição para chaves de sessão específicas.sessions.resolveresolve ou canoniza um alvo de sessão.sessions.createcria uma nova entrada de sessão.sessions.sendenvia uma mensagem para uma sessão existente.sessions.steeré a variante de interromper e redirecionar para uma sessão ativa.sessions.abortaborta trabalho ativo de uma sessão.sessions.patchatualiza metadados/substituições da sessão.sessions.reset,sessions.deleteesessions.compactexecutam manutenção de sessão.sessions.getretorna a linha completa da sessão armazenada.- A execução de chat ainda usa
chat.history,chat.send,chat.abortechat.inject. chat.historyé normalizado para exibição para clientes de UI: tags de diretiva inline são removidas do texto visível, payloads XML de chamada de ferramenta em texto simples (incluindo<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>e blocos truncados de chamada de ferramenta) e tokens de controle vazados do modelo em ASCII/largura total são removidos, linhas puras do assistente com token silencioso, comoNO_REPLY/no_replyexatos, são omitidas, e linhas superdimensionadas podem ser substituídas por placeholders.
Pareamento de dispositivo e tokens de dispositivo
device.pair.listretorna dispositivos pareados pendentes e aprovados.device.pair.approve,device.pair.rejectedevice.pair.removegerenciam registros de pareamento de dispositivo.device.token.rotaterotaciona um token de dispositivo pareado dentro dos limites de papel e escopo aprovados.device.token.revokerevoga um token de dispositivo pareado.
Pareamento de nó, invoke e trabalho pendente
node.pair.request,node.pair.list,node.pair.approve,node.pair.rejectenode.pair.verifycobrem o pareamento de nó e a verificação de bootstrap.node.listenode.describeretornam o estado de nós conhecidos/conectados.node.renameatualiza um rótulo de nó pareado.node.invokeencaminha um comando para um nó conectado.node.invoke.resultretorna o resultado de uma solicitação de invoke.node.eventcarrega eventos originados no nó de volta para o gateway.node.canvas.capability.refreshatualiza tokens de capacidade de canvas com escopo.node.pending.pullenode.pending.acksão as APIs de fila de nós conectados.node.pending.enqueueenode.pending.draingerenciam trabalho pendente durável para nós offline/desconectados.
Famílias de aprovação
exec.approval.requesteexec.approval.resolvecobrem solicitações pontuais de aprovação de exec.exec.approval.waitDecisionaguarda uma aprovação de exec pendente e retorna a decisão final (ounullem caso de timeout).exec.approvals.geteexec.approvals.setgerenciam snapshots da política de aprovação de exec do gateway.exec.approvals.node.geteexec.approvals.node.setgerenciam política local de aprovação de exec de nó por meio de comandos de relay de nó.plugin.approval.request,plugin.approval.waitDecisioneplugin.approval.resolvecobrem fluxos de aprovação definidos por plugin.
Outras famílias principais
- automação:
wakeagenda uma injeção imediata de texto de wake ou no próximo heartbeatcron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runs
- skills/tools:
skills.*,tools.catalog,tools.effective
Famílias comuns de eventos
chat: atualizações de chat da UI, comochat.injecte outros eventos de chat somente de transcrição.session.messageesession.tool: atualizações de transcrição/fluxo de eventos para uma sessão assinada.sessions.changed: índice de sessão ou metadados alterados.presence: atualizações do snapshot de presença do sistema.tick: evento periódico de keepalive / liveness.health: atualização do snapshot de integridade do gateway.heartbeat: atualização do fluxo de eventos de heartbeat.cron: evento de alteração de execução/job do cron.shutdown: notificação de desligamento do gateway.node.pair.requested/node.pair.resolved: ciclo de vida do pareamento de nó.node.invoke.request: transmissão de solicitação de invoke de nó.device.pair.requested/device.pair.resolved: ciclo de vida do dispositivo pareado.voicewake.changed: configuração do gatilho de wake-word alterada.exec.approval.requested/exec.approval.resolved: ciclo de vida da aprovação de exec.plugin.approval.requested/plugin.approval.resolved: ciclo de vida da aprovação de plugin.
Métodos helper de nó
- Nós podem chamar
skills.binspara buscar a lista atual de executáveis de Skill para verificações automáticas de allow.
Métodos helper de operator
- Operators podem chamar
tools.catalog(operator.read) para buscar o catálogo de ferramentas em runtime de um agente. A resposta inclui ferramentas agrupadas e metadados de proveniência:source:coreoupluginpluginId: proprietário do plugin quandosource="plugin"optional: se uma ferramenta de plugin é opcional
- Operators podem chamar
tools.effective(operator.read) para buscar o inventário efetivo de ferramentas em runtime para uma sessão.sessionKeyé obrigatório.- O gateway deriva o contexto confiável de runtime a partir da sessão no lado do servidor em vez de aceitar contexto de autenticação ou entrega fornecido pelo chamador.
- A resposta tem escopo de sessão e reflete o que a conversa ativa pode usar agora, incluindo ferramentas core, plugin e canal.
- Operators podem chamar
skills.status(operator.read) para buscar o inventário visível de Skills de um agente.agentIdé opcional; omita-o para ler o workspace do agente padrão.- A resposta inclui elegibilidade, requisitos ausentes, verificações de configuração e opções de instalação sanitizadas sem expor valores brutos de segredo.
- Operators podem chamar
skills.searcheskills.detail(operator.read) para metadados de descoberta do ClawHub. - Operators podem chamar
skills.install(operator.admin) em dois modos:- Modo ClawHub:
{ source: "clawhub", slug, version?, force? }instala uma pasta de Skill no diretórioskills/do workspace do agente padrão. - Modo instalador do gateway:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }executa uma ação declaradametadata.openclaw.installno host do gateway.
- Modo ClawHub:
- Operators podem chamar
skills.update(operator.admin) em dois modos:- O modo ClawHub atualiza um slug rastreado ou todas as instalações rastreadas do ClawHub no workspace do agente padrão.
- O modo Config aplica patch em valores
skills.entries.<skillKey>, comoenabled,apiKeyeenv.
Aprovações de exec
- Quando uma solicitação de exec precisa de aprovação, o gateway transmite
exec.approval.requested. - Clientes operator resolvem chamando
exec.approval.resolve(requer escopooperator.approvals). - Para
host=node,exec.approval.requestdeve incluirsystemRunPlan(argv/cwd/rawCommand/metadados de sessão canônicos). Solicitações semsystemRunPlansão rejeitadas. - Após a aprovação, chamadas encaminhadas
node.invoke system.runreutilizam essesystemRunPlancanônico como contexto autoritativo de comando/cwd/sessão. - Se um chamador alterar
command,rawCommand,cwd,agentIdousessionKeyentre o preparo e o encaminhamento final aprovado desystem.run, o gateway rejeitará a execução em vez de confiar no payload alterado.
Fallback de entrega do agente
- Solicitações
agentpodem incluirdeliver=truepara solicitar entrega de saída. bestEffortDeliver=falsemantém comportamento estrito: alvos de entrega não resolvidos ou apenas internos retornamINVALID_REQUEST.bestEffortDeliver=truepermite fallback para execução somente na sessão quando nenhuma rota externa entregável pode ser resolvida (por exemplo sessões internas/webchat ou configurações ambíguas de múltiplos canais).
Versionamento
PROTOCOL_VERSIONestá emsrc/gateway/protocol/schema.ts.- Clientes enviam
minProtocol+maxProtocol; o servidor rejeita incompatibilidades. - Schemas + modelos são gerados a partir de definições TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Autenticação
- A autenticação compartilhada por segredo do gateway usa
connect.params.auth.tokenouconnect.params.auth.password, dependendo do modo de autenticação configurado. - Modos com identidade, como Tailscale Serve
(
gateway.auth.allowTailscale: true) ougateway.auth.mode: "trusted-proxy"sem loopback, satisfazem a verificação de autenticação do connect a partir de cabeçalhos da solicitação em vez deconnect.params.auth.*. gateway.auth.mode: "none"em entrada privada ignora completamente a autenticação compartilhada do connect; não exponha esse modo em entrada pública/não confiável.- Após o pareamento, o Gateway emite um token de dispositivo com escopo para o papel + escopos da conexão. Ele é retornado em
hello-ok.auth.deviceTokene deve ser persistido pelo cliente para futuras conexões. - Clientes devem persistir o
hello-ok.auth.deviceTokenprincipal após qualquer conexão bem-sucedida. - Reconectar com esse token de dispositivo armazenado também deve reutilizar o conjunto de escopos aprovados armazenado para esse token. Isso preserva o acesso de leitura/probe/status que já foi concedido e evita reduzir silenciosamente reconexões para um escopo implícito mais restrito apenas de admin.
- A precedência normal de autenticação do connect é token/senha compartilhado explícito primeiro, depois
deviceTokenexplícito, depois token armazenado por dispositivo, depois token de bootstrap. - Entradas adicionais
hello-ok.auth.deviceTokenssão tokens de handoff de bootstrap. Persista-os apenas quando a conexão tiver usado autenticação de bootstrap em um transporte confiável, comowss://ou loopback/pareamento local. - Se um cliente fornecer um
deviceTokenexplícito ouscopesexplícitos, esse conjunto de escopos solicitado pelo chamador continua sendo autoritativo; escopos em cache só são reutilizados quando o cliente está reutilizando o token armazenado por dispositivo. - Tokens de dispositivo podem ser rotacionados/revogados por
device.token.rotateedevice.token.revoke(requer escopooperator.pairing). - Emissão/rotação de token permanece limitada ao conjunto de papéis aprovados registrado na entrada de pareamento desse dispositivo; rotacionar um token não pode expandir o dispositivo para um papel que a aprovação de pareamento nunca concedeu.
- Para sessões de token de dispositivo pareado, o gerenciamento de dispositivo é autocontido no próprio escopo, a menos que o
chamador também tenha
operator.admin: chamadores sem admin podem remover/revogar/rotacionar apenas sua própria entrada de dispositivo. device.token.rotatetambém verifica o conjunto de escopos de operator solicitado contra os escopos atuais da sessão do chamador. Chamadores sem admin não podem rotacionar um token para um conjunto mais amplo de escopos de operator do que já possuem.- Falhas de autenticação incluem
error.details.codemais dicas de recuperação:error.details.canRetryWithDeviceToken(boolean)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- Comportamento do cliente para
AUTH_TOKEN_MISMATCH:- Clientes confiáveis podem tentar uma nova tentativa limitada com um token em cache por dispositivo.
- Se essa nova tentativa falhar, os clientes devem parar loops automáticos de reconexão e exibir orientação para ação do operador.
Identidade do dispositivo + pareamento
- Nós devem incluir uma identidade de dispositivo estável (
device.id) derivada de uma impressão digital de par de chaves. - Gateways emitem tokens por dispositivo + papel.
- Aprovações de pareamento são necessárias para novos IDs de dispositivo, a menos que a aprovação automática local esteja ativada.
- A aprovação automática de pareamento é centrada em conexões diretas locais por loopback.
- O OpenClaw também tem um caminho estreito de autoconexão backend/container-local para fluxos helper confiáveis de segredo compartilhado.
- Conexões pela tailnet ou LAN no mesmo host ainda são tratadas como remotas para fins de pareamento e exigem aprovação.
- Todos os clientes WS devem incluir identidade
deviceduranteconnect(operator + node). A UI de controle pode omiti-la somente nestes modos:gateway.controlUi.allowInsecureAuth=truepara compatibilidade com HTTP inseguro somente em localhost.- autenticação bem-sucedida de operator Control UI em
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(break-glass, rebaixamento grave de segurança).
- Todas as conexões devem assinar o nonce
connect.challengefornecido pelo servidor.
Diagnósticos de migração de autenticação de dispositivo
Para clientes legados que ainda usam comportamento de assinatura anterior ao desafio,connect agora retorna
códigos de detalhe DEVICE_AUTH_* em error.details.code com um error.details.reason estável.
Falhas comuns de migração:
| Mensagem | details.code | details.reason | Significado |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | O cliente omitiu device.nonce (ou enviou em branco). |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | O cliente assinou com nonce obsoleto/incorreto. |
device signature invalid | DEVICE_AUTH_SIGNATURE_INVALID | device-signature | O payload da assinatura não corresponde ao payload v2. |
device signature expired | DEVICE_AUTH_SIGNATURE_EXPIRED | device-signature-stale | O timestamp assinado está fora do desvio permitido. |
device identity mismatch | DEVICE_AUTH_DEVICE_ID_MISMATCH | device-id-mismatch | device.id não corresponde à impressão digital da chave pública. |
device public key invalid | DEVICE_AUTH_PUBLIC_KEY_INVALID | device-public-key | O formato/canonicalização da chave pública falhou. |
- Sempre espere por
connect.challenge. - Assine o payload v2 que inclui o nonce do servidor.
- Envie o mesmo nonce em
connect.params.device.nonce. - O payload de assinatura preferido é
v3, que vinculaplatformedeviceFamilyalém dos campos device/client/role/scopes/token/nonce. - Assinaturas legadas
v2permanecem aceitas por compatibilidade, mas a fixação de metadados de dispositivo pareado ainda controla a política de comando na reconexão.
TLS + pinning
- TLS é compatível para conexões WS.
- Clientes podem opcionalmente fixar a impressão digital do certificado do gateway (veja
gateway.tlsconfig maisgateway.remote.tlsFingerprintou a CLI--tls-fingerprint).
Escopo
Este protocolo expõe a API completa do gateway (status, canais, modelos, chat, agente, sessões, nós, aprovações etc.). A superfície exata é definida pelos schemas TypeBox emsrc/gateway/protocol/schema.ts.