mirror of https://github.com/openclaw/openclaw.git
160 lines
4.2 KiB
Markdown
160 lines
4.2 KiB
Markdown
---
|
|
title: "Plugin Entry Points"
|
|
sidebarTitle: "Entry Points"
|
|
summary: "How to define plugin entry files for provider, tool, channel, and setup plugins"
|
|
read_when:
|
|
- You are writing a plugin `index.ts`
|
|
- You need to choose between `definePluginEntry` and `defineChannelPluginEntry`
|
|
- You are adding a separate `setup-entry.ts`
|
|
---
|
|
|
|
# Plugin Entry Points
|
|
|
|
OpenClaw has two main entry helpers:
|
|
|
|
- `definePluginEntry(...)` for general plugins
|
|
- `defineChannelPluginEntry(...)` for native messaging channels
|
|
|
|
There is also `defineSetupPluginEntry(...)` for a separate setup-only module.
|
|
|
|
## `definePluginEntry(...)`
|
|
|
|
Use this for providers, tools, commands, services, memory plugins, and context
|
|
engines.
|
|
|
|
```ts
|
|
import { definePluginEntry, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
|
|
|
export default definePluginEntry({
|
|
id: "example-tools",
|
|
name: "Example Tools",
|
|
description: "Adds a command and a tool",
|
|
register(api: OpenClawPluginApi) {
|
|
api.registerCommand({
|
|
name: "example",
|
|
description: "Show plugin status",
|
|
handler: async () => ({ text: "example ok" }),
|
|
});
|
|
|
|
api.registerTool({
|
|
name: "example_lookup",
|
|
description: "Look up Example data",
|
|
parameters: {
|
|
type: "object",
|
|
properties: {
|
|
query: { type: "string" },
|
|
},
|
|
required: ["query"],
|
|
},
|
|
async execute(_callId, params) {
|
|
return {
|
|
content: [{ type: "text", text: `lookup: ${String(params.query)}` }],
|
|
};
|
|
},
|
|
});
|
|
},
|
|
});
|
|
```
|
|
|
|
## `defineChannelPluginEntry(...)`
|
|
|
|
Use this for a plugin that registers a `ChannelPlugin`.
|
|
|
|
```ts
|
|
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
|
|
import { channelPlugin } from "./src/channel.js";
|
|
import { setRuntime } from "./src/runtime.js";
|
|
|
|
export default defineChannelPluginEntry({
|
|
id: "example-channel",
|
|
name: "Example Channel",
|
|
description: "Example messaging plugin",
|
|
plugin: channelPlugin,
|
|
setRuntime,
|
|
registerFull(api) {
|
|
api.registerTool({
|
|
name: "example_channel_status",
|
|
description: "Inspect Example Channel state",
|
|
parameters: { type: "object", properties: {} },
|
|
async execute() {
|
|
return { content: [{ type: "text", text: "ok" }] };
|
|
},
|
|
});
|
|
},
|
|
});
|
|
```
|
|
|
|
### Why `registerFull(...)` exists
|
|
|
|
OpenClaw can load plugins in setup-focused registration modes. `registerFull`
|
|
lets a channel plugin skip extra runtime-only registrations such as tools while
|
|
still registering the channel capability itself.
|
|
|
|
Use it for:
|
|
|
|
- agent tools
|
|
- gateway-only routes
|
|
- runtime-only commands
|
|
|
|
Do not use it for the actual `ChannelPlugin`; that belongs in `plugin: ...`.
|
|
|
|
## `defineSetupPluginEntry(...)`
|
|
|
|
Use this when a channel ships a second module for setup flows.
|
|
|
|
```ts
|
|
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
|
|
import { exampleSetupPlugin } from "./src/channel.setup.js";
|
|
|
|
export default defineSetupPluginEntry(exampleSetupPlugin);
|
|
```
|
|
|
|
This keeps the setup entry shape explicit and matches the bundled channel
|
|
pattern used in OpenClaw.
|
|
|
|
## One plugin, many capabilities
|
|
|
|
A single entry file can register multiple capabilities:
|
|
|
|
```ts
|
|
import { definePluginEntry, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
|
|
|
export default definePluginEntry({
|
|
id: "example-hybrid",
|
|
name: "Example Hybrid",
|
|
description: "Provider plus tools",
|
|
register(api: OpenClawPluginApi) {
|
|
api.registerProvider({
|
|
id: "example",
|
|
label: "Example",
|
|
auth: [],
|
|
});
|
|
|
|
api.registerTool({
|
|
name: "example_ping",
|
|
description: "Simple health check",
|
|
parameters: { type: "object", properties: {} },
|
|
async execute() {
|
|
return { content: [{ type: "text", text: "pong" }] };
|
|
},
|
|
});
|
|
},
|
|
});
|
|
```
|
|
|
|
## Entry-file checklist
|
|
|
|
- Give the plugin a stable `id`.
|
|
- Keep `name` and `description` human-readable.
|
|
- Put schema at the entry level when the plugin has config.
|
|
- Register only public capabilities inside `register(api)`.
|
|
- Keep channel plugins on `plugin-sdk/core`.
|
|
- Keep non-channel plugins on `plugin-sdk/plugin-entry`.
|
|
|
|
## Related
|
|
|
|
- [Plugin SDK Overview](/plugins/sdk-overview)
|
|
- [Plugin Runtime](/plugins/sdk-runtime)
|
|
- [Channel Plugin SDK](/plugins/sdk-channel-plugins)
|
|
- [Provider Plugin SDK](/plugins/sdk-provider-plugins)
|