Plugins
Sviluppo di Plugin
I plugin estendono OpenClaw con nuove capacità: canali, provider di modelli, voce, trascrizione in tempo reale, voce in tempo reale, comprensione dei media, generazione di immagini, generazione di video, recupero web, ricerca web, strumenti agente o qualsiasi combinazione.
Non è necessario aggiungere il tuo plugin al repository OpenClaw. Pubblica su
ClawHub e gli utenti installano con
openclaw plugins install clawhub:<package-name>. Le specifiche di pacchetto nude continuano a
installare da npm durante la transizione di lancio.
Prerequisiti
- Node >= 22 e un gestore di pacchetti (npm o pnpm)
- Familiarità con TypeScript (ESM)
- Per i plugin nel repository: repository clonato e
pnpm installcompletato. Lo sviluppo di plugin da checkout sorgente è solo pnpm perché OpenClaw carica i plugin in bundle dai pacchetti workspaceextensions/*.
Che tipo di plugin?
Connetti OpenClaw a una piattaforma di messaggistica (Discord, IRC, ecc.)
Aggiungi un provider di modelli (LLM, proxy o endpoint personalizzato)
Registra strumenti agente, hook di evento o servizi - continua sotto
Per un plugin di canale che non è garantito sia installato quando viene eseguito onboarding/configurazione,
usa createOptionalChannelSetupSurface(...) da
openclaw/plugin-sdk/channel-setup. Produce una coppia adattatore di configurazione + procedura guidata
che comunica il requisito di installazione e fallisce in modo chiuso sulle scritture di configurazione reali
finché il plugin non è installato.
Avvio rapido: plugin strumento
Questa procedura dettagliata crea un plugin minimo che registra uno strumento agente. I plugin di canale e provider hanno guide dedicate linkate sopra.
Crea il pacchetto e il manifest
{
"name": "@myorg/openclaw-my-plugin",
"version": "1.0.0",
"type": "module",
"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
}
}
Ogni plugin ha bisogno di un manifest, anche senza configurazione. Gli strumenti registrati a runtime
devono essere elencati in contracts.tools così OpenClaw può scoprire il
plugin proprietario senza caricare ogni runtime di plugin. I plugin dovrebbero anche dichiarare
activation.onStartup intenzionalmente. Questo esempio lo imposta a true. Consulta
Manifest per lo schema completo. Gli snippet canonici di pubblicazione ClawHub
si trovano in docs/snippets/plugin-publish/.
Scrivi il punto di ingresso
// index.ts
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { Type } from "@sinclair/typebox";
export default definePluginEntry({
id: "my-plugin",
name: "My Plugin",
description: "Adds a custom tool to OpenClaw",
register(api) {
api.registerTool({
name: "my_tool",
description: "Do a thing",
parameters: Type.Object({ input: Type.String() }),
async execute(_id, params) {
return { content: [{ type: "text", text: `Got: ${params.input}` }] };
},
});
},
});
definePluginEntry è per plugin non di canale. Per i canali, usa
defineChannelPluginEntry - consulta Plugin di canale.
Per le opzioni complete del punto di ingresso, consulta Punti di ingresso.
Testa e pubblica
Plugin esterni: valida e pubblica con ClawHub, poi installa:
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
openclaw plugins install clawhub:@myorg/openclaw-my-plugin
Le specifiche di pacchetto nude come @myorg/openclaw-my-plugin installano da npm durante
la transizione di lancio. Usa clawhub: quando vuoi la risoluzione ClawHub.
Plugin nel repository: posiziona sotto l'albero workspace dei plugin in bundle - rilevato automaticamente.
pnpm test -- <bundled-plugin-root>/my-plugin/
Capacità dei plugin
Un singolo plugin può registrare qualsiasi numero di capacità tramite l'oggetto api:
| Capacità | Metodo di registrazione | Guida dettagliata |
|---|---|---|
| Inferenza testuale (LLM) | api.registerProvider(...) |
Plugin provider |
| Backend di inferenza CLI | api.registerCliBackend(...) |
Backend CLI |
| Canale / messaggistica | api.registerChannel(...) |
Plugin di canale |
| Voce (TTS/STT) | api.registerSpeechProvider(...) |
Plugin provider |
| Trascrizione in tempo reale | api.registerRealtimeTranscriptionProvider(...) |
Plugin provider |
| Voce in tempo reale | api.registerRealtimeVoiceProvider(...) |
Plugin provider |
| Comprensione dei media | api.registerMediaUnderstandingProvider(...) |
Plugin provider |
| Generazione di immagini | api.registerImageGenerationProvider(...) |
Plugin provider |
| Generazione di musica | api.registerMusicGenerationProvider(...) |
Plugin provider |
| Generazione di video | api.registerVideoGenerationProvider(...) |
Plugin provider |
| Recupero web | api.registerWebFetchProvider(...) |
Plugin provider |
| Ricerca web | api.registerWebSearchProvider(...) |
Plugin provider |
| Middleware risultati strumento | api.registerAgentToolResultMiddleware(...) |
Panoramica SDK |
| Strumenti agente | api.registerTool(...) |
Sotto |
| Comandi personalizzati | api.registerCommand(...) |
Punti di ingresso |
| Hook di plugin | api.on(...) |
Hook di plugin |
| Hook eventi interni | api.registerHook(...) |
Punti di ingresso |
| Route HTTP | api.registerHttpRoute(...) |
Interni |
| Sottocomandi CLI | api.registerCli(...) |
Punti di ingresso |
Per l'API di registrazione completa, consulta Panoramica SDK.
I plugin in bundle possono usare api.registerAgentToolResultMiddleware(...) quando hanno
bisogno di riscrivere in modo asincrono i risultati degli strumenti prima che il modello veda l'output. Dichiara i
runtime mirati in contracts.agentToolResultMiddleware, per esempio
["pi", "codex"]. Questa è un'interfaccia fidata per plugin in bundle; i
plugin esterni dovrebbero preferire i normali hook di plugin OpenClaw a meno che OpenClaw non sviluppi una
policy di fiducia esplicita per questa capacità.
Se il tuo plugin registra metodi RPC gateway personalizzati, tienili su un
prefisso specifico del plugin. Gli spazi dei nomi amministrativi core (config.*,
exec.approvals.*, wizard.*, update.*) rimangono riservati e si risolvono sempre in
operator.admin, anche se un plugin richiede uno scope più ristretto.
Semantica delle guardie hook da tenere presente:
before_tool_call:{ block: true }è terminale e interrompe gli handler con priorità inferiore.before_tool_call:{ block: false }viene trattato come nessuna decisione.before_tool_call:{ requireApproval: true }mette in pausa l'esecuzione dell'agente e chiede approvazione all'utente tramite l'overlay di approvazione exec, pulsanti Telegram, interazioni Discord o il comando/approvesu qualsiasi canale.before_install:{ block: true }è terminale e interrompe gli handler con priorità inferiore.before_install:{ block: false }viene trattato come nessuna decisione.message_sending:{ cancel: true }è terminale e interrompe gli handler con priorità inferiore.message_sending:{ cancel: false }viene trattato come nessuna decisione.message_received: preferisci il campo tipizzatothreadIdquando ti serve il routing in ingresso di thread/argomento. Mantienimetadataper extra specifici del canale.message_sending: preferisci i campi di routing tipizzatireplyToId/threadIdrispetto alle chiavi metadata specifiche del canale.
Il comando /approve gestisce sia approvazioni exec sia approvazioni plugin con fallback limitato: quando un id di approvazione exec non viene trovato, OpenClaw riprova lo stesso id tra le approvazioni plugin. L'inoltro delle approvazioni plugin può essere configurato indipendentemente tramite approvals.plugin nella configurazione.
Se il plumbing di approvazione personalizzato deve rilevare lo stesso caso di fallback limitato,
preferisci isApprovalNotFoundError da openclaw/plugin-sdk/error-runtime
invece di confrontare manualmente stringhe di scadenza approvazione.
Consulta Hook di plugin per esempi e il riferimento degli hook.
Registrazione di strumenti agente
Gli strumenti sono funzioni tipizzate che l'LLM può chiamare. Possono essere obbligatori (sempre disponibili) o opzionali (opt-in dell'utente):
register(api) {
// Required tool - always available
api.registerTool({
name: "my_tool",
description: "Do a thing",
parameters: Type.Object({ input: Type.String() }),
async execute(_id, params) {
return { content: [{ type: "text", text: params.input }] };
},
});
// Optional tool - user must add to allowlist
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 },
);
}
Ogni strumento registrato con api.registerTool(...) deve anche essere dichiarato nel
manifest del plugin:
{
"contracts": {
"tools": ["my_tool", "workflow_tool"]
},
"toolMetadata": {
"workflow_tool": {
"optional": true
}
}
}
OpenClaw acquisisce e memorizza nella cache il descrittore convalidato dallo strumento registrato,
quindi i plugin non duplicano description o i dati dello schema nel manifest. Il
contratto del manifest dichiara solo proprietà e rilevamento; l'esecuzione chiama comunque
l'implementazione live dello strumento registrato.
Imposta toolMetadata.<tool>.optional: true per gli strumenti registrati con
api.registerTool(..., { optional: true }) così OpenClaw può evitare di caricare quel
runtime del plugin finché lo strumento non viene esplicitamente inserito nell'elenco consentito.
Gli utenti abilitano gli strumenti facoltativi nella configurazione:
{
tools: { allow: ["workflow_tool"] },
}
- I nomi degli strumenti non devono entrare in conflitto con gli strumenti core (i conflitti vengono ignorati)
- Gli strumenti con oggetti di registrazione non validi, inclusi quelli senza
parameters, vengono ignorati e segnalati nella diagnostica del plugin invece di interrompere le esecuzioni degli agenti - Usa
optional: trueper strumenti con effetti collaterali o requisiti binari aggiuntivi - Gli utenti possono abilitare tutti gli strumenti di un plugin aggiungendo l'id del plugin a
tools.allow
Registrazione dei comandi CLI
I plugin possono aggiungere gruppi di comandi radice openclaw con api.registerCli. Fornisci
descriptors per ogni radice di comando di primo livello così OpenClaw può mostrare e instradare
il comando senza caricare in anticipo ogni runtime del plugin.
register(api) {
api.registerCli(
({ program }) => {
const demo = program
.command("demo-plugin")
.description("Run demo plugin commands");
demo
.command("ping")
.description("Check that the plugin CLI is executable")
.action(() => {
console.log("demo-plugin:pong");
});
},
{
descriptors: [
{
name: "demo-plugin",
description: "Run demo plugin commands",
hasSubcommands: true,
},
],
},
);
}
Dopo l'installazione, verifica la registrazione del runtime ed esegui il comando:
openclaw plugins inspect demo-plugin --runtime --json
openclaw demo-plugin ping
Convenzioni di importazione
Importa sempre da percorsi focalizzati openclaw/plugin-sdk/<subpath>:
// Wrong: monolithic root (deprecated, will be removed)
Per il riferimento completo dei sottopercorsi, consulta Panoramica SDK.
Nel tuo plugin, usa file barrel locali (api.ts, runtime-api.ts) per
le importazioni interne: non importare mai il tuo plugin attraverso il suo percorso SDK.
Per i plugin provider, mantieni gli helper specifici del provider in quei barrel alla radice del pacchetto, a meno che il seam non sia davvero generico. Esempi bundled attuali:
- Anthropic: wrapper dello stream Claude e helper
service_tier/ beta - OpenAI: builder dei provider, helper dei modelli predefiniti, provider realtime
- OpenRouter: builder del provider più helper di onboarding/configurazione
Se un helper è utile solo all'interno di un singolo pacchetto provider bundled, mantienilo su quel
seam alla radice del pacchetto invece di promuoverlo in openclaw/plugin-sdk/*.
Alcuni seam helper generati openclaw/plugin-sdk/<bundled-id> esistono ancora per
la manutenzione dei plugin bundled quando hanno utilizzo tracciato da parte del proprietario. Trattali come
superfici riservate, non come schema predefinito per nuovi plugin di terze parti.
Checklist pre-invio
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
package.json contiene i metadati openclaw corretti
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Il manifest openclaw.plugin.json è presente e valido OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
Il punto di ingresso usa defineChannelPluginEntry o definePluginEntry
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
Tutte le importazioni usano percorsi focalizzati plugin-sdk/<subpath>
OPENCLAW_DOCS_MARKER:calloutClose: