Plugins

Plugins bouwen

Plugins breiden OpenClaw uit met nieuwe mogelijkheden: kanalen, modelproviders, spraak, realtime transcriptie, realtime spraak, mediabegrip, afbeeldingsgeneratie, videogeneratie, web-fetch, webzoekopdrachten, agenttools of elke combinatie.

Je hoeft je Plugin niet toe te voegen aan de OpenClaw-repository. Publiceer naar ClawHub en gebruikers installeren met openclaw plugins install clawhub:<package-name>. Kale pakketspecificaties installeren tijdens de lanceringsomschakeling nog steeds vanaf npm.

Vereisten

  • Node >= 22 en een pakketbeheerder (npm of pnpm)
  • Bekendheid met TypeScript (ESM)
  • Voor Plugins in de repository: repository gekloond en pnpm install uitgevoerd. Ontwikkeling van Plugins vanuit een source-checkout is alleen pnpm, omdat OpenClaw gebundelde Plugins laadt uit de extensions/*-workspacepakketten.

Wat voor soort Plugin?

Gebruik voor een kanaalplugin waarvan niet gegarandeerd is dat die is geïnstalleerd wanneer onboarding/setup wordt uitgevoerd createOptionalChannelSetupSurface(...) uit openclaw/plugin-sdk/channel-setup. Dit produceert een setupadapter + wizardpaar dat de installatievereiste aangeeft en veilig faalt bij echte configuratieschrijfbewerkingen totdat de Plugin is geïnstalleerd.

Snelstart: toolplugin

Deze walkthrough maakt een minimale Plugin die een agenttool registreert. Kanaal- en providerplugins hebben eigen gidsen die hierboven zijn gelinkt.

  • Maak het pakket en het 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
    }
    }
    

    Elke Plugin heeft een manifest nodig, zelfs zonder configuratie. Tools die tijdens runtime worden geregistreerd moeten worden vermeld in contracts.tools, zodat OpenClaw de eigenaar- Plugin kan ontdekken zonder elke Plugin-runtime te laden. Plugins moeten ook activation.onStartup bewust declareren. Dit voorbeeld stelt het in op true. Zie Manifest voor het volledige schema. De canonieke ClawHub- publicatiesnippets staan in docs/snippets/plugin-publish/.

  • Schrijf het entrypoint

    // 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 is voor niet-kanaalplugins. Gebruik voor kanalen defineChannelPluginEntry - zie Kanaalplugins. Zie Entrypoints voor alle entrypointopties.

  • Test en publiceer

    Externe Plugins: valideer en publiceer met ClawHub, en installeer daarna:

    clawhub package publish your-org/your-plugin --dry-run
    clawhub package publish your-org/your-plugin
    openclaw plugins install clawhub:@myorg/openclaw-my-plugin
    

    Kale pakketspecificaties zoals @myorg/openclaw-my-plugin installeren tijdens de lanceringsomschakeling vanaf npm. Gebruik clawhub: wanneer je ClawHub-resolutie wilt.

    Plugins in de repository: plaats ze onder de gebundelde Plugin-workspaceboom - ze worden automatisch ontdekt.

    pnpm test -- <bundled-plugin-root>/my-plugin/
    
  • Pluginmogelijkheden

    Een enkele Plugin kan elk aantal mogelijkheden registreren via het api-object:

    Mogelijkheid Registratiemethode Gedetailleerde gids
    Tekstinferentie (LLM) api.registerProvider(...) Providerplugins
    CLI-inferentiebackend api.registerCliBackend(...) CLI-backends
    Kanaal / berichten api.registerChannel(...) Kanaalplugins
    Spraak (TTS/STT) api.registerSpeechProvider(...) Providerplugins
    Realtime transcriptie api.registerRealtimeTranscriptionProvider(...) Providerplugins
    Realtime spraak api.registerRealtimeVoiceProvider(...) Providerplugins
    Mediabegrip api.registerMediaUnderstandingProvider(...) Providerplugins
    Afbeeldingsgeneratie api.registerImageGenerationProvider(...) Providerplugins
    Muziekgeneratie api.registerMusicGenerationProvider(...) Providerplugins
    Videogeneratie api.registerVideoGenerationProvider(...) Providerplugins
    Web-fetch api.registerWebFetchProvider(...) Providerplugins
    Webzoekopdracht api.registerWebSearchProvider(...) Providerplugins
    Toolresultaatmiddleware api.registerAgentToolResultMiddleware(...) SDK-overzicht
    Agenttools api.registerTool(...) Hieronder
    Aangepaste opdrachten api.registerCommand(...) Entrypoints
    Plugin hooks api.on(...) Plugin hooks
    Interne event hooks api.registerHook(...) Entrypoints
    HTTP-routes api.registerHttpRoute(...) Internals
    CLI-subopdrachten api.registerCli(...) Entrypoints

    Zie SDK-overzicht voor de volledige registratie-API.

    Gebundelde Plugins kunnen api.registerAgentToolResultMiddleware(...) gebruiken wanneer ze asynchrone herschrijving van toolresultaten nodig hebben voordat het model de output ziet. Declareer de gerichte runtimes in contracts.agentToolResultMiddleware, bijvoorbeeld ["pi", "codex"]. Dit is een vertrouwde seam voor gebundelde Plugins; externe Plugins moeten reguliere OpenClaw Plugin hooks gebruiken, tenzij OpenClaw een expliciet vertrouwensbeleid voor deze mogelijkheid krijgt.

    Als je Plugin aangepaste Gateway-RPC-methoden registreert, houd ze dan op een Plugin-specifiek prefix. Core-adminnamespaces (config.*, exec.approvals.*, wizard.*, update.*) blijven gereserveerd en verwijzen altijd naar operator.admin, zelfs als een Plugin om een smallere scope vraagt.

    Hook-guardsemantiek om in gedachten te houden:

    • before_tool_call: { block: true } is terminaal en stopt handlers met lagere prioriteit.
    • before_tool_call: { block: false } wordt behandeld als geen beslissing.
    • before_tool_call: { requireApproval: true } pauzeert agentuitvoering en vraagt de gebruiker om goedkeuring via de exec-goedkeuringsoverlay, Telegram-knoppen, Discord-interacties of de opdracht /approve op elk kanaal.
    • before_install: { block: true } is terminaal en stopt handlers met lagere prioriteit.
    • before_install: { block: false } wordt behandeld als geen beslissing.
    • message_sending: { cancel: true } is terminaal en stopt handlers met lagere prioriteit.
    • message_sending: { cancel: false } wordt behandeld als geen beslissing.
    • message_received: geef de voorkeur aan het getypte veld threadId wanneer je routering van inkomende threads/topics nodig hebt. Bewaar metadata voor kanaalspecifieke extra's.
    • message_sending: geef de voorkeur aan getypte routeringsvelden replyToId / threadId boven kanaalspecifieke metadatakeys.

    De opdracht /approve verwerkt zowel exec- als Plugin-goedkeuringen met begrensde fallback: wanneer een exec-goedkeurings-id niet wordt gevonden, probeert OpenClaw dezelfde id opnieuw via Plugin-goedkeuringen. Het doorsturen van Plugin-goedkeuringen kan onafhankelijk worden geconfigureerd via approvals.plugin in de configuratie.

    Als aangepaste goedkeuringsplumbing diezelfde begrensde fallbackcase moet detecteren, gebruik dan bij voorkeur isApprovalNotFoundError uit openclaw/plugin-sdk/error-runtime in plaats van handmatig approval-expiry-strings te matchen.

    Zie Plugin hooks voor voorbeelden en de hookreferentie.

    Agenttools registreren

    Tools zijn getypte functies die de LLM kan aanroepen. Ze kunnen vereist zijn (altijd beschikbaar) of optioneel (opt-in door gebruiker):

    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 },
      );
    }
    

    Elke tool die met api.registerTool(...) wordt geregistreerd, moet ook worden gedeclareerd in het Plugin-manifest:

    {
      "contracts": {
        "tools": ["my_tool", "workflow_tool"]
      },
      "toolMetadata": {
        "workflow_tool": {
          "optional": true
        }
      }
    }
    

    OpenClaw legt de gevalideerde descriptor van de geregistreerde tool vast en cachet deze, zodat plugins geen description- of schemagegevens in het manifest dupliceren. Het manifestcontract verklaart alleen eigendom en vindbaarheid; uitvoering roept nog steeds de live geregistreerde toolimplementatie aan. Stel toolMetadata.<tool>.optional: true in voor tools die zijn geregistreerd met api.registerTool(..., { optional: true }), zodat OpenClaw kan voorkomen dat die plugin-runtime wordt geladen totdat de tool expliciet is toegestaan.

    Gebruikers schakelen optionele tools in de configuratie in:

    {
      tools: { allow: ["workflow_tool"] },
    }
    
    • Toolnamen mogen niet botsen met kerntools (conflicten worden overgeslagen)
    • Tools met misvormde registratieobjecten, inclusief ontbrekende parameters, worden overgeslagen en gemeld in plugin-diagnostiek in plaats van agent-runs te onderbreken
    • Gebruik optional: true voor tools met neveneffecten of extra binaire vereisten
    • Gebruikers kunnen alle tools van een plugin inschakelen door de plugin-id toe te voegen aan tools.allow

    CLI-opdrachten registreren

    Plugins kunnen hoofdgroepen voor openclaw-opdrachten toevoegen met api.registerCli. Geef descriptors op voor elke opdrachtroot op het hoogste niveau, zodat OpenClaw de opdracht kan tonen en routeren zonder elke plugin-runtime vooraf te laden.

    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,
            },
          ],
        },
      );
    }
    

    Verifieer na installatie de runtime-registratie en voer de opdracht uit:

    openclaw plugins inspect demo-plugin --runtime --json
    openclaw demo-plugin ping
    

    Importconventies

    Importeer altijd vanuit gerichte openclaw/plugin-sdk/<subpath>-paden:

    
    
    // Wrong: monolithic root (deprecated, will be removed)
    
    

    Zie SDK-overzicht voor de volledige subpadreferentie.

    Gebruik binnen je plugin lokale barrelbestanden (api.ts, runtime-api.ts) voor interne imports - importeer je eigen plugin nooit via het SDK-pad.

    Voor provider-plugins bewaar je providerspecifieke helpers in die barrels op pakketrootniveau, tenzij de seam echt generiek is. Huidige gebundelde voorbeelden:

    • Anthropic: Claude-streamwrappers en service_tier- / bètahelpers
    • OpenAI: providerbouwers, helpers voor standaardmodellen, realtime providers
    • OpenRouter: providerbouwer plus onboarding-/configuratiehelpers

    Als een helper alleen nuttig is binnen één gebundeld providerpakket, houd deze dan op die seam op pakketrootniveau in plaats van hem naar openclaw/plugin-sdk/* te promoveren.

    Sommige gegenereerde openclaw/plugin-sdk/<bundled-id>-helperseams bestaan nog steeds voor onderhoud van gebundelde plugins wanneer ze bijgehouden gebruik door eigenaren hebben. Behandel die als gereserveerde oppervlakken, niet als het standaardpatroon voor nieuwe plugins van derden.

    Checklist vóór indiening

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s package.json heeft correcte openclaw-metadata OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s openclaw.plugin.json-manifest is aanwezig en geldig OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Entry point gebruikt defineChannelPluginEntry of definePluginEntry OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Alle imports gebruiken gerichte plugin-sdk/<subpath>-paden OPENCLAW_DOCS_MARKER:calloutClose: