Building plugins
Criando plugins
Plugins estendem o OpenClaw sem alterar o núcleo. Um plugin pode adicionar um canal de mensagens, provedor de modelo, backend de CLI local, ferramenta de agente, hook, provedor de mídia ou outra capacidade pertencente ao plugin.
Você não precisa adicionar um plugin externo ao repositório do OpenClaw. Publique o pacote no ClawHub e os usuários o instalam com:
openclaw plugins install clawhub:<package-name>Especificações de pacote simples ainda são instaladas pelo npm durante a transição de lançamento. Use o prefixo clawhub: quando quiser resolução pelo ClawHub.
Requisitos
- Use Node 22.19+, Node 23.11+ ou Node 24+ e um gerenciador de pacotes como
npmoupnpm. - Tenha familiaridade com módulos ESM do TypeScript.
- Para trabalho em plugin empacotado dentro do repositório, clone o repositório e execute
pnpm install. O desenvolvimento de plugins em checkout de código-fonte usa apenas pnpm porque o OpenClaw carrega plugins empacotados a partir dos pacotes de workspaceextensions/*.
Escolha o formato do plugin
Conecte o OpenClaw a uma plataforma de mensagens.
Adicione um provedor de modelo, mídia, busca, fetch, fala ou tempo real.
Execute uma CLI de IA local por meio do fallback de modelo do OpenClaw.
Registre ferramentas de agente.
Início rápido
Crie um plugin de ferramenta mínimo registrando uma ferramenta de agente obrigatória. Este é o formato útil mais curto de plugin e mostra o pacote, o manifesto, o ponto de entrada e a prova local.
Create package metadata
{"name": "@myorg/openclaw-my-plugin","version": "1.0.0","type": "module","dependencies": {"typebox": "1.1.39"},"peerDependencies": {"openclaw": ">=2026.3.24-beta.2"},"openclaw": {"extensions": ["./index.ts"],"compat": {"pluginApi": ">=2026.3.24-beta.2","minGatewayVersion": "2026.3.24-beta.2"},"build": {"openclawVersion": "2026.3.24-beta.2","pluginSdkVersion": "2026.3.24-beta.2"}}}{"id": "my-plugin","name": "My Plugin","description": "Adds a custom tool to OpenClaw","contracts": {"tools": ["my_tool"]},"activation": {"onStartup": true},"configSchema": {"type": "object","additionalProperties": false}}Plugins externos publicados devem apontar entradas de runtime para arquivos JavaScript compilados. Consulte pontos de entrada do SDK para ver o contrato completo de ponto de entrada.
Todo plugin precisa de um manifesto, mesmo quando não tem configuração. Ferramentas de runtime devem aparecer em contracts.tools para que o OpenClaw possa descobrir a propriedade sem carregar antecipadamente todos os runtimes de plugins. Defina activation.onStartup intencionalmente. Este exemplo inicia na inicialização do Gateway.
Superfícies de plugin confiáveis pelo host também são controladas pelo manifesto e exigem habilitação explícita para plugins instalados. Se um plugin instalado registrar api.registerAgentToolResultMiddleware(...), declare cada runtime de destino em contracts.agentToolResultMiddleware. Se ele registrar api.registerTrustedToolPolicy(...), declare cada id de política em contracts.trustedToolPolicies. Essas declarações mantêm a inspeção no momento da instalação alinhada com o registro em runtime.
Para cada campo do manifesto, consulte manifesto do Plugin.
Register the tool
import { Type } from "typebox";import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; export default definePluginEntry({ id: "my-plugin", name: "My Plugin", description: "Adds a custom tool to OpenClaw", register(api) { api.registerTool({ name: "my_tool", description: "Echo one input value", parameters: Type.Object({ input: Type.String() }), async execute(_id, params) { return { content: [{ type: "text", text: `Got: ${params.input}` }], }; }, }); },});Use definePluginEntry para plugins que não são de canal. Plugins de canal usam defineChannelPluginEntry.
Test the runtime
Para um plugin instalado ou externo, inspecione o runtime carregado:
openclaw plugins inspect my-plugin --runtime --jsonSe o plugin registrar um comando de CLI, execute esse comando também. Por exemplo, um comando de demonstração deve ter uma prova de execução como openclaw demo-plugin ping.
Para um plugin empacotado neste repositório, o OpenClaw descobre pacotes de plugin em checkout de código-fonte pelo workspace extensions/*. Execute o teste direcionado mais próximo:
pnpm test -- extensions/my-plugin/pnpm checkTest the package install
Antes de publicar um plugin pronto para pacote, teste o mesmo formato de instalação que os usuários receberão. Primeiro adicione uma etapa de build, aponte entradas de runtime como openclaw.extensions para JavaScript compilado, como ./dist/index.js, e garanta que npm pack inclua essa saída dist/. Entradas de código-fonte TypeScript são apenas para checkouts de código-fonte e caminhos de desenvolvimento local.
Em seguida, empacote o plugin e instale o tarball com npm-pack::
npm pack --pack-destination /tmpopenclaw plugins install npm-pack:/tmp/<plugin-package>.tgz --forceopenclaw plugins inspect my-plugin --runtime --jsonnpm-pack: usa o projeto npm gerenciado por plugin do OpenClaw, então captura erros de dependência de runtime que testes em checkout de código-fonte podem ocultar. Ele comprova o formato do pacote e das dependências, não a confiança oficial vinculada ao catálogo. Imports de runtime devem estar em dependencies ou optionalDependencies; dependências deixadas apenas em devDependencies não serão instaladas para o projeto de runtime gerenciado.
Não use uma instalação bruta por arquivo/caminho como prova final para comportamento de Plugin oficial ou privilegiado. Fontes brutas são úteis para depuração local, mas não provam o mesmo caminho de dependência que instalações via npm ou ClawHub. Se seu Plugin depende de status confiável de Plugin oficial, adicione uma segunda prova por meio de uma instalação oficial baseada em catálogo ou de um caminho de pacote publicado que registre confiança oficial. Consulte Resolução de dependências de Plugin para detalhes sobre raiz de instalação e propriedade de dependências.
Publicar
Valide o pacote antes de publicar:
clawhub package publish your-org/your-plugin --dry-runclawhub package publish your-org/your-pluginOs snippets canônicos do ClawHub ficam em docs/snippets/plugin-publish/.
Instalar
Instale o pacote publicado pelo ClawHub:
openclaw plugins install clawhub:your-org/your-pluginRegistrando ferramentas
Ferramentas podem ser obrigatórias ou opcionais. Ferramentas obrigatórias estão sempre disponíveis quando o Plugin está habilitado. Ferramentas opcionais exigem adesão do usuário.
register(api) { api.registerTool( { name: "workflow_tool", description: "Run a workflow", parameters: Type.Object({ pipeline: Type.String() }), async execute(_id, params) { return { content: [{ type: "text", text: params.pipeline }] }; }, }, { optional: true }, );}Toda ferramenta registrada com api.registerTool(...) também deve ser declarada no
manifesto do Plugin:
{ "contracts": { "tools": ["workflow_tool"] }, "toolMetadata": { "workflow_tool": { "optional": true } }}Usuários aderem com tools.allow:
{ tools: { allow: ["workflow_tool"] }, // or ["my-plugin"] for all tools from one plugin}Ferramentas opcionais controlam se uma ferramenta é exposta ao modelo. Use solicitações de permissão de Plugin quando uma ferramenta ou hook deve pedir aprovação depois que o modelo a seleciona e antes que a ação seja executada.
Use ferramentas opcionais para efeitos colaterais, binários incomuns ou capacidades que
não devem ser expostas por padrão. Nomes de ferramentas não podem conflitar com ferramentas principais;
conflitos são ignorados e relatados nos diagnósticos do Plugin. Registros malformados,
incluindo descritores de ferramenta sem parameters, são ignorados e
relatados da mesma forma. Ferramentas registradas são funções tipadas que o modelo pode chamar
depois que as verificações de política e lista de permissões são aprovadas.
Fábricas de ferramentas recebem um objeto de contexto fornecido pelo runtime. Use ctx.activeModel
quando uma ferramenta precisar registrar, exibir ou se adaptar ao modelo ativo do turno
atual. O objeto pode incluir provider, modelId e modelRef. Trate-o como
metadados informativos de runtime, não como uma fronteira de segurança contra o operador
local, código de Plugin instalado ou um runtime do OpenClaw modificado. Ferramentas locais
sensíveis ainda devem exigir uma adesão explícita do Plugin ou operador e falhar de modo fechado
quando os metadados de modelo ativo estiverem ausentes ou forem inadequados.
O manifesto declara propriedade e descoberta; a execução ainda chama a implementação
registrada ativa da ferramenta. Mantenha toolMetadata.<tool>.optional: true
alinhado com api.registerTool(..., { optional: true }) para que o OpenClaw possa evitar
carregar o runtime desse Plugin até que a ferramenta seja explicitamente incluída na lista de permissões.
Convenções de importação
Importe de subcaminhos focados do SDK:
Não importe do barrel raiz obsoleto:
Dentro do seu pacote de Plugin, use arquivos barrel locais, como api.ts e
runtime-api.ts, para importações internas. Não importe seu próprio Plugin por meio de um
caminho do SDK. Helpers específicos de provedor devem permanecer no pacote do provedor, a menos que
a interface seja realmente genérica.
Métodos RPC personalizados do Gateway são um ponto de entrada avançado. Mantenha-os em um
prefixo específico do Plugin; namespaces administrativos principais, como config.*,
exec.approvals.*, operator.admin.*, wizard.* e update.*, permanecem reservados
e resolvem para operator.admin. A ponte
openclaw/plugin-sdk/gateway-method-runtime é reservada para rotas HTTP de Plugin
que declaram contracts.gatewayMethodDispatch: ["authenticated-request"].
Para o mapa completo de importações, consulte Visão geral do SDK de Plugin.
Lista de verificação de pré-envio
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
package.json tem metadados openclaw corretos
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s O manifesto openclaw.plugin.json está presente e é válido OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
O ponto de entrada usa defineChannelPluginEntry ou definePluginEntry
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
Todas as importações usam caminhos focados plugin-sdk/<subpath>
OPENCLAW_DOCS_MARKER:calloutClose: