概述
创建 OpenClaw 插件的完整快速上手指南,涵盖工具插件、Channel 插件、Provider 插件的开发流程,以及发布到 ClawHub 或 npm 的步骤。
核心要点
前置条件:
- Node >= 22,npm 或 pnpm
- TypeScript (ESM) 基础
- 仓库内插件开发需 pnpm(monorepo 工作区)
插件类型:
- Channel 插件:连接消息平台(Discord、IRC 等)
- Provider 插件:添加模型提供商
- CLI 后端插件:映射本地 AI CLI 到文本回退运行器
- 工具/钩子插件:注册 Agent 工具、事件钩子或服务
工具注册规则:
- 工具名必须在 manifest
contracts.tools中声明 - 可选工具(有副作用或额外依赖)用
{ optional: true }注册 - 工具名不能与核心工具冲突
- 用户通过
tools.allow: ["tool_name"]启用可选工具
Hook 守卫语义:
before_tool_call: { block: true }— 终止,跳过低优先级处理器before_tool_call: { requireApproval: true }— 暂停执行,等待用户审批message_sending: { cancel: true }— 终止,跳过低优先级处理器before_install: { block: true }— 终止安装
导入约定:
- 始终使用聚焦的
openclaw/plugin-sdk/<subpath>路径 - 禁止使用单体根
openclaw/plugin-sdk(已废弃) - 内部导入使用本地桶文件(
api.ts、runtime-api.ts)
配置/使用
最小工具插件示例:
// index.ts
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { Type } from "@sinclair/typebox";
export default definePluginEntry({
id: "my-plugin",
name: "My Plugin",
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}` }] };
},
});
},
});package.json 关键字段:
{
"openclaw": {
"extensions": ["./index.ts"],
"compat": { "pluginApi": ">=2026.3.24-beta.2" }
}
}发布流程:
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
openclaw plugins install clawhub:@myorg/openclaw-my-plugin相关页面
- concepts/plugin-manifest — Manifest 完整 schema 参考
- concepts/plugin-architecture — 插件能力模型和所有权边界
- concepts/plugin-hooks — 插件钩子系统
- concepts/plugin-manage — 插件安装、更新、卸载管理