Plugins

Plugins erstellen

Plugins erweitern OpenClaw um neue Funktionen: Channels, Modell-Provider, Sprache, Echtzeit-Transkription, Echtzeit-Sprache, Medienverständnis, Bildgenerierung, Videogenerierung, Webabruf, Websuche, Agent-Tools oder jede Kombination daraus.

Sie müssen Ihr Plugin nicht zum OpenClaw-Repository hinzufügen. Veröffentlichen Sie es in ClawHub, und Benutzer installieren es mit openclaw plugins install clawhub:<package-name>. Reine Package-Spezifikationen werden während der Launch-Umstellung weiterhin von npm installiert.

Voraussetzungen

  • Node >= 22 und ein Package-Manager (npm oder pnpm)
  • Vertrautheit mit TypeScript (ESM)
  • Für Plugins im Repository: Repository geklont und pnpm install ausgeführt. Die Plugin-Entwicklung aus einem Source-Checkout ist nur mit pnpm möglich, weil OpenClaw gebündelte Plugins aus den Workspace-Packages extensions/* lädt.

Welche Art von Plugin?

Für ein Channel-Plugin, dessen Installation beim Ausführen von Onboarding/Setup nicht garantiert ist, verwenden Sie createOptionalChannelSetupSurface(...) aus openclaw/plugin-sdk/channel-setup. Es erzeugt ein Paar aus Setup-Adapter und Assistent, das auf die Installationsanforderung hinweist und echte Konfigurationsschreibvorgänge geschlossen fehlschlagen lässt, bis das Plugin installiert ist.

Schnellstart: Tool-Plugin

Diese Anleitung erstellt ein minimales Plugin, das ein Agent-Tool registriert. Für Channel- und Provider-Plugins gibt es eigene oben verlinkte Anleitungen.

  • Create the package and 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
    }
    }
    

    Jedes Plugin benötigt ein Manifest, auch ohne Konfiguration. Zur Laufzeit registrierte Tools müssen in contracts.tools aufgeführt sein, damit OpenClaw das besitzende Plugin erkennen kann, ohne jede Plugin-Laufzeit zu laden. Plugins sollten außerdem activation.onStartup bewusst deklarieren. Dieses Beispiel setzt es auf true. Siehe Manifest für das vollständige Schema. Die kanonischen ClawHub- Veröffentlichungsausschnitte befinden sich in docs/snippets/plugin-publish/.

  • Write the entry point

    // 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 ist für Nicht-Channel-Plugins gedacht. Für Channels verwenden Sie defineChannelPluginEntry - siehe Channel-Plugins. Vollständige Optionen für Einstiegspunkte finden Sie unter Einstiegspunkte.

  • Test and publish

    Externe Plugins: Mit ClawHub validieren und veröffentlichen, dann installieren:

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

    Reine Package-Spezifikationen wie @myorg/openclaw-my-plugin werden während der Launch-Umstellung von npm installiert. Verwenden Sie clawhub:, wenn Sie ClawHub-Auflösung wünschen.

    Plugins im Repository: Unter dem gebündelten Plugin-Workspace-Baum ablegen - sie werden automatisch erkannt.

    pnpm test -- <bundled-plugin-root>/my-plugin/
    
  • Plugin-Funktionen

    Ein einzelnes Plugin kann über das api-Objekt beliebig viele Funktionen registrieren:

    Funktion Registrierungsmethode Ausführliche Anleitung
    Text-Inferenz (LLM) api.registerProvider(...) Provider-Plugins
    CLI-Inferenz-Backend api.registerCliBackend(...) CLI-Backends
    Channel / Messaging api.registerChannel(...) Channel-Plugins
    Sprache (TTS/STT) api.registerSpeechProvider(...) Provider-Plugins
    Echtzeit-Transkription api.registerRealtimeTranscriptionProvider(...) Provider-Plugins
    Echtzeit-Sprache api.registerRealtimeVoiceProvider(...) Provider-Plugins
    Medienverständnis api.registerMediaUnderstandingProvider(...) Provider-Plugins
    Bildgenerierung api.registerImageGenerationProvider(...) Provider-Plugins
    Musikgenerierung api.registerMusicGenerationProvider(...) Provider-Plugins
    Videogenerierung api.registerVideoGenerationProvider(...) Provider-Plugins
    Webabruf api.registerWebFetchProvider(...) Provider-Plugins
    Websuche api.registerWebSearchProvider(...) Provider-Plugins
    Tool-Ergebnis-Middleware api.registerAgentToolResultMiddleware(...) SDK-Übersicht
    Agent-Tools api.registerTool(...) Unten
    Benutzerdefinierte Befehle api.registerCommand(...) Einstiegspunkte
    Plugin-Hooks api.on(...) Plugin-Hooks
    Interne Event-Hooks api.registerHook(...) Einstiegspunkte
    HTTP-Routen api.registerHttpRoute(...) Interna
    CLI-Unterbefehle api.registerCli(...) Einstiegspunkte

    Die vollständige Registrierungs-API finden Sie in der SDK-Übersicht.

    Gebündelte Plugins können api.registerAgentToolResultMiddleware(...) verwenden, wenn sie asynchrone Umschreibungen von Tool-Ergebnissen benötigen, bevor das Modell die Ausgabe sieht. Deklarieren Sie die Ziel-Laufzeiten in contracts.agentToolResultMiddleware, zum Beispiel ["pi", "codex"]. Dies ist eine vertrauenswürdige Schnittstelle für gebündelte Plugins; externe Plugins sollten reguläre OpenClaw-Plugin-Hooks bevorzugen, sofern OpenClaw keine explizite Vertrauensrichtlinie für diese Funktion entwickelt.

    Wenn Ihr Plugin benutzerdefinierte Gateway-RPC-Methoden registriert, belassen Sie sie unter einem Plugin-spezifischen Präfix. Zentrale Admin-Namespaces (config.*, exec.approvals.*, wizard.*, update.*) bleiben reserviert und werden immer zu operator.admin aufgelöst, selbst wenn ein Plugin einen engeren Scope anfordert.

    Wichtige Semantik von Hook-Guards:

    • before_tool_call: { block: true } ist terminal und stoppt Handler mit niedrigerer Priorität.
    • before_tool_call: { block: false } wird als keine Entscheidung behandelt.
    • before_tool_call: { requireApproval: true } pausiert die Agent-Ausführung und fordert den Benutzer über das Exec-Freigabe-Overlay, Telegram-Buttons, Discord-Interaktionen oder den Befehl /approve auf einem beliebigen Channel zur Freigabe auf.
    • before_install: { block: true } ist terminal und stoppt Handler mit niedrigerer Priorität.
    • before_install: { block: false } wird als keine Entscheidung behandelt.
    • message_sending: { cancel: true } ist terminal und stoppt Handler mit niedrigerer Priorität.
    • message_sending: { cancel: false } wird als keine Entscheidung behandelt.
    • message_received: Bevorzugen Sie das typisierte Feld threadId, wenn Sie eingehendes Thread-/Topic-Routing benötigen. Behalten Sie metadata für Channel-spezifische Extras bei.
    • message_sending: Bevorzugen Sie typisierte Routing-Felder replyToId / threadId gegenüber Channel-spezifischen Metadatenschlüsseln.

    Der Befehl /approve verarbeitet sowohl Exec- als auch Plugin-Freigaben mit begrenztem Fallback: Wenn eine Exec-Freigabe-ID nicht gefunden wird, versucht OpenClaw dieselbe ID erneut über Plugin-Freigaben. Plugin-Freigabeweiterleitung kann unabhängig über approvals.plugin in der Konfiguration eingerichtet werden.

    Wenn benutzerdefinierte Freigabe-Verkabelung denselben begrenzten Fallback-Fall erkennen muss, verwenden Sie bevorzugt isApprovalNotFoundError aus openclaw/plugin-sdk/error-runtime, statt Freigabeablauf-Strings manuell abzugleichen.

    Beispiele und die Hook-Referenz finden Sie unter Plugin-Hooks.

    Agent-Tools registrieren

    Tools sind typisierte Funktionen, die das LLM aufrufen kann. Sie können erforderlich (immer verfügbar) oder optional (Opt-in durch Benutzer) sein:

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

    Jedes mit api.registerTool(...) registrierte Tool muss auch im Plugin-Manifest deklariert werden:

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

    OpenClaw erfasst und cached den validierten Descriptor des registrierten Tools, sodass Plugins keine description- oder Schemadaten im Manifest duplizieren. Der Manifest-Vertrag deklariert nur Ownership und Discovery; die Ausführung ruft weiterhin die live registrierte Tool-Implementierung auf. Setzen Sie toolMetadata.<tool>.optional: true für Tools, die mit api.registerTool(..., { optional: true }) registriert wurden, damit OpenClaw das Laden dieser Plugin Runtime vermeiden kann, bis das Tool explizit in die Allowlist aufgenommen wird.

    Benutzer aktivieren optionale Tools in der Konfiguration:

    {
      tools: { allow: ["workflow_tool"] },
    }
    
    • Tool-Namen dürfen nicht mit Core-Tools kollidieren (Konflikte werden übersprungen)
    • Tools mit fehlerhaften Registrierungsobjekten, einschließlich fehlender parameters, werden übersprungen und in den Plugin-Diagnosen gemeldet, statt Agent-Ausführungen zu unterbrechen
    • Verwenden Sie optional: true für Tools mit Seiteneffekten oder zusätzlichen Binäranforderungen
    • Benutzer können alle Tools eines Plugins aktivieren, indem sie die Plugin-ID zu tools.allow hinzufügen

    CLI-Befehle registrieren

    Plugins können Root-openclaw-Befehlsgruppen mit api.registerCli hinzufügen. Geben Sie descriptors für jeden Top-Level-Befehlsstamm an, damit OpenClaw den Befehl anzeigen und routen kann, ohne jede Plugin Runtime vorab zu 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,
            },
          ],
        },
      );
    }
    

    Überprüfen Sie nach der Installation die Runtime-Registrierung und führen Sie den Befehl aus:

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

    Import-Konventionen

    Importieren Sie immer aus fokussierten openclaw/plugin-sdk/<subpath>-Pfaden:

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

    Die vollständige Subpath-Referenz finden Sie in der SDK-Übersicht.

    Verwenden Sie innerhalb Ihres Plugins lokale Barrel-Dateien (api.ts, runtime-api.ts) für interne Importe - importieren Sie niemals Ihr eigenes Plugin über seinen SDK-Pfad.

    Für Provider-Plugins sollten Provider-spezifische Hilfsfunktionen in diesen Package-Root- Barrels bleiben, sofern die Schnittstelle nicht wirklich generisch ist. Aktuelle gebündelte Beispiele:

    • Anthropic: Claude-Stream-Wrapper und service_tier- / Beta-Hilfsfunktionen
    • OpenAI: Provider-Builder, Hilfsfunktionen für Standardmodelle, Realtime-Provider
    • OpenRouter: Provider-Builder plus Hilfsfunktionen für Onboarding/Konfiguration

    Wenn eine Hilfsfunktion nur innerhalb eines gebündelten Provider-Pakets nützlich ist, belassen Sie sie auf dieser Package-Root-Schnittstelle, statt sie nach openclaw/plugin-sdk/* zu verschieben.

    Einige generierte openclaw/plugin-sdk/<bundled-id>-Hilfsschnittstellen existieren weiterhin für die Wartung gebündelter Plugins, wenn dafür Owner-Nutzung nachverfolgt wurde. Behandeln Sie diese als reservierte Oberflächen, nicht als Standardmuster für neue Drittanbieter-Plugins.

    Checkliste vor der Einreichung

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s package.json enthält korrekte openclaw-Metadaten OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s openclaw.plugin.json-Manifest ist vorhanden und gültig OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Einstiegspunkt verwendet defineChannelPluginEntry oder definePluginEntry OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Alle Importe verwenden fokussierte plugin-sdk/<subpath>-Pfade OPENCLAW_DOCS_MARKER:calloutClose: