Files
openclaw/docs/plugins/sdk-entrypoints.md
Vincent Koc 28838802d4 docs(plugins): add SDK reference and how-to guide pages (#52366)
* docs(plugins): add SDK reference and how-to guide pages

Create 7 new plugin SDK documentation pages:
- sdk-overview: import map, registration API reference
- sdk-entrypoints: definePluginEntry/defineChannelPluginEntry reference
- sdk-runtime: api.runtime namespace reference
- sdk-setup: packaging, manifests, config schemas reference
- sdk-channel-plugins: step-by-step channel plugin how-to
- sdk-provider-plugins: step-by-step provider plugin how-to
- sdk-testing: test utilities and patterns reference

Restructure plugin docs navigation with nested groups:
- Top-level: user-facing pages (Install, Community, Bundles)
- Building Plugins: Getting Started, Channel, Provider
- SDK Reference: Overview, Entry Points, Runtime, Setup, Testing, Migration, Manifest, Internals

Revise existing pages for new IA:
- building-plugins.md: tightened as quick-start, routes to detailed guides
- architecture.md: updated info box with links to new guides
- sdk-migration.md: expanded Related section

* docs(plugins): add Mintlify components (Steps, CodeGroup, Tabs, Accordion, CardGroup)

- Channel plugin guide: wrap walkthrough in Steps, use CodeGroup for
  package.json/manifest, Accordion for createChatChannelPlugin details,
  CardGroup for advanced topics
- Provider plugin guide: wrap walkthrough in Steps, use CodeGroup for
  package files, Tabs for hook examples, Accordion for all-hooks reference
- Getting started: use CardGroup for plugin-type picker and next steps,
  CodeGroup for package/manifest
- SDK Overview: wrap subpath tables in AccordionGroup for scannability

* fix(docs): address PR review feedback on plugin SDK pages

- Remove nonexistent api.runtime.channel.handleInboundMessage call,
  replace with realistic webhook pattern and note about channel-specific
  inbound handling (issue a)
- Fix registrationMode values: 'setup' -> 'setup-only' and 'setup-runtime'
  matching actual PluginRegistrationMode type (issue b)
- Fix createOptionalChannelSetupSurface params: channelId -> channel,
  add required label field (issue c)
- Fix broken anchor links: #multi-capability-providers ->
  #step-5-add-extra-capabilities, #plugin-kinds -> #registration-api (issue d)
- Add missing acmeChatApi import in channel plugin example (issue e)
- Fix undefined provider variable in provider test example (issue f)

* fix(docs): use correct createProviderApiKeyAuthMethod options

Replace incorrect params (provider, validate) with actual required fields
(providerId, methodId, optionKey, flagName, promptMessage) matching
src/plugins/provider-api-key-auth.ts.

* fix(docs): address second round of PR review feedback

- Add required model fields (reasoning, input, cost, contextWindow,
  maxTokens) to catalog example (issue b)
- Fix buildChannelConfigSchema to take a Zod schema argument (issue c)
- Replace fabricated setupWizard steps/run with real ChannelSetupWizard
  contract (channel, status, credentials) (issue d)
- Add required sessionFile/workspaceDir to runEmbeddedPiAgent (issue e)
- Fix wrapStreamFn to return StreamFn from ctx.streamFn (issue f)
2026-03-22 11:35:53 -07:00

6.6 KiB

title, sidebarTitle, summary, read_when
title sidebarTitle summary read_when
Plugin Entry Points Entry Points Reference for definePluginEntry, defineChannelPluginEntry, and defineSetupPluginEntry
You need the exact type signature of definePluginEntry or defineChannelPluginEntry
You want to understand registration mode (full vs setup)
You are looking up entry point options

Plugin Entry Points

Every plugin exports a default entry object. The SDK provides three helpers for creating them.

**Looking for a walkthrough?** See [Channel Plugins](/plugins/sdk-channel-plugins) or [Provider Plugins](/plugins/sdk-provider-plugins) for step-by-step guides.

definePluginEntry

Import: openclaw/plugin-sdk/plugin-entry

For provider plugins, tool plugins, hook plugins, and anything that is not a messaging channel.

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

export default definePluginEntry({
  id: "my-plugin",
  name: "My Plugin",
  description: "Short summary",
  register(api) {
    api.registerProvider({
      /* ... */
    });
    api.registerTool({
      /* ... */
    });
  },
});

Options

Field Type Required Default
id string Yes
name string Yes
description string Yes
kind string No
configSchema OpenClawPluginConfigSchema | () => OpenClawPluginConfigSchema No Empty object schema
register (api: OpenClawPluginApi) => void Yes
  • id must match your openclaw.plugin.json manifest.
  • kind is for exclusive slots: "memory" or "context-engine".
  • configSchema can be a function for lazy evaluation.

defineChannelPluginEntry

Import: openclaw/plugin-sdk/core

Wraps definePluginEntry with channel-specific wiring. Automatically calls api.registerChannel({ plugin }) and gates registerFull on registration mode.

import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";

export default defineChannelPluginEntry({
  id: "my-channel",
  name: "My Channel",
  description: "Short summary",
  plugin: myChannelPlugin,
  setRuntime: setMyRuntime,
  registerFull(api) {
    api.registerCli(/* ... */);
    api.registerGatewayMethod(/* ... */);
  },
});

Options

Field Type Required Default
id string Yes
name string Yes
description string Yes
plugin ChannelPlugin Yes
configSchema OpenClawPluginConfigSchema | () => OpenClawPluginConfigSchema No Empty object schema
setRuntime (runtime: PluginRuntime) => void No
registerFull (api: OpenClawPluginApi) => void No
  • setRuntime is called during registration so you can store the runtime reference (typically via createPluginRuntimeStore).
  • registerFull only runs when api.registrationMode === "full". It is skipped during setup-only loading.

defineSetupPluginEntry

Import: openclaw/plugin-sdk/core

For the lightweight setup-entry.ts file. Returns just { plugin } with no runtime or CLI wiring.

import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";

export default defineSetupPluginEntry(myChannelPlugin);

OpenClaw loads this instead of the full entry when a channel is disabled, unconfigured, or when deferred loading is enabled. See Setup and Config for when this matters.

Registration mode

api.registrationMode tells your plugin how it was loaded:

Mode When What to register
"full" Normal gateway startup Everything
"setup-only" Disabled/unconfigured channel Channel registration only
"setup-runtime" Setup flow with runtime available Channel + lightweight runtime

defineChannelPluginEntry handles this split automatically. If you use definePluginEntry directly for a channel, check mode yourself:

register(api) {
  api.registerChannel({ plugin: myPlugin });
  if (api.registrationMode !== "full") return;

  // Heavy runtime-only registrations
  api.registerCli(/* ... */);
  api.registerService(/* ... */);
}

Plugin shapes

OpenClaw classifies loaded plugins by their registration behavior:

Shape Description
plain-capability One capability type (e.g. provider-only)
hybrid-capability Multiple capability types (e.g. provider + speech)
hook-only Only hooks, no capabilities
non-capability Tools/commands/services but no capabilities

Use openclaw plugins inspect <id> to see a plugin's shape.