Plugin SDK

The OpenClaw Plugin SDK is exposed under the openclaw/plugin-sdk package (and many subpaths for types, runtime helpers, and narrow contracts). It is the supported surface for native plugins to register capabilities, tools, hooks, and runtime behavior.

Import the entry point and helpers from the package:

import { definePluginEntry } from "openclaw/plugin-sdk";

definePluginEntry

definePluginEntry is the canonical helper for declaring a plugin. It accepts a manifest-like descriptor and returns a registration function that the loader calls with the OpenClawPluginApi.

Typical usage (channel plugins):

export default definePluginEntry({
  id: "example-channel",
  name: "Example Channel",
  description: "...",
  plugin: myChannelPlugin,
  configSchema: () => buildChannelConfigSchema(...),
  setRuntime: (rt) => { /* store runtime if needed */ },
  registerCliMetadata: (api) => { /* descriptors only */ },
  registerFull: (api) => { /* full runtime registration */ },
});

The loader distinguishes registerCliMetadata (parse-time, descriptors only) from registerFull (full runtime activation).

Capability registration

Plugins declare capabilities via the api object passed to register(...). Core surfaces include:

  • Providers (text inference, embeddings, speech, realtime, media understanding, image/video/music generation, web fetch/search, etc.)
  • Channels (messaging surfaces)
  • Tools
  • CLI backends
  • Model catalog providers
  • Gateway methods, HTTP routes, services, hooks, and more

Registration is performed inside the plugin module's register(api) path (or the registerFull callback when using definePluginEntry).

Example patterns from the SDK surface:

  • api.registerProvider(...)
  • api.registerChannel(...)
  • api.registerTool(...)
  • api.registerEmbeddingProvider(...)
  • api.registerSpeechProvider(...)
  • api.registerImageGenerationProvider(...)
  • api.registerWebSearchProvider(...)
  • api.registerCliBackend(...)

Capability ownership is recorded in manifests (contracts.*) and used for activation planning, discovery, and conflict detection. A plugin should own the full surface for its vendor or feature.

See Plugin manifests and contracts.

Runtime hooks

Plugins can register hooks for lifecycle events. The SDK re-exports hook-related types and the global hook runner.

Key surfaces (from plugin-sdk and runtime modules):

  • Typed hooks (e.g., before_agent_start, gateway_start, before_prompt_build, before_model_resolve)
  • PluginHookReplyPayload, PluginHookReplyDispatch* types for reply-payload hooks
  • Hook runner access via getGlobalHookRunner() / initializeGlobalHookRunner()

Hooks are collected during plugin load and executed by the central runner. Legacy before_agent_start remains supported for compatibility but is documented as legacy; prefer narrower hooks where possible.

Hook runner usage

import { getGlobalHookRunner } from "openclaw/plugin-sdk"; // or direct runtime import

const runner = getGlobalHookRunner();
// runner dispatches registered hooks for a given hook name and context

The runner is initialized early in the plugin loader and is the single point for firing hooks from core (agent turns, gateway lifecycle, reply pipelines, etc.). Plugins register via the api during register(...).

Additional helpers exported by the SDK

The package re-exports many narrow runtime contracts and utilities so plugins do not reach into core internals:

  • Channel adapters, outbound/inbound helpers, pairing, policy, targets
  • Reply payload, chunking, dispatch, dedupe
  • Session/transcript bindings, thread bindings
  • Provider auth, catalog, stream, usage, and transport helpers
  • Media, embedding, TTS/STT, generation providers
  • Config schema builders (buildPluginConfigSchema, buildChannelConfigSchema, empty* variants)
  • Runtime primitives (time, number, secure random, logging, fetch, exec, etc.)
  • Tool, command, and approval helpers

See the package exports map for the full list of subpaths (most are typed and intended for plugin consumption).

Activation and manifest contracts

Manifests (openclaw.plugin.json) declare kind, providers, channels, contracts.*, activation.*, setup, modelSupport, etc. These drive discovery, enablement, and activation planning before full runtime load.

The SDK itself focuses on the runtime registration side; manifest data is consumed by the loader and registry.

Notes

  • Use definePluginEntry (and the channel/provider helpers) for new plugins.
  • Keep registration side-effect free until the appropriate register* callback.
  • Capability registration is the preferred model over pure hook-only plugins for new native surfaces.
  • Many SDK subpaths are narrow contracts; prefer documented public surfaces over incidental re-exports.