Plugin Development
OpenBot plugins extend agents by subscribing to the event bus, reading and writing through Storage, and optionally rendering client UI. The supported API is @meetopenbot/plugin-sdk — see the full Plugin SDK reference for every type, helper, and event shape (source: meetopenbot/plugin-sdk).
Install the SDK
Section titled “Install the SDK”npm install @meetopenbot/plugin-sdkInstall peer dependencies melony and zod in your project as required by your package manager. The SDK also re-exports z if you prefer a single import for plugins and schemas.
Define a plugin
Section titled “Define a plugin”Use definePlugin so TypeScript infers the plugin object without hand-annotating Melony types:
import { definePlugin } from '@meetopenbot/plugin-sdk';
export default definePlugin({ id: 'my-plugin', name: 'My Plugin', description: 'A simple example plugin', configSchema: { type: 'object', properties: { apiKey: { type: 'string', description: 'Your API Key', format: 'password' }, }, required: ['apiKey'], }, toolDefinitions: { get_weather: { description: 'Get the current weather', inputSchema: { type: 'object', properties: { location: { type: 'string' }, }, }, }, }, factory: (context) => (builder) => { builder.on('agent:invoke', async function* (event) { // Handle events here }); },});Community npm packages can omit id and export a PluginModule — the OpenBot host derives id from the package name. See Plugin SDK — Plugin vs PluginModule.
Lifecycle
Section titled “Lifecycle”When the host loads your plugin:
- It calls
factory(pluginContext)— you getagentId,agentDetails, resolvedconfig,storage, and mergedtools. Details: Plugin context. - You return a Melony plugin (typed as
PluginFactory) that registers handlers onPluginBuilderwithbuilder.on(eventType, async function* (event, ctx) { ... }). - Handlers
yieldnew bus events (agent:output,client:ui:widget,action:<tool>:result, etc.). See Events.
Frequently used helpers
Section titled “Frequently used helpers”| Helper | When to use |
|---|---|
shouldHandleInvoke(event, context.agentId) | Ignore agent:invoke when another agent was targeted via event.data.agentId. |
agentOutput({ ... }) | Stream a textual reply (agent:output). |
uiWidget({ ... }) | Render a widget (client:ui:widget). |
toolResult(toolName, request, data) | Answer a runtime tool call (action:<tool>:result). |
Examples and typings: Helpers.
Guides and next steps
Section titled “Guides and next steps”- Your First Channel —
channelId+threadIdrequired for SSE and publish correlation - Your First Agent — create
AGENT.md, pick plugins, and write instructions - Your First Plugin — echo plugin tutorial and wiring plugins from
AGENT.md - Plugin SDK — storage methods, widget kinds (
message,choice,form,list,media), and runtime state - Built-in Plugins — what ships with OpenBot