Plugins (Extensões)¶
Início rápido (novo em plugins?)¶
Um plugin é apenas um pequeno módulo de código que estende o OpenClaw com recursos extras (comandos, ferramentas e RPC do Gateway).
Na maioria das vezes, você usará plugins quando quiser um recurso que ainda não está embutido no OpenClaw principal (ou quando quiser manter recursos opcionais fora da sua instalação principal).
Caminho rápido:
- Veja o que já está carregado:
openclaw plugins list
- Instale um plugin oficial (exemplo: Voice Call):
openclaw plugins install @openclaw/voice-call
- Reinicie o Gateway e depois configure em
plugins.entries.<id>.config.
Veja Voice Call para um exemplo concreto de plugin.
Plugins disponíveis (oficiais)¶
- Microsoft Teams é apenas via plugin a partir de 2026.1.15; instale
@openclaw/msteamsse você usa Teams. - Memory (Core) — plugin de busca de memória empacotado (habilitado por padrão via
plugins.slots.memory) - Memory (LanceDB) — plugin de memória de longo prazo empacotado (auto-recall/capture; defina
plugins.slots.memory = "memory-lancedb") - Voice Call —
@openclaw/voice-call - Zalo Personal —
@openclaw/zalouser - Matrix —
@openclaw/matrix - Nostr —
@openclaw/nostr - Zalo —
@openclaw/zalo - Microsoft Teams —
@openclaw/msteams - Google Antigravity OAuth (autenticação de provedor) — empacotado como
google-antigravity-auth(desabilitado por padrão) - Gemini CLI OAuth (autenticação de provedor) — empacotado como
google-gemini-cli-auth(desabilitado por padrão) - Qwen OAuth (autenticação de provedor) — empacotado como
qwen-portal-auth(desabilitado por padrão) - Copilot Proxy (autenticação de provedor) — ponte local do VS Code Copilot Proxy; distinto do login de dispositivo embutido
github-copilot(empacotado, desabilitado por padrão)
Os plugins do OpenClaw são módulos TypeScript carregados em tempo de execução via jiti. A validação de configuração não executa código do plugin; ela usa o manifesto do plugin e o JSON Schema. Veja Plugin manifest.
Os plugins podem registrar:
- Métodos de RPC do Gateway
- Handlers HTTP do Gateway
- Ferramentas de agente
- Comandos de CLI
- Serviços em segundo plano
- Validação opcional de configuração
- Skills (listando diretórios
skillsno manifesto do plugin) - Comandos de resposta automática (executam sem invocar o agente de IA)
Os plugins rodam no mesmo processo do Gateway, portanto trate-os como código confiável. Guia de criação de ferramentas: Plugin agent tools.
Ajudantes de runtime¶
Os plugins podem acessar ajudantes principais selecionados via api.runtime. Para TTS de telefonia:
const result = await api.runtime.tts.textToSpeechTelephony({
text: "Hello from OpenClaw",
cfg: api.config,
});
Notas:
- Usa a configuração principal
messages.tts(OpenAI ou ElevenLabs). - Retorna buffer de áudio PCM + taxa de amostragem. Os plugins devem reamostrar/codificar para os provedores.
- Edge TTS não é suportado para telefonia.
Descoberta e precedência¶
O OpenClaw varre, em ordem:
- Caminhos de configuração
plugins.load.paths(arquivo ou diretório)
- Extensões do workspace
<workspace>/.openclaw/extensions/*.ts<workspace>/.openclaw/extensions/*/index.ts
- Extensões globais
~/.openclaw/extensions/*.ts~/.openclaw/extensions/*/index.ts
- Extensões empacotadas (enviadas com o OpenClaw, desabilitadas por padrão)
<openclaw>/extensions/*
Plugins empacotados devem ser habilitados explicitamente via plugins.entries.<id>.enabled
ou openclaw plugins enable <id>. Plugins instalados são habilitados por padrão,
mas podem ser desabilitados da mesma forma.
Cada plugin deve incluir um arquivo openclaw.plugin.json em sua raiz. Se um caminho
apontar para um arquivo, a raiz do plugin é o diretório do arquivo e deve conter
o manifesto.
Se vários plugins resolverem para o mesmo id, a primeira correspondência na ordem acima vence e as cópias de menor precedência são ignoradas.
Pacotes de pacotes¶
Um diretório de plugin pode incluir um package.json com openclaw.extensions:
{
"name": "my-pack",
"openclaw": {
"extensions": ["./src/safety.ts", "./src/tools.ts"]
}
}
Cada entrada se torna um plugin. Se o pacote listar várias extensões, o id do plugin
se torna name/<fileBase>.
Se o seu plugin importar dependências npm, instale-as nesse diretório para que
node_modules esteja disponível (npm install / pnpm install).
Metadados do catálogo de canais¶
Plugins de canal podem anunciar metadados de integração inicial via openclaw.channel e
dicas de instalação via openclaw.install. Isso mantém o catálogo principal livre de dados.
Exemplo:
{
"name": "@openclaw/nextcloud-talk",
"openclaw": {
"extensions": ["./index.ts"],
"channel": {
"id": "nextcloud-talk",
"label": "Nextcloud Talk",
"selectionLabel": "Nextcloud Talk (self-hosted)",
"docsPath": "/channels/nextcloud-talk",
"docsLabel": "nextcloud-talk",
"blurb": "Self-hosted chat via Nextcloud Talk webhook bots.",
"order": 65,
"aliases": ["nc-talk", "nc"]
},
"install": {
"npmSpec": "@openclaw/nextcloud-talk",
"localPath": "extensions/nextcloud-talk",
"defaultChoice": "npm"
}
}
}
O OpenClaw também pode mesclar catálogos de canais externos (por exemplo, uma exportação de registro MPM). Coloque um arquivo JSON em um dos seguintes caminhos:
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
Ou aponte OPENCLAW_PLUGIN_CATALOG_PATHS (ou OPENCLAW_MPM_CATALOG_PATHS) para
um ou mais arquivos JSON (delimitados por vírgula/ponto e vírgula/PATH). Cada arquivo deve
conter { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }.
IDs de plugin¶
IDs de plugin padrão:
- Pacotes de pacotes:
package.jsonname - Arquivo standalone: nome base do arquivo (
~/.../voice-call.ts→voice-call)
Se um plugin exportar id, o OpenClaw o usa, mas avisa quando não corresponde ao
id configurado.
Configuração¶
{
plugins: {
enabled: true,
allow: ["voice-call"],
deny: ["untrusted-plugin"],
load: { paths: ["~/Projects/oss/voice-call-extension"] },
entries: {
"voice-call": { enabled: true, config: { provider: "twilio" } },
},
},
}
Campos:
enabled: alternância mestre (padrão: true)allow: lista de permissões (opcional)deny: lista de negação (opcional; a negação vence)load.paths: arquivos/diretórios extras de pluginentries.<id>: alternâncias por plugin + configuração
Alterações de configuração exigem reinício do gateway.
Regras de validação (estritas):
- IDs de plugin desconhecidos em
entries,allow,denyouslotssão erros. - Chaves
channels.<id>desconhecidas são erros, a menos que um manifesto de plugin declare o id do canal. - A configuração do plugin é validada usando o JSON Schema incorporado em
openclaw.plugin.json(configSchema). - Se um plugin estiver desabilitado, sua configuração é preservada e um aviso é emitido.
Slots de plugin (categorias exclusivas)¶
Algumas categorias de plugin são exclusivas (apenas uma ativa por vez). Use
plugins.slots para selecionar qual plugin é dono do slot:
{
plugins: {
slots: {
memory: "memory-core", // or "none" to disable memory plugins
},
},
}
Se vários plugins declararem kind: "memory", apenas o selecionado carrega. Os outros
são desabilitados com diagnósticos.
UI de controle (schema + rótulos)¶
A UI de Controle usa config.schema (JSON Schema + uiHints) para renderizar formulários melhores.
O OpenClaw amplia uiHints em tempo de execução com base nos plugins descobertos:
- Adiciona rótulos por plugin para
plugins.entries.<id>/.enabled/.config - Mescla dicas opcionais de campos de configuração fornecidas pelo plugin em:
plugins.entries.<id>.config.<field>
Se você quiser que os campos de configuração do seu plugin exibam bons rótulos/placeholders
(e marquem segredos como sensíveis), forneça uiHints junto com seu JSON Schema no manifesto do plugin.
Exemplo:
{
"id": "my-plugin",
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {
"apiKey": { "type": "string" },
"region": { "type": "string" }
}
},
"uiHints": {
"apiKey": { "label": "API Key", "sensitive": true },
"region": { "label": "Region", "placeholder": "us-east-1" }
}
}
CLI¶
openclaw plugins list
openclaw plugins info <id>
openclaw plugins install <path> # copy a local file/dir into ~/.openclaw/extensions/<id>
openclaw plugins install ./extensions/voice-call # relative path ok
openclaw plugins install ./plugin.tgz # install from a local tarball
openclaw plugins install ./plugin.zip # install from a local zip
openclaw plugins install -l ./extensions/voice-call # link (no copy) for dev
openclaw plugins install @openclaw/voice-call # install from npm
openclaw plugins update <id>
openclaw plugins update --all
openclaw plugins enable <id>
openclaw plugins disable <id>
openclaw plugins doctor
plugins update funciona apenas para instalações npm rastreadas em plugins.installs.
Os plugins também podem registrar seus próprios comandos de nível superior (exemplo: openclaw voicecall).
API de Plugin (visão geral)¶
Os plugins exportam um de:
- Uma função:
(api) => { ... } - Um objeto:
{ id, name, configSchema, register(api) { ... } }
Hooks de plugin¶
Os plugins podem enviar hooks e registrá-los em tempo de execução. Os plugins podem incluir hooks e registrá-los em tempo de execução. Isso permite que um plugin empacote automação orientada a eventos sem uma instalação separada de pacote de hooks.
Exemplo¶
import { registerPluginHooksFromDir } from "openclaw/plugin-sdk";
export default function register(api) {
registerPluginHooksFromDir(api, "./hooks");
}
Notas:
- Diretórios de hooks seguem a estrutura normal de hooks (
HOOK.md+handler.ts). - As regras de elegibilidade de hooks ainda se aplicam (requisitos de SO/bins/env/config).
- Hooks gerenciados por plugin aparecem em
openclaw hooks listcomplugin:<id>. - Você não pode habilitar/desabilitar hooks gerenciados por plugin via
openclaw hooks; habilite/desabilite o plugin em vez disso.
Plugins de provedor (autenticação de modelo)¶
Os plugins podem registrar fluxos de autenticação de provedor de modelo para que os usuários possam executar OAuth ou configuração de chave de API dentro do OpenClaw (sem scripts externos).
Registre um provedor via api.registerProvider(...). Cada provedor expõe um
ou mais métodos de autenticação (OAuth, chave de API, código de dispositivo etc.). Esses métodos alimentam:
openclaw models auth login --provider <id> [--method <id>]
Exemplo:
api.registerProvider({
id: "acme",
label: "AcmeAI",
auth: [
{
id: "oauth",
label: "OAuth",
kind: "oauth",
run: async (ctx) => {
// Run OAuth flow and return auth profiles.
return {
profiles: [
{
profileId: "acme:default",
credential: {
type: "oauth",
provider: "acme",
access: "...",
refresh: "...",
expires: Date.now() + 3600 * 1000,
},
},
],
defaultModel: "acme/opus-1",
};
},
},
],
});
Notas:
runrecebe umProviderAuthContextcom ajudantesprompter,runtime,openUrleoauth.createVpsAwareHandlers.- Retorne
configPatchquando você precisar adicionar modelos padrão ou configuração do provedor. - Retorne
defaultModelpara que--set-defaultpossa atualizar os padrões do agente.
Registrar um canal de mensagens¶
Os plugins podem registrar plugins de canal que se comportam como canais embutidos
(WhatsApp, Telegram etc.). A configuração do canal fica em channels.<id> e é
validada pelo código do seu plugin de canal.
const myChannel = {
id: "acmechat",
meta: {
id: "acmechat",
label: "AcmeChat",
selectionLabel: "AcmeChat (API)",
docsPath: "/channels/acmechat",
blurb: "demo channel plugin.",
aliases: ["acme"],
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
resolveAccount: (cfg, accountId) =>
cfg.channels?.acmechat?.accounts?.[accountId ?? "default"] ?? {
accountId,
},
},
outbound: {
deliveryMode: "direct",
sendText: async () => ({ ok: true }),
},
};
export default function (api) {
api.registerChannel({ plugin: myChannel });
}
Notas:
- Coloque a configuração em
channels.<id>(não emplugins.entries). meta.labelé usado para rótulos em listas da CLI/UI.meta.aliasesadiciona ids alternativos para normalização e entradas da CLI.meta.preferOverlista ids de canal para pular auto-habilitação quando ambos estiverem configurados.meta.detailLabelemeta.systemImagepermitem que UIs mostrem rótulos/ícones de canal mais ricos.
Escrever um novo canal de mensagens (passo a passo)¶
Use isto quando quiser uma nova superfície de chat (um “canal de mensagens”), não um provedor de modelo.
A documentação de provedores de modelo fica em /providers/*.
- Escolha um id + formato de configuração
- Toda a configuração de canal fica em
channels.<id>. - Prefira
channels.<id>.accounts.<accountId>para configurações multi‑conta.
- Defina os metadados do canal
meta.label,meta.selectionLabel,meta.docsPath,meta.blurbcontrolam listas da CLI/UI.meta.docsPathdeve apontar para uma página de docs como/channels/<id>.meta.preferOverpermite que um plugin substitua outro canal (a auto-habilitação o prefere).meta.detailLabelemeta.systemImagesão usados pelas UIs para texto/ícones de detalhe.
- Implemente os adaptadores obrigatórios
config.listAccountIds+config.resolveAccountcapabilities(tipos de chat, mídia, threads etc.)outbound.deliveryMode+outbound.sendText(para envio básico)
- Adicione adaptadores opcionais conforme necessário
setup(assistente),security(política de DM),status(saúde/diagnósticos)gateway(start/stop/login),mentions,threading,streamingactions(ações de mensagem),commands(comportamento de comando nativo)
- Registre o canal no seu plugin
api.registerChannel({ plugin })
Exemplo mínimo de configuração:
{
channels: {
acmechat: {
accounts: {
default: { token: "ACME_TOKEN", enabled: true },
},
},
},
}
Plugin mínimo de canal (apenas saída):
const plugin = {
id: "acmechat",
meta: {
id: "acmechat",
label: "AcmeChat",
selectionLabel: "AcmeChat (API)",
docsPath: "/channels/acmechat",
blurb: "AcmeChat messaging channel.",
aliases: ["acme"],
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
resolveAccount: (cfg, accountId) =>
cfg.channels?.acmechat?.accounts?.[accountId ?? "default"] ?? {
accountId,
},
},
outbound: {
deliveryMode: "direct",
sendText: async ({ text }) => {
// deliver `text` to your channel here
return { ok: true };
},
},
};
export default function (api) {
api.registerChannel({ plugin });
}
Carregue o plugin (diretório de extensões ou plugins.load.paths), reinicie o gateway,
depois configure channels.<id> na sua configuração.
Ferramentas de agente¶
Veja o guia dedicado: Plugin agent tools.
Registrar um método de RPC do gateway¶
export default function (api) {
api.registerGatewayMethod("myplugin.status", ({ respond }) => {
respond(true, { ok: true });
});
}
Registrar comandos de CLI¶
export default function (api) {
api.registerCli(
({ program }) => {
program.command("mycmd").action(() => {
console.log("Hello");
});
},
{ commands: ["mycmd"] },
);
}
Registrar comandos de resposta automática¶
Os plugins podem registrar comandos personalizados de barra que executam sem invocar o agente de IA. Isso é útil para comandos de alternância, verificações de status ou ações rápidas que não precisam de processamento por LLM.
export default function (api) {
api.registerCommand({
name: "mystatus",
description: "Show plugin status",
handler: (ctx) => ({
text: `Plugin is running! Channel: ${ctx.channel}`,
}),
});
}
Contexto do manipulador de comando:
senderId: O ID do remetente (se disponível)channel: O canal onde o comando foi enviadoisAuthorizedSender: Se o remetente é um usuário autorizadoargs: Argumentos passados após o comando (seacceptsArgs: true)commandBody: O texto completo do comandoconfig: A configuração atual do OpenClaw
Opções de comando:
name: Nome do comando (sem o/inicial)description: Texto de ajuda mostrado em listas de comandosacceptsArgs: Se o comando aceita argumentos (padrão: false). Se false e argumentos forem fornecidos, o comando não corresponderá e a mensagem seguirá para outros manipuladoresrequireAuth: Se deve exigir remetente autorizado (padrão: true)handler: Função que retorna{ text: string }(pode ser async)
Exemplo com autorização e argumentos:
api.registerCommand({
name: "setmode",
description: "Set plugin mode",
acceptsArgs: true,
requireAuth: true,
handler: async (ctx) => {
const mode = ctx.args?.trim() || "default";
await saveMode(mode);
return { text: `Mode set to: ${mode}` };
},
});
Notas:
- Comandos de plugin são processados antes dos comandos embutidos e do agente de IA
- Os comandos são registrados globalmente e funcionam em todos os canais
- Nomes de comando não diferenciam maiúsculas/minúsculas (
/MyStatuscorresponde a/mystatus) - Os nomes dos comandos devem começar com uma letra e conter apenas letras, números, hífens e sublinhados
- Nomes de comando reservados (como
help,status,reset, etc.) não podem ser sobrescritos por plugins - Registro duplicado de comandos entre plugins falhará com um erro de diagnóstico
Registrar serviços em segundo plano¶
export default function (api) {
api.registerService({
id: "my-service",
start: () => api.logger.info("ready"),
stop: () => api.logger.info("bye"),
});
}
Convenções de nomenclatura¶
- Métodos do Gateway:
pluginId.action(exemplo:voicecall.status) - Ferramentas:
snake_case(exemplo:voice_call) - Comandos de CLI: kebab ou camel, mas evite conflito com comandos principais
Skills¶
Os plugins podem incluir uma skill no repositório (skills/<name>/SKILL.md).
Habilite-a com plugins.entries.<id>.enabled (ou outros controles de configuração) e garanta
que ela esteja presente nos locais de skills do workspace/gerenciados.
Distribuição (npm)¶
Empacotamento recomendado:
- Pacote principal:
openclaw(este repositório) - Plugins: pacotes npm separados sob
@openclaw/*(exemplo:@openclaw/voice-call)
Contrato de publicação:
- O
package.jsondo plugin deve incluiropenclaw.extensionscom um ou mais arquivos de entrada. - Os arquivos de entrada podem ser
.jsou.ts(jiti carrega TS em tempo de execução). openclaw plugins install <npm-spec>usanpm pack, extrai em~/.openclaw/extensions/<id>/e o habilita na configuração.- Estabilidade da chave de configuração: pacotes com escopo são normalizados para o id sem escopo em
plugins.entries.*.
Plugin de exemplo: Voice Call¶
Este repositório inclui um plugin de chamada de voz (Twilio ou fallback de log):
- Código-fonte:
extensions/voice-call - Skill:
skills/voice-call - CLI:
openclaw voicecall start|status - Ferramenta:
voice_call - RPC:
voicecall.start,voicecall.status - Configuração (twilio):
provider: "twilio"+twilio.accountSid/authToken/from(opcionalstatusCallbackUrl,twimlUrl) - Configuração (dev):
provider: "log"(sem rede)
Veja Voice Call e extensions/voice-call/README.md para configuração e uso.
Notas de segurança¶
Os plugins rodam no mesmo processo do Gateway. Trate-os como código confiável:
- Instale apenas plugins em que você confia.
- Prefira listas de permissões
plugins.allow. - Reinicie o Gateway após alterações.
Testando plugins¶
Os plugins podem (e devem) incluir testes:
- Plugins no repositório podem manter testes Vitest em
src/**(exemplo:src/plugins/voice-call.plugin.test.ts). - Plugins publicados separadamente devem executar sua própria CI (lint/build/test) e validar que
openclaw.extensionsaponta para o entrypoint compilado (dist/index.js).