Plugins (Extensions)¶
Démarrage rapide (nouveau sur les plugins ?)¶
Un plugin est simplement un petit module de code qui étend OpenClaw avec des fonctionnalités supplémentaires (commandes, outils et RPC de la Gateway (passerelle)).
La plupart du temps, vous utiliserez des plugins lorsque vous souhaitez une fonctionnalitĂ© qui nâest pas encore intĂ©grĂ©e au cĆur dâOpenClaw (ou lorsque vous voulez conserver des fonctionnalitĂ©s optionnelles hors de votre installation principale).
Chemin rapide :
- Voir ce qui est déjà chargé :
openclaw plugins list
- Installer un plugin officiel (exemple : Voice Call) :
openclaw plugins install @openclaw/voice-call
- Redémarrez la Gateway (passerelle), puis configurez sous
plugins.entries.<id>.config.
Voir Voice Call pour un exemple concret de plugin.
Plugins disponibles (officiels)¶
- Microsoft Teams est uniquement disponible via plugin depuis le 15/01/2026 ; installez
@openclaw/msteamssi vous utilisez Teams. - Memory (Core) â plugin de recherche de mĂ©moire groupĂ© (activĂ© par dĂ©faut via
plugins.slots.memory) - Memory (LanceDB) â plugin de mĂ©moire long terme groupĂ© (rappel/capture automatiques ; dĂ©finir
plugins.slots.memory = "memory-lancedb") - Voice Call â
@openclaw/voice-call - Zalo Personal â
@openclaw/zalouser - Matrix â
@openclaw/matrix - Nostr â
@openclaw/nostr - Zalo â
@openclaw/zalo - Microsoft Teams â
@openclaw/msteams - Google Antigravity OAuth (authentification fournisseur) â groupĂ© en tant que
google-antigravity-auth(dĂ©sactivĂ© par dĂ©faut) - Gemini CLI OAuth (authentification fournisseur) â groupĂ© en tant que
google-gemini-cli-auth(dĂ©sactivĂ© par dĂ©faut) - Qwen OAuth (authentification fournisseur) â groupĂ© en tant que
qwen-portal-auth(dĂ©sactivĂ© par dĂ©faut) - Copilot Proxy (authentification fournisseur) â pont local VS Code Copilot Proxy ; distinct de la connexion intĂ©grĂ©e
github-copilotpar appareil (groupé, désactivé par défaut)
Les plugins OpenClaw sont des modules TypeScript chargĂ©s Ă lâexĂ©cution via jiti. La validation de configuration nâexĂ©cute pas le code du plugin ; elle utilise le manifeste du plugin et le schĂ©ma JSON Ă la place. Voir Plugin manifest.
Les plugins peuvent enregistrer :
- Des méthodes RPC de la Gateway (passerelle)
- Des gestionnaires HTTP de la Gateway (passerelle)
- Des outils dâagent
- Des commandes CLI
- Des services en arriĂšre-plan
- Une validation de configuration optionnelle
- Des Skills (en listant des répertoires
skillsdans le manifeste du plugin) - Des commandes de rĂ©ponse automatique (exĂ©cutĂ©es sans invoquer lâagent IA)
Les plugins sâexĂ©cutent dans le mĂȘme processus que la Gateway (passerelle) ; traitez-les donc comme du code de confiance. Guide de crĂ©ation dâoutils : Plugin agent tools.
Aides Ă lâexĂ©cution¶
Les plugins peuvent accĂ©der Ă certaines aides du cĆur via api.runtime. Pour la synthĂšse vocale (TTS) tĂ©lĂ©phonique :
const result = await api.runtime.tts.textToSpeechTelephony({
text: "Hello from OpenClaw",
cfg: api.config,
});
Remarques :
- Utilise la configuration centrale
messages.tts(OpenAI ou ElevenLabs). - Retourne un tampon audio PCM + un taux dâĂ©chantillonnage. Les plugins doivent rééchantillonner/encoder pour les fournisseurs.
- Edge TTS nâest pas pris en charge pour la tĂ©lĂ©phonie.
Découverte et priorité¶
OpenClaw analyse, dans lâordre :
- Chemins de configuration
plugins.load.paths(fichier ou répertoire)
- Extensions de lâespace de travail
<workspace>/.openclaw/extensions/*.ts<workspace>/.openclaw/extensions/*/index.ts
- Extensions globales
~/.openclaw/extensions/*.ts~/.openclaw/extensions/*/index.ts
- Extensions groupées (livrées avec OpenClaw, désactivées par défaut)
<openclaw>/extensions/*
Les plugins groupĂ©s doivent ĂȘtre activĂ©s explicitement via plugins.entries.<id>.enabled
ou openclaw plugins enable <id>. Les plugins installés sont activés par défaut,
mais peuvent ĂȘtre dĂ©sactivĂ©s de la mĂȘme maniĂšre.
Chaque plugin doit inclure un fichier openclaw.plugin.json Ă sa racine. Si un chemin
pointe vers un fichier, la racine du plugin est le répertoire du fichier et doit
contenir le manifeste.
Si plusieurs plugins se rĂ©solvent vers le mĂȘme id, la premiĂšre correspondance selon lâordre ci-dessus lâemporte et les copies de prioritĂ© infĂ©rieure sont ignorĂ©es.
Package packs¶
Un répertoire de plugin peut inclure un package.json avec openclaw.extensions :
{
"name": "my-pack",
"openclaw": {
"extensions": ["./src/safety.ts", "./src/tools.ts"]
}
}
Chaque entrĂ©e devient un plugin. Si le pack liste plusieurs extensions, lâid du plugin
devient name/<fileBase>.
Si votre plugin importe des dépendances npm, installez-les dans ce répertoire afin que
node_modules soit disponible (npm install / pnpm install).
Métadonnées du catalogue de canaux¶
Les plugins de canal peuvent annoncer des métadonnées de prise en main via openclaw.channel et
des indications dâinstallation via openclaw.install. Cela permet de garder le catalogue central sans donnĂ©es.
Exemple :
{
"name": "@openclaw/nextcloud-talk",
"openclaw": {
"extensions": ["./index.ts"],
"channel": {
"id": "nextcloud-talk",
"label": "Nextcloud Talk",
"selectionLabel": "Nextcloud Talk (self-hosted)",
"docsPath": "/channels/nextcloud-talk",
"docsLabel": "nextcloud-talk",
"blurb": "Self-hosted chat via Nextcloud Talk webhook bots.",
"order": 65,
"aliases": ["nc-talk", "nc"]
},
"install": {
"npmSpec": "@openclaw/nextcloud-talk",
"localPath": "extensions/nextcloud-talk",
"defaultChoice": "npm"
}
}
}
OpenClaw peut Ă©galement fusionner des catalogues de canaux externes (par exemple, un export de registre MPM). DĂ©posez un fichier JSON Ă lâun des emplacements suivants :
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
Ou pointez OPENCLAW_PLUGIN_CATALOG_PATHS (ou OPENCLAW_MPM_CATALOG_PATHS) vers
un ou plusieurs fichiers JSON (délimités par des virgules/points-virgules/PATH). Chaque fichier doit
contenir { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }.
IDs de plugin¶
IDs de plugin par défaut :
- Package packs :
package.jsonname - Fichier autonome : nom de base du fichier (
~/.../voice-call.tsâvoice-call)
Si un plugin exporte id, OpenClaw lâutilise mais avertit lorsquâil ne correspond pas Ă lâid configurĂ©.
Configuration¶
{
plugins: {
enabled: true,
allow: ["voice-call"],
deny: ["untrusted-plugin"],
load: { paths: ["~/Projects/oss/voice-call-extension"] },
entries: {
"voice-call": { enabled: true, config: { provider: "twilio" } },
},
},
}
Champs :
enabled: interrupteur principal (par dĂ©faut : true)allow: liste dâautorisation (optionnelle)deny: liste de refus (optionnelle ; le refus lâemporte)load.paths: fichiers/rĂ©pertoires de plugins supplĂ©mentairesentries.<id>: interrupteurs par plugin + configuration
Les modifications de configuration nécessitent un redémarrage de la gateway (passerelle).
RĂšgles de validation (strictes) :
- Les ids de plugin inconnus dans
entries,allow,denyouslotssont des erreurs. - Les clés
channels.<id>inconnues sont des erreurs, sauf si un manifeste de plugin dĂ©clare lâid de canal. - La configuration du plugin est validĂ©e Ă lâaide du schĂ©ma JSON intĂ©grĂ© dans
openclaw.plugin.json(configSchema). - Si un plugin est désactivé, sa configuration est conservée et un avertissement est émis.
Emplacements de plugin (catégories exclusives)¶
Certaines catégories de plugins sont exclusives (une seule active à la fois). Utilisez
plugins.slots pour sĂ©lectionner quel plugin possĂšde lâemplacement :
{
plugins: {
slots: {
memory: "memory-core", // or "none" to disable memory plugins
},
},
}
Si plusieurs plugins déclarent kind: "memory", seul celui sélectionné est chargé. Les autres
sont désactivés avec des diagnostics.
Interface de contrÎle (schéma + libellés)¶
Lâinterface de contrĂŽle utilise config.schema (schĂ©ma JSON + uiHints) pour afficher de meilleurs formulaires.
OpenClaw enrichit uiHints Ă lâexĂ©cution en fonction des plugins dĂ©couverts :
- Ajoute des libellés par plugin pour
plugins.entries.<id>/.enabled/.config - Fusionne des indications de champs de configuration optionnelles fournies par les plugins sous :
plugins.entries.<id>.config.<field>
Si vous souhaitez que les champs de configuration de votre plugin affichent de bons libellés/espaces réservés
(et marquent les secrets comme sensibles), fournissez uiHints à cÎté de votre schéma JSON
dans le manifeste du plugin.
Exemple :
{
"id": "my-plugin",
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {
"apiKey": { "type": "string" },
"region": { "type": "string" }
}
},
"uiHints": {
"apiKey": { "label": "API Key", "sensitive": true },
"region": { "label": "Region", "placeholder": "us-east-1" }
}
}
CLI¶
openclaw plugins list
openclaw plugins info <id>
openclaw plugins install <path> # copy a local file/dir into ~/.openclaw/extensions/<id>
openclaw plugins install ./extensions/voice-call # relative path ok
openclaw plugins install ./plugin.tgz # install from a local tarball
openclaw plugins install ./plugin.zip # install from a local zip
openclaw plugins install -l ./extensions/voice-call # link (no copy) for dev
openclaw plugins install @openclaw/voice-call # install from npm
openclaw plugins update <id>
openclaw plugins update --all
openclaw plugins enable <id>
openclaw plugins disable <id>
openclaw plugins doctor
plugins update fonctionne uniquement pour les installations npm suivies sous plugins.installs.
Les plugins peuvent également enregistrer leurs propres commandes de premier niveau (exemple : openclaw voicecall).
API de plugin (aperçu)¶
Les plugins exportent soit :
- Une fonction :
(api) => { ... } - Un objet :
{ id, name, configSchema, register(api) { ... } }
Hooks de plugin¶
Les plugins peuvent fournir des hooks et les enregistrer Ă lâexĂ©cution. Cela permet Ă un plugin dâintĂ©grer une automatisation pilotĂ©e par Ă©vĂ©nements sans installation sĂ©parĂ©e de pack de hooks.
Exemple¶
import { registerPluginHooksFromDir } from "openclaw/plugin-sdk";
export default function register(api) {
registerPluginHooksFromDir(api, "./hooks");
}
Remarques :
- Les répertoires de hooks suivent la structure normale des hooks (
HOOK.md+handler.ts). - Les rĂšgles dâĂ©ligibilitĂ© des hooks sâappliquent toujours (OS/binaires/variables d'environnement/exigences de configuration).
- Les hooks gérés par des plugins apparaissent dans
openclaw hooks listavecplugin:<id>. - Vous ne pouvez pas activer/désactiver les hooks gérés par des plugins via
openclaw hooks; activez/désactivez le plugin à la place.
Plugins de fournisseur (authentification de modÚle)¶
Les plugins peuvent enregistrer des flux dâauthentification de fournisseur de modĂšle afin que les utilisateurs puissent exĂ©cuter la configuration OAuth ou par clĂ© API dans OpenClaw (sans scripts externes).
Enregistrez un fournisseur via api.registerProvider(...). Chaque fournisseur expose une
ou plusieurs mĂ©thodes dâauthentification (OAuth, clĂ© API, code appareil, etc.). Ces mĂ©thodes alimentent :
openclaw models auth login --provider <id> [--method <id>]
Exemple :
api.registerProvider({
id: "acme",
label: "AcmeAI",
auth: [
{
id: "oauth",
label: "OAuth",
kind: "oauth",
run: async (ctx) => {
// Run OAuth flow and return auth profiles.
return {
profiles: [
{
profileId: "acme:default",
credential: {
type: "oauth",
provider: "acme",
access: "...",
refresh: "...",
expires: Date.now() + 3600 * 1000,
},
},
],
defaultModel: "acme/opus-1",
};
},
},
],
});
Remarques :
runreçoit unProviderAuthContextavec des aidesprompter,runtime,openUrletoauth.createVpsAwareHandlers.- Retournez
configPatchlorsque vous devez ajouter des modÚles par défaut ou une configuration de fournisseur. - Retournez
defaultModelafin que--set-defaultpuisse mettre Ă jour les valeurs par dĂ©faut de lâagent.
Enregistrer un canal de messagerie¶
Les plugins peuvent enregistrer des plugins de canal qui se comportent comme des canaux intégrés
(WhatsApp, Telegram, etc.). La configuration du canal se trouve sous channels.<id> et est
validée par le code de votre plugin de canal.
const myChannel = {
id: "acmechat",
meta: {
id: "acmechat",
label: "AcmeChat",
selectionLabel: "AcmeChat (API)",
docsPath: "/channels/acmechat",
blurb: "demo channel plugin.",
aliases: ["acme"],
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
resolveAccount: (cfg, accountId) =>
cfg.channels?.acmechat?.accounts?.[accountId ?? "default"] ?? {
accountId,
},
},
outbound: {
deliveryMode: "direct",
sendText: async () => ({ ok: true }),
},
};
export default function (api) {
api.registerChannel({ plugin: myChannel });
}
Remarques :
- Placez la configuration sous
channels.<id>(pasplugins.entries). meta.labelest utilisĂ© pour les libellĂ©s dans les listes CLI/UI.meta.aliasesajoute des ids alternatifs pour la normalisation et les entrĂ©es CLI.meta.preferOverliste les ids de canal Ă ignorer pour lâactivation automatique lorsque les deux sont configurĂ©s.meta.detailLabeletmeta.systemImagepermettent aux interfaces dâafficher des libellĂ©s/icĂŽnes de canal plus riches.
Ăcrire un nouveau canal de messagerie (Ă©tape par Ă©tape)¶
Utilisez ceci lorsque vous souhaitez une nouvelle surface de discussion (un « canal de messagerie »), et non un fournisseur de modÚle.
La documentation des fournisseurs de modĂšle se trouve sous /providers/*.
- Choisir un id + une forme de configuration
- Toute la configuration du canal se trouve sous
channels.<id>. - Préférez
channels.<id>.accounts.<accountId>pour les configurations multiâcomptes.
- Définir les métadonnées du canal
meta.label,meta.selectionLabel,meta.docsPath,meta.blurbcontrĂŽlent les listes CLI/UI.meta.docsPathdoit pointer vers une page de documentation comme/channels/<id>.meta.preferOverpermet Ă un plugin de remplacer un autre canal (lâactivation automatique le privilĂ©gie).meta.detailLabeletmeta.systemImagesont utilisĂ©s par les interfaces pour le texte/icĂŽnes de dĂ©tail.
- Implémenter les adaptateurs requis
config.listAccountIds+config.resolveAccountcapabilities(types de chat, mĂ©dias, fils, etc.)outbound.deliveryMode+outbound.sendText(pour lâenvoi de base)
- Ajouter des adaptateurs optionnels selon les besoins
setup(assistant),security(politique de message privĂ©),status(santĂ©/diagnostics)gateway(dĂ©marrer/arrĂȘter/connexion),mentions,threading,streamingactions(actions sur les messages),commands(comportement des commandes natives)
- Enregistrer le canal dans votre plugin
api.registerChannel({ plugin })
Exemple de configuration minimale :
{
channels: {
acmechat: {
accounts: {
default: { token: "ACME_TOKEN", enabled: true },
},
},
},
}
Plugin de canal minimal (sortant uniquement) :
const plugin = {
id: "acmechat",
meta: {
id: "acmechat",
label: "AcmeChat",
selectionLabel: "AcmeChat (API)",
docsPath: "/channels/acmechat",
blurb: "AcmeChat messaging channel.",
aliases: ["acme"],
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
resolveAccount: (cfg, accountId) =>
cfg.channels?.acmechat?.accounts?.[accountId ?? "default"] ?? {
accountId,
},
},
outbound: {
deliveryMode: "direct",
sendText: async ({ text }) => {
// deliver `text` to your channel here
return { ok: true };
},
},
};
export default function (api) {
api.registerChannel({ plugin });
}
Chargez le plugin (rĂ©pertoire dâextensions ou plugins.load.paths), redĂ©marrez la gateway (passerelle),
puis configurez channels.<id> dans votre configuration.
Outils dâagent¶
Voir le guide dédié : Plugin agent tools.
Enregistrer une méthode RPC de la gateway (passerelle)¶
export default function (api) {
api.registerGatewayMethod("myplugin.status", ({ respond }) => {
respond(true, { ok: true });
});
}
Enregistrer des commandes CLI¶
export default function (api) {
api.registerCli(
({ program }) => {
program.command("mycmd").action(() => {
console.log("Hello");
});
},
{ commands: ["mycmd"] },
);
}
Enregistrer des commandes de réponse automatique¶
Les plugins peuvent enregistrer des commandes slash personnalisĂ©es qui sâexĂ©cutent sans invoquer lâagent IA. Câest utile pour les commandes de bascule, les vĂ©rifications dâĂ©tat ou les actions rapides qui ne nĂ©cessitent pas de traitement par LLM.
export default function (api) {
api.registerCommand({
name: "mystatus",
description: "Show plugin status",
handler: (ctx) => ({
text: `Plugin is running! Channel: ${ctx.channel}`,
}),
});
}
Contexte du gestionnaire de commande :
senderId: lâid de lâexpĂ©diteur (si disponible)channel: le canal oĂč la commande a Ă©tĂ© envoyĂ©eisAuthorizedSender: si lâexpĂ©diteur est un utilisateur autorisĂ©args: arguments passĂ©s aprĂšs la commande (siacceptsArgs: true)commandBody: le texte complet de la commandeconfig: la configuration OpenClaw actuelle
Options de commande :
name: nom de la commande (sans le/initial)description: texte dâaide affichĂ© dans les listes de commandesacceptsArgs: indique si la commande accepte des arguments (par dĂ©faut : false). Si false et que des arguments sont fournis, la commande ne correspondra pas et le message sera transmis aux autres gestionnairesrequireAuth: indique sâil faut exiger un expĂ©diteur autorisĂ© (par dĂ©faut : true)handler: fonction qui retourne{ text: string }(peut ĂȘtre async)
Exemple avec autorisation et arguments :
api.registerCommand({
name: "setmode",
description: "Set plugin mode",
acceptsArgs: true,
requireAuth: true,
handler: async (ctx) => {
const mode = ctx.args?.trim() || "default";
await saveMode(mode);
return { text: `Mode set to: ${mode}` };
},
});
Remarques :
- Les commandes de plugin sont traitĂ©es avant les commandes intĂ©grĂ©es et lâagent IA
- Les commandes sont enregistrées globalement et fonctionnent sur tous les canaux
- Les noms de commande sont insensibles Ă la casse (
/MyStatuscorrespond Ă/mystatus) - Les noms de commande doivent commencer par une lettre et ne contenir que des lettres, chiffres, tirets et underscores
- Les noms de commande réservés (comme
help,status,reset, etc.) ne peuvent pas ĂȘtre redĂ©finis par des plugins - Lâenregistrement de commandes en double entre plugins Ă©chouera avec une erreur de diagnostic
Enregistrer des services en arriÚre-plan¶
export default function (api) {
api.registerService({
id: "my-service",
start: () => api.logger.info("ready"),
stop: () => api.logger.info("bye"),
});
}
Conventions de nommage¶
- Méthodes de la Gateway (passerelle) :
pluginId.action(exemple :voicecall.status) - Outils :
snake_case(exemple :voice_call) - Commandes CLI : kebab ou camel, mais Ă©vitez les conflits avec les commandes du cĆur
Skills¶
Les plugins peuvent fournir un skill dans le dépÎt (skills/<name>/SKILL.md).
Activez-le avec plugins.entries.<id>.enabled (ou dâautres verrous de configuration) et assurez-vous
quâil est prĂ©sent dans les emplacements de skills de votre espace de travail/skills gĂ©rĂ©s.
Distribution (npm)¶
Conditionnement recommandé :
- Paquet principal :
openclaw(ce dépÎt) - Plugins : paquets npm séparés sous
@openclaw/*(exemple :@openclaw/voice-call)
Contrat de publication :
- Le
package.jsondu plugin doit inclureopenclaw.extensionsavec un ou plusieurs fichiers dâentrĂ©e. - Les fichiers dâentrĂ©e peuvent ĂȘtre
.jsou.ts(jiti charge TS Ă lâexĂ©cution). openclaw plugins install <npm-spec>utilisenpm pack, extrait dans~/.openclaw/extensions/<id>/et lâactive dans la configuration.- StabilitĂ© des clĂ©s de configuration : les paquets scopĂ©s sont normalisĂ©s vers lâid non scopĂ© pour
plugins.entries.*.
Exemple de plugin : Voice Call¶
Ce dĂ©pĂŽt inclut un plugin dâappel vocal (Twilio ou repli sur journalisation) :
- Source :
extensions/voice-call - Skill :
skills/voice-call - CLI :
openclaw voicecall start|status - Outil :
voice_call - RPC :
voicecall.start,voicecall.status - Configuration (twilio) :
provider: "twilio"+twilio.accountSid/authToken/from(statusCallbackUrl,twimlUrloptionnels) - Configuration (dev) :
provider: "log"(sans réseau)
Voir Voice Call et extensions/voice-call/README.md pour lâinstallation et lâutilisation.
Remarques de sécurité¶
Les plugins sâexĂ©cutent dans le mĂȘme processus que la Gateway (passerelle). Traitez-les comme du code de confiance :
- Nâinstallez que des plugins de confiance.
- PrĂ©fĂ©rez les listes dâautorisation
plugins.allow. - Redémarrez la Gateway (passerelle) aprÚs les modifications.
Tester les plugins¶
Les plugins peuvent (et doivent) fournir des tests :
- Les plugins dans le dépÎt peuvent conserver des tests Vitest sous
src/**(exemple :src/plugins/voice-call.plugin.test.ts). - Les plugins publiés séparément doivent exécuter leur propre CI (lint/build/test) et valider que
openclaw.extensionspointe vers le point dâentrĂ©e compilĂ© (dist/index.js).