OpenClaw 的插件系统允许在 gateway 进程中挂载自定义逻辑,与 AI agent 共享运行时。插件可以做很多事情:监听 agent 事件、提供自定义 tool、定时任务,或者像我们这次一样——跑一个独立的同步守护进程。

这篇记录从零创建一个插件、验证、发布到 ClawHub,再到远程节点安装的全过程。

背景 链接到标题

OpenClaw 插件和 Skill 的区别:Skill 是一组 instructions 文件,通过注入到 agent prompt 来改变行为;插件则是编译后的 JavaScript 代码,运行在 gateway 进程内,能调用 SDK 提供的 API(config、storage、http 等)。两者互补,技能负责"教 agent 怎么做",插件负责"替 agent 做"。

环境要求 链接到标题

  • Node.js ≥ 22.19(OpenClaw 的要求)
  • TypeScript + ESM 模块
  • clawhub CLI — 用于验证和发布
  • 一个 GitHub 仓库(公开或私有均可)

安装 clawhub CLI:

npm install -g @openclaw/clawhub

创建插件项目 链接到标题

推荐项目结构:

my-plugin/
├── src/
│   ├── index.ts          # 插件入口
│   └── lib.ts            # 核心逻辑
├── openclaw.plugin.json  # 插件清单
├── tsconfig.json
└── package.json

插件清单 链接到标题

openclaw.plugin.json 是最重要的文件,定义了插件的元数据和能力:

{
  "id": "my-plugin",
  "name": "My Plugin",
  "description": "示例插件",
  "version": "0.1.0",
  "author": {
    "name": "marshal"
  },
  "entrypoints": {
    "main": "dist/index.js"
  },
  "activation": {
    "onStartup": true
  },
  "contracts": {
    "tools": ["custom_tool_name"]
  }
}

字段说明:

字段 说明
id 插件唯一标识,安装时使用
entrypoints.main 编译后的 JS 入口文件
activation.onStartup 是否在 gateway 启动时自动加载
contracts.tools 插件提供的 tool 列表,供 agent 调用

TypeScript 配置 链接到标题

ESM 模块编译配置,tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "dist",
    "rootDir": "src",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true
  },
  "include": ["src"]
}

SDK 入口与最小示例 链接到标题

插件入口从 openclaw/plugin-sdk/plugin-entry 导入:

import type { PluginEntry } from 'openclaw/plugin-sdk/plugin-entry';

const entry: PluginEntry = {
  onStartup: async (api) => {
    console.log('[my-plugin] Plugin started');

    // 读取配置(来自 openclaw.json plugins.entries.<id>.config)
    const cfg = api.config.plugins.entries['my-plugin']?.config;
    console.log('[my-plugin] Config:', JSON.stringify(cfg));

    // 你的逻辑...
  },
  onShutdown: async () => {
    console.log('[my-plugin] Plugin stopped');
  },
};

export default entry;

onStartup 是插件运行时入口,gateway 启动时调用。api 对象提供了访问 OpenClaw 配置、存储、HTTP 客户端等能力。

注册自定义 Tool 链接到标题

通过 registerTools 注册可供 agent 调用的 tool:

import type { PluginEntry } from 'openclaw/plugin-sdk/plugin-entry';

const entry: PluginEntry = {
  onStartup: async (api) => {
    api.registerTools([
      {
        id: 'my_custom_tool',
        name: '自定义工具',
        description: 'agent 可以调用的自定义功能',
        handler: async (args) => {
          return { result: '处理成功', data: args };
        },
      },
    ]);
  },
};

export default entry;

插件配置 链接到标题

插件的配置通过 openclaw.json 注入,安装插件后在配置文件中添加:

{
  "plugins": {
    "allow": ["my-plugin"],
    "entries": {
      "my-plugin": {
        "enabled": true,
        "config": {
          "serverUrl": "http://内网地址:端口",
          "userName": "user",
          "password": "***"
        }
      }
    }
  }
}

代码中通过 api.config.plugins.entries['my-plugin'].config 读取。

注意:api.config 返回的是整个 openclaw.json,不是插件独享的配置对象。取值时要注意路径。

本地验证 链接到标题

编译项目后,使用 clawhub CLI 做完整性检查:

npx tsc
clawhub package validate .

成功输出:

Plugin Inspector: PASS
Breakages: 0
Warnings: 0
Findings: none

Inspector 会检查:清单字段完整性、入口文件存在性、依赖冲突、Node 版本兼容性等。验证报告会写入 reports/ 目录。

发布到 ClawHub 链接到标题

发布需要关联一个 GitHub 仓库(公开或私有均可):

clawhub package publish <scope>/<name> \
  --source-repo <github-user>/<repo-name> \
  --source-commit $(git rev-parse HEAD)
  • <scope>:你的 GitHub 用户名
  • <name>:包名,与插件 id 无关,独立定义
  • ClawHub 不限制仓库必须是公开的,私有仓库也能发布
  • 每次发布建议更新版本号

发布后查看:

clawhub package info <scope>/<name>

版本管理 链接到标题

建议使用 semver,每次修改后更新 openclaw.plugin.json 中的 version,再重新发布。Agent 安装时若不指定版本,默认拉取最新版。

远程节点安装 链接到标题

在有 OpenClaw gateway 运行的节点上安装:

openclaw plugins install clawhub:@<scope>/<name>

安装后,编辑 openclaw.json 添加配置(可选),然后重启 gateway:

# Docker 部署场景
docker restart openclaw-openclaw-gateway-1

验证插件是否加载成功:

docker logs openclaw-openclaw-gateway-1 2>&1 | grep "plugin"

日志中应看到插件名称出现在加载列表中:

http server listening (N plugins: ... my-plugin ...)

关闭并卸载 链接到标题

openclaw.json 中可以:

  • plugins.allow 中移除(彻底卸载)
  • 或设置 plugins.entries.<id>.enabled: false(临时禁用)

日志与调试 链接到标题

插件内的标准输出会被 OpenClaw 日志系统捕获:

console.log('[my-plugin] [INFO] 信息');
console.warn('[my-plugin] [WARN] 警告');
console.error('[my-plugin] [ERROR] 错误');

建议日志格式保持 [插件名] [级别] 消息,便于 grep 过滤。

对于需要持久化的状态(如上一次处理的 seq、token 等),有两种方式:

  • 写入文件(插件进程内持久)
  • 通过 api.storage SDK 接口(推荐,配置管理等场景)

小结 链接到标题

OpenClaw 插件机制的几个要点:

  • TypeScript ESM + Node ≥22 是硬性要求
  • 插件清单定义了元数据和入口,是 clawhub 验证和 gateway 加载的依据
  • 发布不要求公开仓库,私有仓库完全可用
  • 远程安装一行命令,配置通过 openclaw.json 注入
  • 日志通过 console 输出,与 gateway 日志汇总

插件的应用场景不止于此:可以挂载 HTTP handler、定时任务、集成外部服务。对于需要在 AI agent 侧执行的计算密集型或持久化任务,插件是比 Skill 更合适的选择。