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:

bash
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 npm ou pnpm.
  • 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 workspace extensions/*.

Escolha o formato do plugin

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

    package.json
    {"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"}}}
    openclaw.plugin.json
    {"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

    index.ts
    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:

    bash
    openclaw plugins inspect my-plugin --runtime --json

    Se 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:

    bash
    pnpm test -- extensions/my-plugin/pnpm check
  • Test 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::

    bash
    npm pack --pack-destination /tmpopenclaw plugins install npm-pack:/tmp/<plugin-package>.tgz --forceopenclaw plugins inspect my-plugin --runtime --json

    npm-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:

    bash
    clawhub package publish your-org/your-plugin --dry-runclawhub package publish your-org/your-plugin

    Os snippets canônicos do ClawHub ficam em docs/snippets/plugin-publish/.

  • Instalar

    Instale o pacote publicado pelo ClawHub:

    bash
    openclaw plugins install clawhub:your-org/your-plugin
  • Registrando 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.

    typescript
    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:

    json
    {  "contracts": {    "tools": ["workflow_tool"]  },  "toolMetadata": {    "workflow_tool": {      "optional": true    }  }}

    Usuários aderem com tools.allow:

    json5
    {  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:

    typescript
      

    Não importe do barrel raiz obsoleto:

    typescript
     

    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:

    Was this useful?
    On this page

    On this page