概述

创建 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 — 插件安装、更新、卸载管理