mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-23 16:01:17 +00:00
* 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)
237 lines
8.4 KiB
Markdown
237 lines
8.4 KiB
Markdown
---
|
|
title: "Building Plugins"
|
|
sidebarTitle: "Getting Started"
|
|
summary: "Create your first OpenClaw plugin in minutes"
|
|
read_when:
|
|
- You want to create a new OpenClaw plugin
|
|
- You need a quick-start for plugin development
|
|
- You are adding a new channel, provider, tool, or other capability to OpenClaw
|
|
---
|
|
|
|
# Building Plugins
|
|
|
|
Plugins extend OpenClaw with new capabilities: channels, model providers, speech,
|
|
image generation, web search, agent tools, or any combination.
|
|
|
|
You do not need to add your plugin to the OpenClaw repository. Publish on npm
|
|
and users install with `openclaw plugins install <npm-spec>`.
|
|
|
|
## Prerequisites
|
|
|
|
- Node >= 22 and a package manager (npm or pnpm)
|
|
- Familiarity with TypeScript (ESM)
|
|
- For in-repo plugins: repository cloned and `pnpm install` done
|
|
|
|
## What kind of plugin?
|
|
|
|
<CardGroup cols={3}>
|
|
<Card title="Channel plugin" icon="message" href="/plugins/sdk-channel-plugins">
|
|
Connect OpenClaw to a messaging platform (Discord, IRC, etc.)
|
|
</Card>
|
|
<Card title="Provider plugin" icon="microchip" href="/plugins/sdk-provider-plugins">
|
|
Add a model provider (LLM, proxy, or custom endpoint)
|
|
</Card>
|
|
<Card title="Tool / hook plugin" icon="wrench">
|
|
Register agent tools, event hooks, or services — continue below
|
|
</Card>
|
|
</CardGroup>
|
|
|
|
## Quick start: tool plugin
|
|
|
|
This walkthrough creates a minimal plugin that registers an agent tool. Channel
|
|
and provider plugins have dedicated guides linked above.
|
|
|
|
<Steps>
|
|
<Step title="Create the package and manifest">
|
|
<CodeGroup>
|
|
```json package.json
|
|
{
|
|
"name": "@myorg/openclaw-my-plugin",
|
|
"version": "1.0.0",
|
|
"type": "module",
|
|
"openclaw": {
|
|
"extensions": ["./index.ts"]
|
|
}
|
|
}
|
|
```
|
|
|
|
```json openclaw.plugin.json
|
|
{
|
|
"id": "my-plugin",
|
|
"name": "My Plugin",
|
|
"description": "Adds a custom tool to OpenClaw",
|
|
"configSchema": {
|
|
"type": "object",
|
|
"additionalProperties": false
|
|
}
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
Every plugin needs a manifest, even with no config. See
|
|
[Manifest](/plugins/manifest) for the full schema.
|
|
|
|
</Step>
|
|
|
|
<Step title="Write the entry point">
|
|
|
|
```typescript
|
|
// index.ts
|
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
import { Type } from "@sinclair/typebox";
|
|
|
|
export default definePluginEntry({
|
|
id: "my-plugin",
|
|
name: "My Plugin",
|
|
description: "Adds a custom tool to OpenClaw",
|
|
register(api) {
|
|
api.registerTool({
|
|
name: "my_tool",
|
|
description: "Do a thing",
|
|
parameters: Type.Object({ input: Type.String() }),
|
|
async execute(_id, params) {
|
|
return { content: [{ type: "text", text: `Got: ${params.input}` }] };
|
|
},
|
|
});
|
|
},
|
|
});
|
|
```
|
|
|
|
`definePluginEntry` is for non-channel plugins. For channels, use
|
|
`defineChannelPluginEntry` — see [Channel Plugins](/plugins/sdk-channel-plugins).
|
|
For full entry point options, see [Entry Points](/plugins/sdk-entrypoints).
|
|
|
|
</Step>
|
|
|
|
<Step title="Test and publish">
|
|
|
|
**External plugins:**
|
|
|
|
```bash
|
|
npm publish
|
|
openclaw plugins install @myorg/openclaw-my-plugin
|
|
```
|
|
|
|
**In-repo plugins:** place under `extensions/` — automatically discovered.
|
|
|
|
```bash
|
|
pnpm test -- extensions/my-plugin/
|
|
```
|
|
|
|
</Step>
|
|
</Steps>
|
|
|
|
## Plugin capabilities
|
|
|
|
A single plugin can register any number of capabilities via the `api` object:
|
|
|
|
| Capability | Registration method | Detailed guide |
|
|
| -------------------- | --------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
| Text inference (LLM) | `api.registerProvider(...)` | [Provider Plugins](/plugins/sdk-provider-plugins) |
|
|
| Channel / messaging | `api.registerChannel(...)` | [Channel Plugins](/plugins/sdk-channel-plugins) |
|
|
| Speech (TTS/STT) | `api.registerSpeechProvider(...)` | [Provider Plugins](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
|
| Media understanding | `api.registerMediaUnderstandingProvider(...)` | [Provider Plugins](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
|
| Image generation | `api.registerImageGenerationProvider(...)` | [Provider Plugins](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
|
| Web search | `api.registerWebSearchProvider(...)` | [Provider Plugins](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
|
| Agent tools | `api.registerTool(...)` | Below |
|
|
| Custom commands | `api.registerCommand(...)` | [Entry Points](/plugins/sdk-entrypoints) |
|
|
| Event hooks | `api.registerHook(...)` | [Entry Points](/plugins/sdk-entrypoints) |
|
|
| HTTP routes | `api.registerHttpRoute(...)` | [Internals](/plugins/architecture#gateway-http-routes) |
|
|
| CLI subcommands | `api.registerCli(...)` | [Entry Points](/plugins/sdk-entrypoints) |
|
|
|
|
For the full registration API, see [SDK Overview](/plugins/sdk-overview#registration-api).
|
|
|
|
## Registering agent tools
|
|
|
|
Tools are typed functions the LLM can call. They can be required (always
|
|
available) or optional (user opt-in):
|
|
|
|
```typescript
|
|
register(api) {
|
|
// Required tool — always available
|
|
api.registerTool({
|
|
name: "my_tool",
|
|
description: "Do a thing",
|
|
parameters: Type.Object({ input: Type.String() }),
|
|
async execute(_id, params) {
|
|
return { content: [{ type: "text", text: params.input }] };
|
|
},
|
|
});
|
|
|
|
// Optional tool — user must add to allowlist
|
|
api.registerTool(
|
|
{
|
|
name: "workflow_tool",
|
|
description: "Run a workflow",
|
|
parameters: Type.Object({ pipeline: Type.String() }),
|
|
async execute(_id, params) {
|
|
return { content: [{ type: "text", text: params.pipeline }] };
|
|
},
|
|
},
|
|
{ optional: true },
|
|
);
|
|
}
|
|
```
|
|
|
|
Users enable optional tools in config:
|
|
|
|
```json5
|
|
{
|
|
tools: { allow: ["workflow_tool"] },
|
|
}
|
|
```
|
|
|
|
- Tool names must not clash with core tools (conflicts are skipped)
|
|
- Use `optional: true` for tools with side effects or extra binary requirements
|
|
- Users can enable all tools from a plugin by adding the plugin id to `tools.allow`
|
|
|
|
## Import conventions
|
|
|
|
Always import from focused `openclaw/plugin-sdk/<subpath>` paths:
|
|
|
|
```typescript
|
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
|
|
|
// Wrong: monolithic root (deprecated, will be removed)
|
|
import { ... } from "openclaw/plugin-sdk";
|
|
```
|
|
|
|
For the full subpath reference, see [SDK Overview](/plugins/sdk-overview).
|
|
|
|
Within your plugin, use local barrel files (`api.ts`, `runtime-api.ts`) for
|
|
internal imports — never import your own plugin through its SDK path.
|
|
|
|
## Pre-submission checklist
|
|
|
|
<Check>**package.json** has correct `openclaw` metadata</Check>
|
|
<Check>**openclaw.plugin.json** manifest is present and valid</Check>
|
|
<Check>Entry point uses `defineChannelPluginEntry` or `definePluginEntry`</Check>
|
|
<Check>All imports use focused `plugin-sdk/<subpath>` paths</Check>
|
|
<Check>Internal imports use local modules, not SDK self-imports</Check>
|
|
<Check>Tests pass (`pnpm test -- extensions/my-plugin/`)</Check>
|
|
<Check>`pnpm check` passes (in-repo plugins)</Check>
|
|
|
|
## Next steps
|
|
|
|
<CardGroup cols={2}>
|
|
<Card title="Channel Plugins" icon="message" href="/plugins/sdk-channel-plugins">
|
|
Build a messaging channel plugin
|
|
</Card>
|
|
<Card title="Provider Plugins" icon="microchip" href="/plugins/sdk-provider-plugins">
|
|
Build a model provider plugin
|
|
</Card>
|
|
<Card title="SDK Overview" icon="book" href="/plugins/sdk-overview">
|
|
Import map and registration API reference
|
|
</Card>
|
|
<Card title="Runtime Helpers" icon="gear" href="/plugins/sdk-runtime">
|
|
TTS, search, subagent via api.runtime
|
|
</Card>
|
|
<Card title="Testing" icon="flask" href="/plugins/sdk-testing">
|
|
Test utilities and patterns
|
|
</Card>
|
|
<Card title="Plugin Manifest" icon="file-code" href="/plugins/manifest">
|
|
Full manifest schema reference
|
|
</Card>
|
|
</CardGroup>
|