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.

337
Files
80+
Channels
60+
Providers
TypeScript
Language

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

NameFileTypeDescription
OpenClawPluginApicore.tsInterfaceMain plugin registration API with registerTool, registerHook, registerChannel, etc.
OpenClawPluginDefinitioncore.tsInterfacePlugin module export: register(api) function
OpenClawPluginConfigSchemacore.tsInterfacePlugin config schema with parse(), validate(), uiHints, jsonSchema
ChannelPlugincore.tsInterfaceChannel adapter: inbound, outbound, auth, threading, messaging
ProviderAuthContextprovider-auth.tsInterfaceInteractive auth context: config, prompter, runtime, OAuth helpers
ProviderAuthResultprovider-auth-result.tsInterfaceAuth outcome with profiles, credentials, config patch
PluginLoggercore.tsInterfaceLogger passed to plugins: debug, info, warn, error
AnyAgentToolcore.tsTypeAgent 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.

Extracted topic page

📋 Plugin Contract Focus

The OpenClawPluginDefinition interface and register() lifecycle.

Extracted topic page

🎯 Capability Registration Focus

How tools, hooks, channels, and providers are registered through the SDK.

Extracted topic page

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;