Plugin SDK reference
Plugin-Einstiegspunkte
Jedes Plugin exportiert ein standardmäßiges Einstiegsobjekt. Das SDK stellt für
jede Einstiegsform eine Hilfsfunktion bereit: defineToolPlugin, definePluginEntry,
defineChannelPluginEntry, defineSetupPluginEntry.
Paket-Einstiegspunkte
Installierte Plugins verweisen über die openclaw-Felder in package.json sowohl auf
Quell- als auch auf Build-Einstiegspunkte:
{ "openclaw": { "extensions": ["./src/index.ts"], "runtimeExtensions": ["./dist/index.js"], "setupEntry": "./src/setup-entry.ts", "runtimeSetupEntry": "./dist/setup-entry.js" }}extensionsundsetupEntrysind Quell-Einstiegspunkte, die für die Entwicklung in Workspaces und Git-Checkouts verwendet werden.runtimeExtensionsundruntimeSetupEntrywerden bei installierten Paketen bevorzugt: Damit können npm-Pakete auf die TypeScript-Kompilierung zur Laufzeit verzichten.- Wenn
runtimeExtensionsvorhanden ist, muss seine Array-Länge mit der vonextensionsübereinstimmen (die Einträge werden positionsweise zugeordnet).runtimeSetupEntryerfordertsetupEntry. - Wenn ein Artefakt für
runtimeExtensions/runtimeSetupEntrydeklariert ist, aber fehlt, schlägt die Installation/Erkennung mit einem Paketierungsfehler fehl; OpenClaw greift nicht stillschweigend auf die Quelle zurück. Der unten beschriebene Rückgriff auf die Quelle gilt nur, wenn überhaupt kein Laufzeit-Einstiegspunkt deklariert ist. - Wenn ein installiertes Paket nur einen TypeScript-Quell-Einstiegspunkt deklariert,
sucht OpenClaw nach einem entsprechenden gebauten Gegenstück unter
dist/*.js(oder.mjs/.cjs) und verwendet dieses; andernfalls greift es auf die TypeScript-Quelle zurück. - Alle Einstiegspfade müssen innerhalb des Plugin-Paketverzeichnisses bleiben.
Laufzeit-Einstiegspunkte und abgeleitete gebaute JS-Gegenstücke machen einen aus
dem Verzeichnis herausführenden Quellpfad in
extensionsodersetupEntrynicht gültig.
defineToolPlugin
Import: openclaw/plugin-sdk/tool-plugin
Für Plugins, die ausschließlich Agenten-Tools hinzufügen. Hält den Quellcode klein,
leitet Konfigurations- und Tool-Parametertypen aus TypeBox-Schemas ab, verpackt
einfache Rückgabewerte in das OpenClaw-Tool-Ergebnisformat und stellt statische
Metadaten bereit, die openclaw plugins build in das Plugin-Manifest schreibt
(contracts.tools, configSchema).
export default defineToolPlugin({ id: "stock-quotes", name: "Stock Quotes", description: "Fetch stock quotes.", configSchema: Type.Object({ apiKey: Type.Optional(Type.String({ description: "API key." })), }), tools: (tool) => [ tool({ name: "quote", label: "Quote", description: "Fetch a quote.", parameters: Type.Object({ symbol: Type.String({ description: "Ticker symbol." }), }), execute: async ({ symbol }, config) => ({ symbol, hasKey: Boolean(config.apiKey) }), }), ],});configSchemaist optional; wenn es weggelassen wird, kommt ein striktes Schema für ein leeres Objekt zum Einsatz (das generierte Manifest enthält dennochconfigSchema).executegibt eine einfache Zeichenfolge oder einen JSON-serialisierbaren Wert zurück; die Hilfsfunktion verpackt ihn als Text-Tool-Ergebnis, wobeidetailsauf den ursprünglichen (nicht in eine Zeichenfolge umgewandelten) Rückgabewert gesetzt wird.- Für benutzerdefinierte Tool-Ergebnisse exportiert
openclaw/plugin-sdk/tool-resultsdie FunktionentextResultundjsonResult. - Tool-Namen sind statisch, sodass
openclaw plugins buildcontracts.toolsaus den deklarierten Tools ableitet, ohne die Namen manuell zu duplizieren. - Das Laden zur Laufzeit bleibt strikt: Installierte Plugins benötigen weiterhin
openclaw.plugin.jsonundopenclaw.extensionsinpackage.json. OpenClaw führt niemals Plugin-Code aus, um fehlende Manifestdaten abzuleiten.
definePluginEntry
Import: openclaw/plugin-sdk/plugin-entry
Für Provider-Plugins, erweiterte Tool-Plugins, Hook-Plugins und alles, was kein Nachrichtenkanal ist.
export default definePluginEntry({ id: "my-plugin", name: "My Plugin", description: "Short summary", register(api) { api.registerProvider({/* ... */}); api.registerTool({/* ... */}); },});| Feld | Typ | Erforderlich | Standardwert |
|---|---|---|---|
id |
string |
Ja | - |
name |
string |
Ja | - |
description |
string |
Ja | - |
kind |
string (veraltet, siehe unten) |
Nein | - |
configSchema |
OpenClawPluginConfigSchema | () => OpenClawPluginConfigSchema |
Nein | Schema für leeres Objekt |
reload |
OpenClawPluginReloadRegistration |
Nein | - |
nodeHostCommands |
OpenClawPluginNodeHostCommand[] |
Nein | - |
securityAuditCollectors |
OpenClawPluginSecurityAuditCollector[] |
Nein | - |
register |
(api: OpenClawPluginApi) => void |
Ja | - |
idmuss mit Ihrem Manifestopenclaw.plugin.jsonübereinstimmen.- Externe Sitzungskataloge verwenden
openclaw/plugin-sdk/session-catalogundapi.registerSessionCatalog({ id, label, list, read, continueSession?, archive? }). Der Kern verwaltet die Gateway-Methodensessions.catalog.*; Provider geben Host-, Sitzungs- und normalisierte Transkriptprojektionen zurück, ohne RPCs zu registrieren. kindist veraltet: Deklarieren Sie stattdessen einen exklusiven Slot ("memory"oder"context-engine") im Feldkinddes Manifestsopenclaw.plugin.json.kindim Laufzeit-Einstiegspunkt bleibt nur als Kompatibilitätsrückgriff für ältere Plugins bestehen.configSchemakann für eine verzögerte Auswertung eine Funktion sein. OpenClaw löst das Schema beim ersten Zugriff auf und speichert es zwischen, sodass aufwendige Schema-Builder nur einmal ausgeführt werden.- Ein
nodeHostCommands-Deskriptor kannisAvailable({ config, env })definieren. Bei der Rückgabe vonfalsewerden dieser Befehl und seine Fähigkeit aus der Gateway-Deklaration des Headless-Nodes weggelassen. OpenClaw wertet dies anhand der lokalen Startkonfiguration des Nodes aus; Befehlshandler sollten die Verfügbarkeit beim Aufruf dennoch validieren.
defineChannelPluginEntry
Import: openclaw/plugin-sdk/channel-core
Umschließt definePluginEntry mit kanalspezifischer Verdrahtung: Die Funktion ruft
automatisch api.registerChannel({ plugin }) auf, stellt eine optionale
CLI-Metadatenschnittstelle für die Hilfe auf oberster Ebene bereit und beschränkt
registerFull auf den Registrierungsmodus.
export default defineChannelPluginEntry({ id: "my-channel", name: "My Channel", description: "Short summary", plugin: myChannelPlugin, setRuntime: setMyRuntime, registerCliMetadata(api) { api.registerCli(/* ... */); }, registerFull(api) { api.registerGatewayMethod(/* ... */); },});| Feld | Typ | Erforderlich | Standardwert |
|---|---|---|---|
id |
string |
Ja | - |
name |
string |
Ja | - |
description |
string |
Ja | - |
plugin |
ChannelPlugin |
Ja | - |
configSchema |
OpenClawPluginConfigSchema | () => OpenClawPluginConfigSchema |
Nein | Schema für leeres Objekt |
setRuntime |
(runtime: PluginRuntime) => void |
Nein | - |
registerCliMetadata |
(api: OpenClawPluginApi) => void |
Nein | - |
registerFull |
(api: OpenClawPluginApi) => void |
Nein | - |
Callbacks werden je nach Registrierungsmodus ausgeführt (vollständige Tabelle unter Registrierungsmodus):
setRuntimewird in jedem Modus außer"cli-metadata"und"tool-discovery"ausgeführt. Speichern Sie hier die Laufzeitreferenz, üblicherweise übercreatePluginRuntimeStore.registerCliMetadatawird für"cli-metadata","discovery"und"full"ausgeführt. Verwenden Sie dies als kanonischen Ort für kanaleigene CLI-Deskriptoren, damit die Hilfe auf oberster Ebene nicht aktivierend bleibt, Erkennungs-Snapshots statische Befehlsmetadaten enthalten und die normale CLI-Registrierung mit vollständigen Plugin-Ladevorgängen kompatibel bleibt.registerFullwird nur für"full"und"tool-discovery"ausgeführt. Bei"tool-discovery"wird es anstelle der Kanalregistrierung ausgeführt: OpenClaw überspringtregisterChannel/setRuntimevollständig und ruft nurregisterFullauf. Daher muss jede Provider-/Tool-Registrierung, die Ihr Kanal für die eigenständige Tool-Erkennung oder -Ausführung benötigt, dort erfolgen und darf nicht hinter der normalen Kanaleinrichtung liegen.- Die Erkennungsregistrierung ist nicht aktivierend, aber nicht importfrei:
OpenClaw kann den vertrauenswürdigen Plugin-Einstiegspunkt und das
Kanal-Plugin-Modul auswerten, um den Snapshot zu erstellen. Halten Sie Importe
auf oberster Ebene frei von Seiteneffekten und platzieren Sie Sockets, Clients,
Worker und Dienste hinter Pfaden, die ausschließlich für
"full"gelten. - Wie bei
definePluginEntrykannconfigSchemaeine verzögert ausgewertete Factory sein; OpenClaw speichert das aufgelöste Schema beim ersten Zugriff zwischen.
CLI-Registrierung:
- Verwenden Sie
api.registerCli(..., { descriptors: [...] })für Plugin-eigene CLI-Befehle auf oberster Ebene, die verzögert geladen werden sollen, ohne aus dem Parse-Baum der Root-CLI zu verschwinden. Deskriptornamen dürfen nur Buchstaben, Zahlen, Bindestriche und Unterstriche enthalten und müssen mit einem Buchstaben oder einer Zahl beginnen; OpenClaw lehnt andere Formen ab und entfernt Terminal-Steuersequenzen aus Beschreibungen, bevor die Hilfe dargestellt wird. Decken Sie jeden vom Registrar bereitgestellten Befehlsstamm auf oberster Ebene ab.commandsallein verbleibt auf dem sofort geladenen Kompatibilitätspfad. - Verwenden Sie
api.registerNodeCliFeature(...)für Funktionsbefehle gekoppelter Nodes, damit sie unteropenclaw nodeseingeordnet werden (entsprichtregisterCli(registrar, { parentPath: ["nodes"], ... })). - Fügen Sie für andere verschachtelte Plugin-Befehle
parentPathhinzu und registrieren Sie Befehle amprogram-Objekt, das dem Registrar übergeben wird; OpenClaw löst es zum übergeordneten Befehl auf, bevor das Plugin aufgerufen wird. - Registrieren Sie bei Kanal-Plugins CLI-Deskriptoren aus
registerCliMetadataund beschränken SieregisterFullauf reine Laufzeitarbeiten. - Wenn
registerFullauch Gateway-RPC-Methoden registriert, verwenden Sie dafür ein Plugin-spezifisches Präfix. Reservierte administrative Kern-Namensräume (config.*,exec.approvals.*,wizard.*,update.*) werden immer zuoperator.adminerzwungen.
defineSetupPluginEntry
Import: openclaw/plugin-sdk/channel-core
Für die schlanke Datei setup-entry.ts. Gibt lediglich { plugin } ohne
Laufzeit- oder CLI-Verdrahtung zurück.
export default defineSetupPluginEntry(myChannelPlugin);OpenClaw lädt diesen Einstiegspunkt anstelle des vollständigen Einstiegspunkts, wenn ein Kanal deaktiviert oder nicht konfiguriert ist oder wenn verzögertes Laden aktiviert ist. Unter Einrichtung und Konfiguration erfahren Sie, wann dies relevant ist.
Kombinieren Sie defineSetupPluginEntry(...) mit den schlanken Familien von
Einrichtungshilfsfunktionen:
| Import | Verwenden für |
|---|---|
openclaw/plugin-sdk/setup-runtime |
Laufzeitsichere Setup-Hilfsfunktionen: createSetupTranslator, importsichere Setup-Patch-Adapter, Ausgabe von Lookup-Hinweisen, promptResolvedAllowFrom, splitSetupEntries, delegierte Setup-Proxys |
openclaw/plugin-sdk/channel-setup |
Setup-Oberflächen für optionale Installationen |
openclaw/plugin-sdk/setup-tools |
Hilfsfunktionen für Setup-/Installations-CLI, Archive und Dokumentation |
Belassen Sie umfangreiche SDKs, die CLI-Registrierung und langlebige Laufzeitdienste im vollständigen Einstiegspunkt.
Gebündelte Workspace-Kanäle, die Setup- und Laufzeitoberflächen trennen, können stattdessen
defineBundledChannelSetupEntry(...) aus
openclaw/plugin-sdk/channel-entry-contract verwenden. Dadurch kann der Setup-
Einstiegspunkt Setup-sichere Plugin-/Secrets-Exporte beibehalten und gleichzeitig einen Laufzeit-
Setter bereitstellen:
export default defineBundledChannelSetupEntry({ importMetaUrl: import.meta.url, plugin: { specifier: "./channel-plugin-api.js", exportName: "myChannelPlugin", }, runtime: { specifier: "./runtime-api.js", exportName: "setMyChannelRuntime", }, registerSetupRuntime(api) { api.registerHttpRoute({ path: "/my-channel/events", auth: "plugin", handler: async (req, res) => { /* Setup-sichere Route */ }, }); },});Verwenden Sie dies nur, wenn ein Setup-Ablauf tatsächlich einen leichtgewichtigen Laufzeit-Setter oder
eine Setup-sichere Gateway-Oberfläche benötigt, bevor der vollständige Kanaleinstiegspunkt geladen wird.
registerSetupRuntime wird nur bei "setup-runtime"-Ladevorgängen ausgeführt; beschränken Sie es
auf reine Konfigurationsrouten oder Methoden, die vor der verzögerten
vollständigen Aktivierung vorhanden sein müssen.
Registrierungsmodus
api.registrationMode teilt Ihrem Plugin mit, wie es geladen wurde:
| Modus | Zeitpunkt | Zu registrierende Elemente |
|---|---|---|
"full" |
Normaler Gateway-Start | Alles |
"discovery" |
Schreibgeschützte Ermittlung von Fähigkeiten | Kanalregistrierung plus statische CLI-Deskriptoren; Einstiegscode darf geladen werden, aber Sockets, Worker, Clients und Dienste auslassen |
"tool-discovery" |
Begrenztes Laden zum Auflisten oder Ausführen der Tools bestimmter Plugins | Nur Registrierung von Fähigkeiten/Tools; keine Kanalaktivierung |
"setup-only" |
Deaktivierter/nicht konfigurierter Kanal | Nur Kanalregistrierung |
"setup-runtime" |
Setup-Ablauf mit verfügbarer Laufzeit | Kanalregistrierung plus nur die leichtgewichtige Laufzeit, die vor dem Laden des vollständigen Einstiegspunkts benötigt wird |
"cli-metadata" |
Erfassung der Stammhilfe/CLI-Metadaten | Nur CLI-Deskriptoren |
defineChannelPluginEntry verarbeitet diese Aufteilung automatisch. Wenn Sie
definePluginEntry direkt für einen Kanal verwenden, prüfen Sie den Modus selbst und beachten Sie,
dass "tool-discovery" die Kanalregistrierung überspringt:
register(api) { if ( api.registrationMode === "cli-metadata" || api.registrationMode === "discovery" || api.registrationMode === "full" ) { api.registerCli(/* ... */); if (api.registrationMode === "cli-metadata") return; } if (api.registrationMode === "tool-discovery") { // Nur fähigkeitsbezogene Oberflächen (Provider/Tools) registrieren, keinen Kanal. return; } api.registerChannel({ plugin: myPlugin }); if (api.registrationMode !== "full") return; // Umfangreiche Registrierungen nur für die Laufzeit api.registerService(/* ... */);}Der Ermittlungsmodus erstellt einen nicht aktivierenden Registry-Snapshot. Dabei können weiterhin der Plugin-Einstiegspunkt und das Kanal-Plugin-Objekt ausgewertet werden, damit OpenClaw Kanalfähigkeiten und statische CLI-Deskriptoren registrieren kann. Behandeln Sie die Modul- auswertung während der Ermittlung als vertrauenswürdig, aber leichtgewichtig: keine Netzwerkclients, Unterprozesse, Listener, Datenbankverbindungen, Hintergrund-Worker, Zugangsdaten-Lesevorgänge oder andere aktiven Laufzeit-Nebenwirkungen auf oberster Ebene.
Betrachten Sie "setup-runtime" als das Zeitfenster, in dem ausschließlich für das Setup benötigte Startoberflächen
vorhanden sein müssen, ohne erneut in die vollständige Laufzeit des gebündelten Kanals einzutreten. Gut geeignet sind
Kanalregistrierung, Setup-sichere HTTP-Routen, Setup-sichere Gateway-Methoden
und delegierte Setup-Hilfsfunktionen. Umfangreiche Hintergrunddienste, CLI-Registrare und
Initialisierungen von Provider-/Client-SDKs gehören weiterhin in "full".
Plugin-Formen
OpenClaw klassifiziert geladene Plugins anhand ihres Registrierungsverhaltens:
| Form | Beschreibung |
|---|---|
| plain-capability | Ein Fähigkeitstyp (z. B. nur Provider) |
| hybrid-capability | Mehrere Fähigkeitstypen (z. B. Provider + Sprache) |
| hook-only | Nur Hooks, keine Fähigkeiten |
| non-capability | Tools/Befehle/Dienste, aber keine Fähigkeiten |
Verwenden Sie openclaw plugins inspect <id>, um die Form eines Plugins anzuzeigen.
Verwandte Themen
- SDK-Übersicht - Registrierungs-API und Unterpfadreferenz
- Laufzeit-Hilfsfunktionen -
api.runtimeundcreatePluginRuntimeStore - Setup und Konfiguration - Manifest, Setup-Einstiegspunkt, verzögertes Laden
- Kanal-Plugins - Erstellen des
ChannelPlugin-Objekts - Provider-Plugins - Provider-Registrierung und Hooks