Building plugins
Plugin per strumenti
defineToolPlugin crea un plugin che aggiunge solo strumenti richiamabili dall'agente: nessun
canale, provider di modelli, hook, servizio o backend di configurazione. Genera i
metadati del manifest necessari a OpenClaw per individuare gli strumenti senza caricare il codice
runtime del plugin.
Per plugin di provider, canale, hook, servizio o con funzionalità miste, iniziare invece da Creazione di plugin, Plugin di canale o Plugin di provider.
Requisiti
- Node 22.22.3+, Node 24.15+ o Node 25.9+.
- Output del pacchetto TypeScript ESM.
typeboxindependencies(non solodevDependencies: il plugin generato lo importa in fase di runtime).openclaw >=2026.5.17, la prima versione che esportaopenclaw/plugin-sdk/tool-plugin.- Una radice del pacchetto che distribuisca
dist/,openclaw.plugin.jsonepackage.json.
Avvio rapido
openclaw plugins init stock-quotes --name "Stock Quotes"cd stock-quotesnpm installnpm run plugin:buildnpm run plugin:validatenpm testplugins init genera la struttura di base:
| File | Scopo |
|---|---|
src/index.ts |
Punto di ingresso defineToolPlugin con uno strumento echo |
src/index.test.ts |
Test dei metadati che verifica l'elenco degli strumenti |
tsconfig.json |
Output TypeScript NodeNext in dist/ |
vitest.config.ts |
Configurazione Vitest per src/**/*.test.ts |
package.json |
Script, dipendenze runtime, openclaw.extensions: ["./dist/index.js"] |
openclaw.plugin.json |
Metadati del manifest generati per lo strumento iniziale |
npm run plugin:build esegue npm run build (tsc), quindi
openclaw plugins build --entry ./dist/index.js. npm run plugin:validate
ricompila ed esegue openclaw plugins validate --entry ./dist/index.js.
Una convalida riuscita stampa:
Il plugin stock-quotes è valido.Opzioni di openclaw plugins init <id>:
| Flag | Valore predefinito | Effetto |
|---|---|---|
--directory <path> |
<id> |
Directory di output |
--name <name> |
<id> con iniziali maiuscole |
Nome visualizzato |
--type <type> |
tool |
Tipo di struttura: tool o provider |
--force |
disattivato | Sovrascrive una directory di output esistente |
Scrivere uno strumento
defineToolPlugin accetta l'identità del plugin, uno schema di configurazione facoltativo e un
elenco statico di strumenti. I tipi dei parametri e della configurazione vengono dedotti dagli
schemi TypeBox.
export default defineToolPlugin({ id: "stock-quotes", name: "Stock Quotes", description: "Recupera istantanee delle quotazioni azionarie.", configSchema: Type.Object({ apiKey: Type.Optional(Type.String({ description: "Chiave API delle quotazioni." })), baseUrl: Type.Optional(Type.String({ description: "URL di base dell'API delle quotazioni." })), }), tools: (tool) => [ tool({ name: "stock_quote", label: "Quotazione azionaria", description: "Recupera un'istantanea della quotazione azionaria.", parameters: Type.Object({ symbol: Type.String({ description: "Simbolo ticker, ad esempio OPEN." }), }), async execute({ symbol }, config, context) { context.signal?.throwIfAborted(); return { symbol: symbol.toUpperCase(), configured: Boolean(config.apiKey), baseUrl: config.baseUrl ?? "https://api.example.com", }; }, }), ],});I nomi degli strumenti costituiscono l'API stabile. Scegliere nomi univoci, in minuscolo e abbastanza specifici da evitare collisioni con gli strumenti principali o con altri plugin.
Strumenti facoltativi e factory
Impostare optional: true quando gli utenti devono inserire esplicitamente lo strumento nell'elenco consentito prima che
venga inviato a un modello. openclaw plugins build scrive la voce del manifest
toolMetadata.<tool>.optional corrispondente, affinché OpenClaw possa rilevare che lo
strumento è facoltativo senza caricare il codice runtime del plugin.
tool({ name: "workflow_run", description: "Esegue un flusso di lavoro esterno.", parameters: Type.Object({ goal: Type.String() }), optional: true, execute: ({ goal }) => ({ queued: true, goal }),});Usare factory quando uno strumento necessita del contesto runtime degli strumenti prima di poter essere
creato, per escluderlo da un'esecuzione specifica, esaminare lo stato della sandbox o associare
helper runtime. I metadati rimangono statici anche se lo strumento concreto viene creato
in fase di runtime.
tool({ name: "local_workflow", description: "Esegue un flusso di lavoro locale al di fuori delle sessioni in sandbox.", parameters: Type.Object({ goal: Type.String() }), optional: true, factory({ api, toolContext }) { if (toolContext.sandboxed) { return null; } return createLocalWorkflowTool(api); },});Le factory dichiarano comunque in anticipo un nome fisso per lo strumento. Usare direttamente definePluginEntry
quando il plugin calcola dinamicamente i nomi degli strumenti o combina gli strumenti
con hook, servizi, provider o comandi.
Valori restituiti
defineToolPlugin racchiude i valori restituiti semplici nel formato dei risultati degli strumenti
di OpenClaw:
- Restituire una stringa quando il modello deve visualizzare esattamente quel testo.
- Restituire un valore compatibile con JSON quando si desidera che il modello visualizzi JSON formattato
e che OpenClaw conservi il valore originale in
details.
tool({ name: "echo_text", description: "Ripete il testo di input.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => input,});tool({ name: "echo_json", description: "Ripete l'input come JSON strutturato.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => ({ input, length: input.length }),});Usare uno strumento factory quando è necessario un AgentToolResult personalizzato o si desidera riutilizzare
un'implementazione api.registerTool esistente.
Configurazione
configSchema è facoltativo. Se viene omesso, OpenClaw applica uno schema rigoroso per oggetti vuoti;
il manifest generato include comunque configSchema.
export default defineToolPlugin({ id: "no-config-tools", name: "Strumenti senza configurazione", description: "Aggiunge strumenti che non richiedono configurazione.", tools: () => [],});Con un configSchema, il secondo argomento execute viene tipizzato a partire da esso:
const configSchema = Type.Object({ apiKey: Type.String(),}); export default defineToolPlugin({ id: "configured-tools", name: "Strumenti configurati", description: "Aggiunge strumenti configurati.", configSchema, tools: (tool) => [ tool({ name: "configured_ping", description: "Verifica se la configurazione è disponibile.", parameters: Type.Object({}), execute: (_params, config) => ({ hasKey: config.apiKey.length > 0 }), }), ],});OpenClaw legge la configurazione del plugin dalla voce del plugin nella configurazione del Gateway. Non inserire segreti direttamente nel codice sorgente o negli esempi della documentazione; usare la configurazione, le variabili d'ambiente o i SecretRef in base al modello di sicurezza del plugin.
Metadati generati
OpenClaw deve leggere il manifest del plugin prima di importare il codice runtime del plugin.
defineToolPlugin espone metadati statici a questo scopo e
openclaw plugins build li scrive nel pacchetto. Eseguire nuovamente il generatore dopo
aver modificato l'ID, il nome, la descrizione, lo schema di configurazione, l'attivazione o i nomi degli strumenti
del plugin:
npm run buildopenclaw plugins build --entry ./dist/index.jsManifest generato per un plugin con un solo strumento:
{ "id": "stock-quotes", "name": "Stock Quotes", "description": "Recupera istantanee delle quotazioni azionarie.", "version": "0.1.0", "configSchema": { "type": "object", "additionalProperties": false, "properties": {} }, "activation": { "onStartup": true }, "contracts": { "tools": ["stock_quote"] }}contracts.tools è il contratto di individuazione fondamentale: indica a OpenClaw quale
plugin è proprietario di ciascuno strumento senza caricare il runtime di ogni plugin installato. Un
manifest obsoleto può impedire l'individuazione di uno strumento oppure attribuire un errore
di registrazione al plugin sbagliato.
Metadati del pacchetto
openclaw plugins build allinea inoltre package.json al punto di ingresso runtime
selezionato:
{ "type": "module", "files": ["dist", "openclaw.plugin.json", "README.md"], "dependencies": { "typebox": "^1.1.38" }, "peerDependencies": { "openclaw": ">=2026.5.17" }, "openclaw": { "extensions": ["./dist/index.js"] }}Distribuire JavaScript compilato (./dist/index.js), non un punto di ingresso sorgente TypeScript.
I punti di ingresso sorgente funzionano solo per lo sviluppo locale nell'area di lavoro.
Convalidare nella CI
plugins build --check non riesce, senza riscrivere i file, quando i metadati generati
sono obsoleti:
npm run buildopenclaw plugins build --entry ./dist/index.js --checkopenclaw plugins validate --entry ./dist/index.jsnpm testplugins validate verifica che:
openclaw.plugin.jsonesista e superi il normale caricatore del manifest.- Il punto di ingresso corrente esporti i metadati
defineToolPlugin. - I campi del manifest generato corrispondano ai metadati del punto di ingresso.
contracts.toolscorrisponda ai nomi degli strumenti dichiarati.package.jsonindirizziopenclaw.extensionsal punto di ingresso runtime selezionato.
Installare ed esaminare localmente
Da un checkout OpenClaw separato o da una CLI installata, installare il percorso del pacchetto:
openclaw plugins install ./stock-quotesopenclaw plugins inspect stock-quotes --runtimePer un test rapido del pacchetto, creare prima il pacchetto e installare il tarball:
npm packopenclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgzopenclaw plugins inspect stock-quotes --runtime --jsonDopo l'installazione, riavviare o ricaricare il Gateway e chiedere all'agente di usare lo strumento. Se lo strumento non è visibile, esaminare il runtime del plugin e il catalogo degli strumenti effettivo prima di modificare il codice (vedere Risoluzione dei problemi).
Pubblicazione
Pubblicare tramite ClawHub quando il pacchetto è pronto. clawhub package publish
accetta una sorgente: una cartella locale, un repository GitHub (owner/repo[@ref]) o un
URL di tarball.
clawhub package publish ./stock-quotes --dry-runclawhub package publish ./stock-quotesInstallare con un localizzatore ClawHub esplicito:
openclaw plugins install clawhub:your-org/stock-quotesLe specifiche semplici dei pacchetti npm continuano a essere installate da npm durante la transizione del lancio, ma ClawHub è la superficie preferita per individuare e distribuire i plugin OpenClaw. Vedere Pubblicazione su ClawHub per l'ambito del proprietario e la revisione della versione.
Risoluzione dei problemi
plugin entry not found: ./dist/index.js
Il file del punto di ingresso selezionato non esiste. Eseguire npm run build, quindi eseguire nuovamente
openclaw plugins build --entry ./dist/index.js o
openclaw plugins validate --entry ./dist/index.js.
plugin entry does not expose defineToolPlugin metadata
Il punto di ingresso non ha esportato un valore creato da defineToolPlugin. Verificare che
l'esportazione predefinita del modulo sia il risultato di defineToolPlugin(...), oppure specificare il
punto di ingresso corretto con --entry.
openclaw.plugin.json generated metadata is stale
Il manifest non corrisponde più ai metadati del punto di ingresso. Eseguire:
npm run buildopenclaw plugins build --entry ./dist/index.jsEseguire il commit delle modifiche sia a openclaw.plugin.json sia a package.json.
package.json openclaw.extensions must include ./dist/index.js
I metadati del pacchetto puntano a un punto di ingresso runtime diverso. Eseguire
openclaw plugins build --entry ./dist/index.js affinché il generatore allinei
i metadati del pacchetto al punto di ingresso che si intende distribuire.
Cannot find package 'typebox'
Il plugin compilato importa typebox in fase di runtime. Mantenerlo in dependencies,
reinstallare, ricompilare ed eseguire nuovamente la convalida.
Lo strumento non compare dopo l'installazione
Verificare quanto segue nell'ordine:
openclaw plugins inspect <plugin-id> --runtimeopenclaw plugins validate --root <plugin-root> --entry ./dist/index.jsopenclaw.plugin.jsoncontienecontracts.toolscon i nomi degli strumenti previsti.package.jsoncontieneopenclaw.extensions: ["./dist/index.js"].- Il Gateway è stato riavviato o ricaricato dopo l'installazione del Plugin.