SDK — Plugin Development API
Public API surface for building plugins, channels, providers, and tool extensions
The Plugin SDK (src/plugin-sdk/) is the public API surface that plugin developers use to build extensions. It provides typed interfaces for every extensibility point: channels, providers, memory engines, tools, hooks, commands, and services. The SDK follows a re-export architecture — it wraps internal modules into a clean, stable API boundary so that plugin authors don’t depend on internal file paths.
Type-Safe Multi-Surface Re-export Architecture Channel Adapters
📚 What is this & why does it exist?
The Plugin SDK (src/plugin-sdk/) is the public API surface that plugin developers use to build extensions. It provides typed interfaces for every extensibility point: channels, providers, memory engines, tools, hooks, commands, and services. The SDK follows a re-export architecture — it wraps internal modules into a clean, stable API boundary so that plugin authors don’t depend on internal file paths. The entry point (index.ts) deliberately keeps a tiny surface; specialized concerns live on dedicated subpaths like openclaw/plugin-sdk/channel-runtime or openclaw/plugin-sdk/provider-auth.
💡 Real-world analogy
The Plugin SDK is like a hardware manufacturer’s development kit (HDK). The internal modules are the raw circuit boards and chips; the SDK packages them into a clean breadboard with labeled pins. Plugin developers plug into the labeled pins (typed interfaces) without needing to understand the internal wiring. The re-export architecture ensures that if the internal wiring changes, the pin labels stay the same.
Contents
Architecture
flowchart TD
subgraph Entry["SDK Entry Points"]
Index["index.ts (root)"]
Core["core.ts"]
Compat["compat.ts"]
PluginRT["plugin-runtime.ts"]
PluginEntry["plugin-entry.ts"]
end
subgraph Surfaces["API Surfaces"]
ChanRT["channel-runtime.ts"]
ProvAuth["provider-auth.ts"]
ProvSetup["provider-setup.ts"]
AgentRT["agent-runtime.ts"]
MemCore["memory-core.ts"]
CliRT["cli-runtime.ts"]
end
subgraph Impl["Channel Implementations"]
Discord["discord.ts"]
Slack["slack.ts"]
WhatsApp["whatsapp.ts"]
Telegram["telegram.ts"]
More["20+ more channels"]
end
subgraph Providers["Provider Implementations"]
OpenAI["openai.ts"]
Anthropic["anthropic-cli.ts"]
Google["google.ts"]
Ollama["ollama.ts"]
MoreProv["40+ more providers"]
end
Index --> Core
Index --> Compat
Core --> ChanRT
Core --> ProvAuth
PluginRT --> ProvSetup
PluginEntry --> AgentRT
ChanRT --> Discord
ChanRT --> Slack
ChanRT --> WhatsApp
ChanRT --> Telegram
ChanRT --> More
ProvAuth --> OpenAI
ProvAuth --> Anthropic
ProvAuth --> Google
ProvAuth --> Ollama
ProvAuth --> MoreProv
AgentRT --> MemCore
CliRT --> AgentRT
Key Types
| Name | File | Type | Description |
|---|---|---|---|
OpenClawPluginApi | core.ts | Interface | Main plugin registration API with registerTool, registerHook, registerChannel, etc. |
OpenClawPluginDefinition | core.ts | Interface | Plugin module export: register(api) function |
OpenClawPluginConfigSchema | core.ts | Interface | Plugin config schema with parse(), validate(), uiHints, jsonSchema |
ChannelPlugin | core.ts | Interface | Channel adapter: inbound, outbound, auth, threading, messaging |
ProviderAuthContext | provider-auth.ts | Interface | Interactive auth context: config, prompter, runtime, OAuth helpers |
ProviderAuthResult | provider-auth-result.ts | Interface | Auth outcome with profiles, credentials, config patch |
PluginLogger | core.ts | Interface | Logger passed to plugins: debug, info, warn, error |
AnyAgentTool | core.ts | Type | Agent tool definition with name, description, parameters, execute |
Plugin Contract Flow
sequenceDiagram
participant Dev as Plugin Developer
participant SDK as plugin-sdk/index.ts
participant Core as plugin-sdk/core.ts
participant Loader as plugins/loader.ts
participant API as plugins/api-builder.ts
participant Reg as plugins/registry.ts
Dev->>SDK: import type { OpenClawPluginApi }
SDK->>Core: re-export types
Dev->>Dev: export default { register(api) { ... } }
Loader->>API: buildPluginApi(params)
API-->>Loader: OpenClawPluginApi instance
Loader->>Dev: plugin.register(api)
Dev->>Reg: api.registerTool(toolDef)
Dev->>Reg: api.registerHook('before_agent_start', handler)
Dev->>Reg: api.registerChannel(channelPlugin)
Reg-->>Loader: PluginRegistry updated
Deep-Dive Highlights
Core SDK mechanisms have been extracted into dedicated focus pages for in-depth exploration. Each page covers one aspect of the plugin SDK with diagrams, code walks, and API details.
Deep-Dive Pages
🏗 API Builder Focus
How buildPluginApi() constructs the registration facade for plugin authors.
📋 Plugin Contract Focus
The OpenClawPluginDefinition interface and register() lifecycle.
🎯 Capability Registration Focus
How tools, hooks, channels, and providers are registered through the SDK.
Directory Map
Source tree for plugin-sdk
📁 src/plugin-sdk/ — 337 files
├── index.ts # Root SDK entry (minimal re-exports)
├── core.ts # Core types and adapter builders
├── compat.ts # Legacy compatibility surface
├── plugin-runtime.ts # Runtime command/hook helpers
├── plugin-entry.ts # Plugin entry point utilities
├── channel-runtime.ts # Channel runtime re-exports
├── channel-config-*.ts # Channel config helpers (6 files)
├── channel-lifecycle*.ts # Channel lifecycle management
├── provider-auth*.ts # Provider auth abstractions (6 files)
├── provider-setup.ts # Provider setup wizard
├── provider-entry.ts # Provider entry helpers
├── agent-runtime.ts # Agent runtime abstractions
├── conversation-runtime.ts # Conversation runtime
├── memory-core*.ts # Memory engine SDK (20+ files)
├── discord*.ts # Discord channel (8+ files)
├── slack*.ts # Slack channel (8+ files)
├── whatsapp*.ts # WhatsApp channel (8+ files)
├── telegram*.ts # Telegram channel
├── openai.ts # OpenAI provider
├── anthropic*.ts # Anthropic provider
├── google.ts # Google provider
├── security-runtime.ts # Security abstractions
├── gateway-runtime.ts # Gateway runtime
└── testing.ts # Test utilities
Code Examples
Example: Registering a Channel Plugin
// Plugin SDK usage — registering a channel plugin
import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk";
import type { ChannelPlugin } from "openclaw/plugin-sdk/channel-runtime";
const myChannelPlugin: ChannelPlugin = {
channelId: "my-channel",
displayName: "My Channel",
messaging: {
async sendMessage(ctx, payload) {
await myChannelApi.send(ctx.target, payload.text);
return { delivered: true };
},
},
inbound: {
async handleWebhook(req, res) {
const event = parseWebhookEvent(req);
return { channelId: "my-channel", message: event.text };
},
},
};
export default {
register(api) {
api.registerChannel(myChannelPlugin);
api.logger.info("My channel plugin registered");
},
} satisfies OpenClawPluginDefinition;