Plugins (Extensies)¶
Snelle start (nieuw met plugins?)¶
Een plugin is gewoon een kleine codemodule die OpenClaw uitbreidt met extra functies (opdrachten, tools en Gateway RPC).
Meestal gebruik je plugins wanneer je een functie wilt die nog niet in de kern van OpenClaw zit (of wanneer je optionele functies buiten je hoofdinstallatie wilt houden).
Snelle route:
- Bekijk wat er al is geladen:
openclaw plugins list
- Installeer een officiële plugin (voorbeeld: Voice Call):
openclaw plugins install @openclaw/voice-call
- Herstart de Gateway en configureer vervolgens onder
plugins.entries.<id>.config.
Zie Voice Call voor een concreet voorbeeld van een plugin.
Beschikbare plugins (officieel)¶
- Microsoft Teams is sinds 2026.1.15 alleen via een plugin beschikbaar; installeer
@openclaw/msteamsals je Teams gebruikt. - Memory (Core) — gebundelde geheugenzoekplugin (standaard ingeschakeld via
plugins.slots.memory) - Memory (LanceDB) — gebundelde langetermijngeheugenplugin (automatisch ophalen/vastleggen; stel
plugins.slots.memory = "memory-lancedb"in) - 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 (provider-authenticatie) — gebundeld als
google-antigravity-auth(standaard uitgeschakeld) - Gemini CLI OAuth (provider-authenticatie) — gebundeld als
google-gemini-cli-auth(standaard uitgeschakeld) - Qwen OAuth (provider-authenticatie) — gebundeld als
qwen-portal-auth(standaard uitgeschakeld) - Copilot Proxy (provider-authenticatie) — lokale VS Code Copilot Proxy-bridge; onderscheiden van ingebouwde
github-copilotapparaatlogin (gebundeld, standaard uitgeschakeld)
OpenClaw-plugins zijn TypeScript-modules die tijdens runtime via jiti worden geladen. Configuratievalidatie voert geen plugincode uit; deze gebruikt in plaats daarvan het pluginmanifest en JSON Schema. Zie Plugin manifest.
Plugins kunnen registreren:
- Gateway RPC-methoden
- Gateway HTTP-handlers
- Agent-tools
- CLI-opdrachten
- Achtergronddiensten
- Optionele configuratievalidatie
- Skills (door
skills-mappen te vermelden in het pluginmanifest) - Auto-reply-opdrachten (uitgevoerd zonder de AI-agent aan te roepen)
Plugins draaien in-process met de Gateway, dus behandel ze als vertrouwde code. Handleiding voor tool-ontwikkeling: Plugin agent tools.
Runtime-hulpmiddelen¶
Plugins hebben toegang tot geselecteerde kernhulpmiddelen via api.runtime. Voor telefonie-TTS:
const result = await api.runtime.tts.textToSpeechTelephony({
text: "Hello from OpenClaw",
cfg: api.config,
});
Notities:
- Gebruikt de kernconfiguratie
messages.tts(OpenAI of ElevenLabs). - Retourneert een PCM-audiobuffer + sample rate. Plugins moeten zelf resamplen/encoderen voor providers.
- Edge TTS wordt niet ondersteund voor telefonie.
Discovery & prioriteit¶
OpenClaw scant, in volgorde:
- Config-paden
plugins.load.paths(bestand of map)
- Werkruimte-extensies
<workspace>/.openclaw/extensions/*.ts<workspace>/.openclaw/extensions/*/index.ts
- Globale extensies
~/.openclaw/extensions/*.ts~/.openclaw/extensions/*/index.ts
- Gebundelde extensies (meegeleverd met OpenClaw, standaard uitgeschakeld)
<openclaw>/extensions/*
Gebundelde plugins moeten expliciet worden ingeschakeld via plugins.entries.<id>.enabled
of openclaw plugins enable <id>. Geïnstalleerde plugins zijn standaard ingeschakeld,
maar kunnen op dezelfde manier worden uitgeschakeld.
Elke plugin moet een openclaw.plugin.json-bestand in de root bevatten. Als een pad
naar een bestand wijst, is de plugin-root de map van dat bestand en moet deze
het manifest bevatten.
Als meerdere plugins naar dezelfde id resolven, wint de eerste overeenkomst in bovenstaande volgorde en worden kopieën met lagere prioriteit genegeerd.
Package packs¶
Een pluginmap kan een package.json bevatten met openclaw.extensions:
{
"name": "my-pack",
"openclaw": {
"extensions": ["./src/safety.ts", "./src/tools.ts"]
}
}
Elke entry wordt een plugin. Als het pack meerdere extensies vermeldt, wordt de plugin-id
name/<fileBase>.
Als je plugin npm-afhankelijkheden importeert, installeer deze dan in die map zodat
node_modules beschikbaar is (npm install / pnpm install).
Kanaalcatalogus-metadata¶
Kanaalplugins kunnen onboarding-metadata adverteren via openclaw.channel en
installatiehints via openclaw.install. Dit houdt de kerncatalogus vrij van data.
Voorbeeld:
{
"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 kan ook externe kanaalcatalogi samenvoegen (bijvoorbeeld een MPM- registry-export). Plaats een JSON-bestand op een van:
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
Of wijs OPENCLAW_PLUGIN_CATALOG_PATHS (of OPENCLAW_MPM_CATALOG_PATHS) naar
een of meer JSON-bestanden (gescheiden door komma/komma-puntkomma/PATH). Elk bestand moet
{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] } bevatten.
Plugin-ID’s¶
Standaard plugin-id’s:
- Package packs:
package.jsonname - Losstaand bestand: bestandsbasisnaam (
~/.../voice-call.ts→voice-call)
Als een plugin id exporteert, gebruikt OpenClaw deze maar waarschuwt
wanneer deze niet overeenkomt met de geconfigureerde id.
Configuratie¶
{
plugins: {
enabled: true,
allow: ["voice-call"],
deny: ["untrusted-plugin"],
load: { paths: ["~/Projects/oss/voice-call-extension"] },
entries: {
"voice-call": { enabled: true, config: { provider: "twilio" } },
},
},
}
Velden
enabled: hoofdswitch (standaard: true)allow: toegestane lijst (optioneel)deny: denylist (optioneel; deny wint)load.paths: extra pluginbestanden/-mappenentries.<id>: per-plugin schakelaars + configuratie
Configuratiewijzigingen vereisen een Gateway-herstart.
Validatieregels (streng):
- Onbekende plugin-id’s in
entries,allow,denyofslotszijn fouten. - Onbekende
channels.<id>-sleutels zijn fouten, tenzij een pluginmanifest de kanaal-id declareert. - Pluginconfiguratie wordt gevalideerd met het JSON Schema dat is ingesloten in
openclaw.plugin.json(configSchema). - Als een plugin is uitgeschakeld, blijft de configuratie behouden en wordt een waarschuwing gegeven.
Plugin-slots (exclusieve categorieën)¶
Sommige plugincategorieën zijn exclusief (slechts één tegelijk actief). Gebruik
plugins.slots om te selecteren welke plugin het slot bezit:
{
plugins: {
slots: {
memory: "memory-core", // or "none" to disable memory plugins
},
},
}
Als meerdere plugins kind: "memory" declareren, wordt alleen de geselecteerde geladen. De andere worden uitgeschakeld met diagnostische meldingen.
Control UI (schema + labels)¶
De Control UI gebruikt config.schema (JSON Schema + uiHints) om betere formulieren te renderen.
OpenClaw breidt uiHints tijdens runtime uit op basis van ontdekte plugins:
- Voegt per-plugin labels toe voor
plugins.entries.<id>/.enabled/.config - Voegt optionele, door plugins aangeleverde hints voor configuratievelden samen onder:
plugins.entries.<id>.config.<field>
Als je wilt dat je pluginconfiguratievelden goede labels/plaats-houders tonen (en geheimen als gevoelig markeren),
lever dan uiHints mee naast je JSON Schema in het pluginmanifest.
Voorbeeld:
{
"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 werkt alleen voor npm-installaties die worden bijgehouden onder plugins.installs.
Plugins kunnen ook hun eigen top-level opdrachten registreren (voorbeeld: openclaw voicecall).
Plugin-API (overzicht)¶
Plugins exporteren óf:
- Een functie:
(api) => { ... } - Een object:
{ id, name, configSchema, register(api) { ... } }
Plugin-hooks¶
Plugins kunnen hooks meeleveren en deze tijdens runtime registreren. Hiermee kan een plugin event-gedreven automatisering bundelen zonder een aparte hook-pack-installatie.
Voorbeeld¶
import { registerPluginHooksFromDir } from "openclaw/plugin-sdk";
export default function register(api) {
registerPluginHooksFromDir(api, "./hooks");
}
Notities:
- Hook-mappen volgen de normale hook-structuur (
HOOK.md+handler.ts). - Regels voor hook-geschiktheid blijven van toepassing (OS/binaries/omgevings-/configvereisten).
- Door plugins beheerde hooks verschijnen in
openclaw hooks listmetplugin:<id>. - Je kunt door plugins beheerde hooks niet in-/uitschakelen via
openclaw hooks; schakel in plaats daarvan de plugin in/uit.
Provider-plugins (modelauthenticatie)¶
Plugins kunnen modelprovider-authenticatie-flows registreren zodat gebruikers OAuth of API-sleutel-installatie binnen OpenClaw kunnen uitvoeren (geen externe scripts nodig).
Registreer een provider via api.registerProvider(...). Elke provider stelt een of meer
auth-methoden beschikbaar (OAuth, API-sleutel, apparaatcode, enz.). Deze methoden voeden:
openclaw models auth login --provider <id> [--method <id>]
Voorbeeld:
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",
};
},
},
],
});
Notities:
runontvangt eenProviderAuthContextmetprompter,runtime,openUrlenoauth.createVpsAwareHandlers-hulpmiddelen.- Retourneer
configPatchwanneer je standaardmodellen of providerconfiguratie moet toevoegen. - Retourneer
defaultModelzodat--set-defaultde agent-standaardwaarden kan bijwerken.
Een messagingkanaal registreren¶
Plugins kunnen kanaalplugins registreren die zich gedragen als ingebouwde kanalen
(WhatsApp, Telegram, enz.). Kanaalconfiguratie staat onder channels.<id> en wordt
gevalideerd door je kanaalplugincode.
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 });
}
Notities:
- Plaats configuratie onder
channels.<id>(nietplugins.entries). meta.labelwordt gebruikt voor labels in CLI/UI-lijsten.meta.aliasesvoegt alternatieve id’s toe voor normalisatie en CLI-invoer.meta.preferOververmeldt kanaal-id’s die automatisch inschakelen moeten overslaan wanneer beide zijn geconfigureerd.meta.detailLabelenmeta.systemImagestellen UI’s in staat rijkere kanaallabels/iconen te tonen.
Een nieuw messagingkanaal schrijven (stap-voor-stap)¶
Gebruik dit wanneer je een nieuw chatoppervlak (een “messagingkanaal”) wilt, geen modelprovider.
Documentatie voor modelproviders staat onder /providers/*.
- Kies een id + configuratievorm
- Alle kanaalconfiguratie staat onder
channels.<id>. - Geef de voorkeur aan
channels.<id>.accounts.<accountId>voor multi-accountopstellingen.
- Definieer de kanaalmetadata
meta.label,meta.selectionLabel,meta.docsPath,meta.blurbbepalen CLI/UI-lijsten.meta.docsPathmoet verwijzen naar een documentatiepagina zoals/channels/<id>.meta.preferOverlaat een plugin een ander kanaal vervangen (auto-inschakelen geeft er de voorkeur aan).meta.detailLabelenmeta.systemImageworden door UI’s gebruikt voor detailtekst/iconen.
- Implementeer de vereiste adapters
config.listAccountIds+config.resolveAccountcapabilities(chattypes, media, threads, enz.)outbound.deliveryMode+outbound.sendText(voor basisverzending)
- Voeg optionele adapters toe indien nodig
setup(wizard),security(DM-beleid),status(gezondheid/diagnostiek)gateway(start/stop/login),mentions,threading,streamingactions(berichtacties),commands(native opdrachtgedrag)
- Registreer het kanaal in je plugin
api.registerChannel({ plugin })
Minimaal configuratievoorbeeld:
{
channels: {
acmechat: {
accounts: {
default: { token: "ACME_TOKEN", enabled: true },
},
},
},
}
Minimale kanaalplugin (alleen uitgaand):
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 });
}
Laad de plugin (extensions-map of plugins.load.paths), herstart de Gateway
en configureer vervolgens channels.<id> in je configuratie.
Agent-tools¶
Zie de aparte handleiding: Plugin agent tools.
Een gateway RPC-methode registreren¶
export default function (api) {
api.registerGatewayMethod("myplugin.status", ({ respond }) => {
respond(true, { ok: true });
});
}
CLI-opdrachten registreren¶
export default function (api) {
api.registerCli(
({ program }) => {
program.command("mycmd").action(() => {
console.log("Hello");
});
},
{ commands: ["mycmd"] },
);
}
Auto-reply-opdrachten registreren¶
Plugins kunnen aangepaste slash-opdrachten registreren die worden uitgevoerd zonder de AI-agent aan te roepen. Dit is handig voor toggle-opdrachten, statuscontroles of snelle acties die geen LLM-verwerking nodig hebben.
export default function (api) {
api.registerCommand({
name: "mystatus",
description: "Show plugin status",
handler: (ctx) => ({
text: `Plugin is running! Channel: ${ctx.channel}`,
}),
});
}
Context van de opdrachthandler:
senderId: De ID van de afzender (indien beschikbaar)channel: Het kanaal waarin de opdracht is verzondenisAuthorizedSender: Of de afzender een geautoriseerde gebruiker isargs: Argumenten die na de opdracht zijn doorgegeven (indienacceptsArgs: true)commandBody: De volledige opdrachttekstconfig: De huidige OpenClaw-configuratie
Opdrachtopties:
name: Opdrachtnaam (zonder de voorloop-/)description: Hulptekst die in opdrachtoverzichten wordt getoondacceptsArgs: Of de opdracht argumenten accepteert (standaard: false). Als false en er argumenten worden opgegeven, matcht de opdracht niet en valt het bericht door naar andere handlersrequireAuth: Of een geautoriseerde afzender vereist is (standaard: true)handler: Functie die{ text: string }retourneert (kan async zijn)
Voorbeeld met autorisatie en argumenten:
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}` };
},
});
Notities:
- Pluginopdrachten worden vóór ingebouwde opdrachten en de AI-agent verwerkt
- Opdrachten worden globaal geregistreerd en werken over alle kanalen
- Opdrachtnamen zijn niet hoofdlettergevoelig (
/MyStatusmatcht/mystatus) - Opdrachtnamen moeten met een letter beginnen en mogen alleen letters, cijfers, koppeltekens en underscores bevatten
- Gereserveerde opdrachtnamen (zoals
help,status,reset, enz.) kunnen niet door plugins worden overschreven - Dubbele opdrachtregistratie over plugins heen faalt met een diagnostische fout
Achtergronddiensten registreren¶
export default function (api) {
api.registerService({
id: "my-service",
start: () => api.logger.info("ready"),
stop: () => api.logger.info("bye"),
});
}
Naamgevingsconventies¶
- Gateway-methoden:
pluginId.action(voorbeeld:voicecall.status) - Tools:
snake_case(voorbeeld:voice_call) - CLI-opdrachten: kebab of camel, maar vermijd conflicten met kernopdrachten
Skills¶
Plugins kunnen een skill in de repo meeleveren (skills/<name>/SKILL.md).
Schakel deze in met plugins.entries.<id>.enabled (of andere configuratiepoorten) en zorg
dat deze aanwezig is in je werkruimte-/beheerde skills-locaties.
Distributie (npm)¶
Aanbevolen packaging:
- Hoofdpakket:
openclaw(deze repo) - Plugins: afzonderlijke npm-pakketten onder
@openclaw/*(voorbeeld:@openclaw/voice-call)
Publicatiecontract:
- Plugin
package.jsonmoetopenclaw.extensionsbevatten met een of meer entrybestanden. - Entrybestanden kunnen
.jsof.tszijn (jiti laadt TS tijdens runtime). openclaw plugins install <npm-spec>gebruiktnpm pack, extraheert naar~/.openclaw/extensions/<id>/en schakelt het in via config.- Stabiliteit van configsleutels: scoped packages worden genormaliseerd naar de ongescopte id voor
plugins.entries.*.
Voorbeeldplugin: Voice Call¶
Deze repo bevat een voice-call-plugin (Twilio of log-fallback):
- Bron:
extensions/voice-call - Skill:
skills/voice-call - CLI:
openclaw voicecall start|status - Tool:
voice_call - RPC:
voicecall.start,voicecall.status - Config (twilio):
provider: "twilio"+twilio.accountSid/authToken/from(optioneelstatusCallbackUrl,twimlUrl) - Config (dev):
provider: "log"(geen netwerk)
Zie Voice Call en extensions/voice-call/README.md voor installatie en gebruik.
Veiligheidsnotities¶
Plugins draaien in-process met de Gateway. Behandel ze als vertrouwde code:
- Installeer alleen plugins die je vertrouwt.
- Geef de voorkeur aan
plugins.allowtoegestane lijsten. - Herstart de Gateway na wijzigingen.
Plugins testen¶
Plugins kunnen (en zouden) tests meeleveren:
- In-repo plugins kunnen Vitest-tests onder
src/**plaatsen (voorbeeld:src/plugins/voice-call.plugin.test.ts). - Afzonderlijk gepubliceerde plugins moeten hun eigen CI draaien (lint/build/test) en valideren dat
openclaw.extensionsnaar het gebouwde entrypoint wijst (dist/index.js).