---
read_when:
    - Você quer criar um Plugin simples do OpenClaw que apenas adicione ferramentas de agente
    - Você quer usar defineToolPlugin em vez de escrever manualmente os metadados do manifesto do Plugin
    - É necessário estruturar, gerar, validar, testar ou publicar um plugin somente de ferramentas
sidebarTitle: Tool Plugins
summary: Crie ferramentas de agente tipadas simples com defineToolPlugin e openclaw plugins init/build/validate
title: Plugins de ferramentas
x-i18n:
    generated_at: "2026-07-16T12:50:37Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: fb9187e1d8aed88eee5c99dcdce89f70cd0d4f930b97aaac2ff868037d63adc1
    source_path: plugins/tool-plugins.md
    workflow: 16
---

`defineToolPlugin` cria um plugin que adiciona apenas ferramentas que podem ser chamadas pelo agente: sem
canal, provedor de modelo, hook, serviço ou backend de configuração. Ele gera os
metadados de manifesto necessários para que o OpenClaw descubra ferramentas sem carregar o código
de runtime do plugin.

Para plugins de provedor, canal, hook, serviço ou com recursos mistos, comece por
[Criação de plugins](/pt-BR/plugins/building-plugins), [Plugins de canal](/pt-BR/plugins/sdk-channel-plugins)
ou [Plugins de provedor](/pt-BR/plugins/sdk-provider-plugins).

## Requisitos

- Node 22.22.3+, Node 24.15+ ou Node 25.9+.
- Saída de pacote TypeScript ESM.
- `typebox` em `dependencies` (não apenas `devDependencies` — o plugin gerado
  o importa durante o runtime).
- `openclaw >=2026.5.17`, a primeira versão que exporta
  `openclaw/plugin-sdk/tool-plugin`.
- Uma raiz de pacote que distribua `dist/`, `openclaw.plugin.json` e
  `package.json`.

## Início rápido

```bash
openclaw plugins init stock-quotes --name "Stock Quotes"
cd stock-quotes
npm install
npm run plugin:build
npm run plugin:validate
npm test
```

`plugins init` gera a estrutura inicial:

| Arquivo                | Finalidade                                                        |
| ---------------------- | ----------------------------------------------------------------- |
| `src/index.ts`         | Entrada `defineToolPlugin` com uma ferramenta `echo`             |
| `src/index.test.ts`    | Teste de metadados que verifica a lista de ferramentas            |
| `tsconfig.json`        | Saída TypeScript NodeNext em `dist/`                              |
| `vitest.config.ts`     | Configuração do Vitest para `src/**/*.test.ts`                    |
| `package.json`         | Scripts, dependências de runtime, `openclaw.extensions: ["./dist/index.js"]` |
| `openclaw.plugin.json` | Metadados de manifesto gerados para a ferramenta inicial          |

`npm run plugin:build` executa `npm run build` (tsc) e depois
`openclaw plugins build --entry ./dist/index.js`. `npm run plugin:validate`
recompila e executa `openclaw plugins validate --entry ./dist/index.js`.
Uma validação bem-sucedida exibe:

```text
O plugin stock-quotes é válido.
```

Opções de `openclaw plugins init <id>`:

| Flag                 | Padrão             | Efeito                                 |
| -------------------- | ------------------ | -------------------------------------- |
| `--directory <path>` | `<id>`             | Diretório de saída                     |
| `--name <name>`      | `<id>` em formato de título | Nome de exibição                       |
| `--type <type>`      | `tool`             | Tipo de estrutura inicial: `tool` ou `provider` |
| `--force`            | desativado         | Sobrescreve um diretório de saída existente |

## Escrever uma ferramenta

`defineToolPlugin` recebe a identidade do plugin, um esquema de configuração opcional e uma
lista estática de ferramentas. Os tipos de parâmetros e configuração são inferidos dos
esquemas TypeBox.

```typescript
import { Type } from "typebox";
import { defineToolPlugin } from "openclaw/plugin-sdk/tool-plugin";

export default defineToolPlugin({
  id: "stock-quotes",
  name: "Cotações de ações",
  description: "Obtém snapshots de cotações de ações.",
  configSchema: Type.Object({
    apiKey: Type.Optional(Type.String({ description: "Chave da API de cotações." })),
    baseUrl: Type.Optional(Type.String({ description: "URL base da API de cotações." })),
  }),
  tools: (tool) => [
    tool({
      name: "stock_quote",
      label: "Cotação de ação",
      description: "Obtém um snapshot de cotação de ação.",
      parameters: Type.Object({
        symbol: Type.String({ description: "Símbolo do ticker, por exemplo, OPEN." }),
      }),
      async execute({ symbol }, config, context) {
        context.signal?.throwIfAborted();
        return {
          symbol: symbol.toUpperCase(),
          configured: Boolean(config.apiKey),
          baseUrl: config.baseUrl ?? "https://api.example.com",
        };
      },
    }),
  ],
});
```

Os nomes das ferramentas são a API estável. Escolha nomes exclusivos, em letras minúsculas e
específicos o suficiente para evitar colisões com ferramentas do núcleo ou de outros plugins.

## Ferramentas opcionais e de fábrica

Defina `optional: true` quando os usuários precisarem incluir explicitamente a ferramenta na lista de permissões antes que ela
seja enviada a um modelo. `openclaw plugins build` grava a entrada de manifesto
`toolMetadata.<tool>.optional` correspondente, para que o OpenClaw possa identificar que a
ferramenta é opcional sem carregar o código de runtime do plugin.

```typescript
tool({
  name: "workflow_run",
  description: "Executa um workflow externo.",
  parameters: Type.Object({ goal: Type.String() }),
  optional: true,
  execute: ({ goal }) => ({ queued: true, goal }),
});
```

Use `factory` quando uma ferramenta precisar do contexto de ferramenta do runtime antes de poder ser
criada — para não participar de uma execução específica, inspecionar o estado do sandbox ou vincular
helpers de runtime. Os metadados permanecem estáticos, embora a ferramenta concreta seja criada
durante o runtime.

```typescript
tool({
  name: "local_workflow",
  description: "Executa um workflow local fora de sessões em sandbox.",
  parameters: Type.Object({ goal: Type.String() }),
  optional: true,
  factory({ api, toolContext }) {
    if (toolContext.sandboxed) {
      return null;
    }
    return createLocalWorkflowTool(api);
  },
});
```

As fábricas ainda declaram antecipadamente um nome de ferramenta fixo. Use `definePluginEntry`
diretamente quando o plugin calcular nomes de ferramentas dinamicamente ou combinar ferramentas
com hooks, serviços, provedores ou comandos.

## Valores de retorno

`defineToolPlugin` encapsula valores de retorno simples no formato de resultado de ferramenta
do OpenClaw:

- Retorne uma string quando o modelo precisar ver exatamente esse texto.
- Retorne um valor compatível com JSON quando quiser que o modelo veja JSON formatado
  e que o OpenClaw mantenha o valor original em `details`.

```typescript
tool({
  name: "echo_text",
  description: "Repete o texto de entrada.",
  parameters: Type.Object({
    input: Type.String(),
  }),
  execute: ({ input }) => input,
});
```

```typescript
tool({
  name: "echo_json",
  description: "Repete a entrada como JSON estruturado.",
  parameters: Type.Object({
    input: Type.String(),
  }),
  execute: ({ input }) => ({ input, length: input.length }),
});
```

Use uma ferramenta de fábrica quando precisar de um `AgentToolResult` personalizado ou quiser reutilizar uma
implementação `api.registerTool` existente.

## Configuração

`configSchema` é opcional. Omita-o e o OpenClaw aplicará um esquema estrito de objeto
vazio; o manifesto gerado ainda incluirá `configSchema`.

```typescript
export default defineToolPlugin({
  id: "no-config-tools",
  name: "Ferramentas sem configuração",
  description: "Adiciona ferramentas que não precisam de configuração.",
  tools: () => [],
});
```

Com um `configSchema`, o segundo argumento de `execute` tem seu tipo derivado dele:

```typescript
const configSchema = Type.Object({
  apiKey: Type.String(),
});

export default defineToolPlugin({
  id: "configured-tools",
  name: "Ferramentas configuradas",
  description: "Adiciona ferramentas configuradas.",
  configSchema,
  tools: (tool) => [
    tool({
      name: "configured_ping",
      description: "Verifica se a configuração está disponível.",
      parameters: Type.Object({}),
      execute: (_params, config) => ({ hasKey: config.apiKey.length > 0 }),
    }),
  ],
});
```

O OpenClaw lê a configuração do plugin na entrada correspondente ao plugin na configuração do Gateway. Não
codifique segredos diretamente no código-fonte nem nos exemplos da documentação; use configuração, variáveis
de ambiente ou SecretRefs, conforme o modelo de segurança do plugin.

## Metadados gerados

O OpenClaw precisa ler o manifesto do plugin antes de importar seu código de runtime.
`defineToolPlugin` expõe metadados estáticos para isso, e
`openclaw plugins build` os grava no pacote. Execute novamente o gerador após
alterar o id, o nome, a descrição, o esquema de configuração, a ativação ou os nomes das ferramentas
do plugin:

```bash
npm run build
openclaw plugins build --entry ./dist/index.js
```

Manifesto gerado para um plugin com uma ferramenta:

```json
{
  "id": "stock-quotes",
  "name": "Cotações de ações",
  "description": "Obtém snapshots de cotações de ações.",
  "version": "0.1.0",
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  },
  "activation": {
    "onStartup": true
  },
  "contracts": {
    "tools": ["stock_quote"]
  }
}
```

`contracts.tools` é o contrato de descoberta importante: ele informa ao OpenClaw qual
plugin é proprietário de cada ferramenta sem carregar o runtime de todos os plugins instalados. Um
manifesto desatualizado pode fazer uma ferramenta desaparecer da descoberta ou fazer com que um erro de registro
seja atribuído ao plugin errado.

## Metadados do pacote

`openclaw plugins build` também alinha `package.json` à entrada de runtime
selecionada:

```json
{
  "type": "module",
  "files": ["dist", "openclaw.plugin.json", "README.md"],
  "dependencies": {
    "typebox": "^1.1.38"
  },
  "peerDependencies": {
    "openclaw": ">=2026.5.17"
  },
  "openclaw": {
    "extensions": ["./dist/index.js"]
  }
}
```

Distribua o JavaScript compilado (`./dist/index.js`), não uma entrada de código-fonte TypeScript.
Entradas de código-fonte funcionam apenas no desenvolvimento local no workspace.

## Validar na CI

`plugins build --check` falha sem regravar arquivos quando os metadados gerados
estão desatualizados:

```bash
npm run build
openclaw plugins build --entry ./dist/index.js --check
openclaw plugins validate --entry ./dist/index.js
npm test
```

`plugins validate` verifica se:

- `openclaw.plugin.json` existe e passa pelo carregador normal de manifestos.
- A entrada atual exporta os metadados `defineToolPlugin`.
- Os campos do manifesto gerado correspondem aos metadados da entrada.
- `contracts.tools` corresponde aos nomes de ferramentas declarados.
- `package.json` aponta `openclaw.extensions` para a entrada de runtime selecionada.

## Instalar e inspecionar localmente

Em outro checkout do OpenClaw ou usando uma CLI instalada, instale o caminho do pacote:

```bash
openclaw plugins install ./stock-quotes
openclaw plugins inspect stock-quotes --runtime
```

Para um teste de fumaça do pacote, primeiro empacote e instale o tarball:

```bash
npm pack
openclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgz
openclaw plugins inspect stock-quotes --runtime --json
```

Após a instalação, reinicie ou recarregue o Gateway e peça ao agente para usar a
ferramenta. Se a ferramenta não estiver visível, inspecione o runtime do plugin e o catálogo efetivo
de ferramentas antes de alterar o código (consulte [Solução de problemas](#troubleshooting)).

## Publicar

Publique por meio do ClawHub quando o pacote estiver pronto. `clawhub package publish`
recebe uma origem: uma pasta local, um repositório do GitHub (`owner/repo[@ref]`) ou uma
URL de tarball.

```bash
clawhub package publish ./stock-quotes --dry-run
clawhub package publish ./stock-quotes
```

Instale com um localizador explícito do ClawHub:

```bash
openclaw plugins install clawhub:your-org/stock-quotes
```

As especificações simples de pacotes npm ainda são instaladas pelo npm durante a transição de lançamento, mas
o ClawHub é a superfície preferencial de descoberta e distribuição para plugins do OpenClaw.
Consulte [Publicação no ClawHub](/pt-BR/clawhub/publishing) para informações sobre o escopo do proprietário e a
revisão da versão.

## Solução de problemas

### `plugin entry not found: ./dist/index.js`

O arquivo de entrada selecionado não existe. Execute `npm run build` e depois execute novamente
`openclaw plugins build --entry ./dist/index.js` ou
`openclaw plugins validate --entry ./dist/index.js`.

### `plugin entry does not expose defineToolPlugin metadata`

A entrada não exportou um valor criado por `defineToolPlugin`. Confirme se a
exportação padrão do módulo é o resultado de `defineToolPlugin(...)` ou informe a
entrada correta com `--entry`.

### `openclaw.plugin.json generated metadata is stale`

O manifesto não corresponde mais aos metadados da entrada. Execute:

```bash
npm run build
openclaw plugins build --entry ./dist/index.js
```

Faça commit das alterações em `openclaw.plugin.json` e `package.json`.

### `package.json openclaw.extensions must include ./dist/index.js`

Os metadados do pacote apontam para uma entrada de runtime diferente. Execute
`openclaw plugins build --entry ./dist/index.js` para que o gerador alinhe os
metadados do pacote à entrada que você pretende distribuir.

### `Cannot find package 'typebox'`

O plugin compilado importa `typebox` durante o runtime. Mantenha-o em `dependencies`,
reinstale, recompile e execute novamente a validação.

### A ferramenta não aparece após a instalação

Verifique estes itens na ordem:

1. `openclaw plugins inspect <plugin-id> --runtime`
2. `openclaw plugins validate --root <plugin-root> --entry ./dist/index.js`
3. `openclaw.plugin.json` tem `contracts.tools` com os nomes de ferramentas esperados.
4. `package.json` tem `openclaw.extensions: ["./dist/index.js"]`.
5. O Gateway foi reiniciado ou recarregado após a instalação do plugin.

## Consulte também

- [Criação de plugins](/pt-BR/plugins/building-plugins)
- [Pontos de entrada de plugins](/pt-BR/plugins/sdk-entrypoints)
- [Subcaminhos do SDK de plugins](/pt-BR/plugins/sdk-subpaths)
- [Manifesto do plugin](/pt-BR/plugins/manifest)
- [CLI de plugins](/pt-BR/cli/plugins)
- [Publicação no ClawHub](/pt-BR/clawhub/publishing)
