Skip to content

OpenClaw 工具插件用于向智能体添加可调用函数,无需实现渠道、模型提供商或其他后端。使用 defineToolPlugin 定义固定工具列表,OpenClaw 自动生成清单元数据,使工具可被发现但不加载运行时代码。推荐流程:openclaw plugins init 脚手架 → 编写工具 → openclaw plugins build 生成元数据 → openclaw plugins validate 验证。要求 Node >= 22、TypeScript ESM 输出、typebox 在 runtime dependencies,并且 openclaw >=2026.5.17。验证通过后可通过 ClawHub 发布或在本地安装。

OpenClaw 工具插件配置与 defineToolPlugin 使用指南

工具插件为 OpenClaw 添加智能体可调用的工具,不加渠道、模型提供商、钩子、服务或设置后端。当插件拥有固定工具列表,且希望 OpenClaw 在不加载运行时代码的情况下生成元数据使工具被发现时,使用 defineToolPlugin

推荐流程:

  1. openclaw plugins init 脚手架创建包。
  2. defineToolPlugin 编写工具。
  3. 构建 JavaScript。
  4. openclaw plugins build 生成 openclaw.plugin.jsonpackage.json 元数据。
  5. 在发布或安装前验证生成的元数据。

如需实现提供商、渠道、钩子、服务或混合能力插件,请参考 构建插件渠道插件提供商插件

要求

  • Node >= 22
  • TypeScript ESM 包输出
  • typebox 用于配置和工具参数 schema
  • openclaw >=2026.5.17(首个导出 openclaw/plugin-sdk/tool-plugin 的版本)
  • 包根目录必须能部署 dist/openclaw.plugin.jsonpackage.json

生成的插件在运行时导入 typebox,因此 typebox 必须置于 dependencies,不能仅在 devDependencies

快速开始

创建新插件包:

bash
openclaw plugins init stock-quotes --name "Stock Quotes"
cd stock-quotes
npm install
npm run plugin:build
npm run plugin:validate
npm test

脚手架创建的内容:

  • src/index.ts:一个包含 echo 工具的 defineToolPlugin 入口。
  • src/index.test.ts:小型元数据测试。
  • tsconfig.json:NodeNext TypeScript 输出到 dist/
  • package.json:脚本、运行时依赖和 openclaw.extensions: ["./dist/index.js"]
  • openclaw.plugin.json:初始工具生成的清单元数据。

验证预期输出:

text
Plugin stock-quotes is valid.

编写工具

defineToolPlugin 接受插件标识、可选配置 schema 和静态工具列表。参数和配置类型从 TypeBox schema 推断。

typescript
import { Type } from "typebox";
import { defineToolPlugin } from "openclaw/plugin-sdk/tool-plugin";

export default defineToolPlugin({
  id: "stock-quotes",
  name: "Stock Quotes",
  description: "Fetch stock quote snapshots.",
  configSchema: Type.Object({
    apiKey: Type.Optional(Type.String({ description: "Quote API key." })),
    baseUrl: Type.Optional(Type.String({ description: "Quote API base URL." })),
  }),
  tools: (tool) => [
    tool({
      name: "stock_quote",
      label: "Stock Quote",
      description: "Fetch a stock quote snapshot.",
      parameters: Type.Object({
        symbol: Type.String({ description: "Ticker symbol, for example OPEN." }),
      }),
      async execute({ symbol }, config, context) {
        context.signal?.throwIfAborted();
        return {
          symbol: symbol.toUpperCase(),
          configured: Boolean(config.apiKey),
          baseUrl: config.baseUrl ?? "https://api.example.com",
        };
      },
    }),
  ],
});

工具名是稳定 API。选择唯一、小写、足够具体的名称,避免与核心工具或其他插件冲突。

可选工具与工厂工具

可选工具

设置 optional: true,用户必须显式允许列表后才发送给模型:

typescript
tool({
  name: "workflow_run",
  description: "Run an external workflow.",
  parameters: Type.Object({ goal: Type.String() }),
  optional: true,
  execute: ({ goal }) => ({ queued: true, goal }),
});

openclaw plugins build 会写入匹配的 toolMetadata.<tool>.optional 清单条目,OpenClaw 无需加载插件运行时即可发现该工具。

工厂工具

当工具需要运行时环境才能创建时使用 factory。工厂保持元数据静态,同时让工具根据运行环境选择退出、检查沙箱状态或绑定运行时辅助。

typescript
tool({
  name: "local_workflow",
  description: "Run a local workflow outside sandboxed sessions.",
  parameters: Type.Object({ goal: Type.String() }),
  optional: true,
  factory({ api, toolContext }) {
    if (toolContext.sandboxed) {
      return null;
    }
    return createLocalWorkflowTool(api);
  },
});

工厂仍用于固定工具名。如需动态计算工具名或将工具与钩子、服务、提供商、命令或其他运行时面组合,应直接使用 definePluginEntry

返回值

defineToolPlugin 将简单返回值包装为 OpenClaw 工具结果格式:

  • 返回字符串:模型看到该文本。
  • 返回 JSON 兼容值:模型看到格式化 JSON,OpenClaw 在 details 中保留原始值。
typescript
tool({
  name: "echo_text",
  description: "Echo input text.",
  parameters: Type.Object({
    input: Type.String(),
  }),
  execute: ({ input }) => input,
});
typescript
tool({
  name: "echo_json",
  description: "Echo input as structured JSON.",
  parameters: Type.Object({
    input: Type.String(),
  }),
  execute: ({ input }) => ({ input, length: input.length }),
});

如需返回自定义 AgentToolResult 或重用现有 api.registerTool 实现,请使用工厂工具。需要完全动态工具或混合插件能力时,使用 definePluginEntry 替代 defineToolPlugin

配置

configSchema 可选。如果省略,OpenClaw 使用严格空对象 schema,生成的清单仍包含 configSchema

typescript
export default defineToolPlugin({
  id: "no-config-tools",
  name: "No Config Tools",
  description: "Adds tools that do not need configuration.",
  tools: () => [],
});

包含 configSchema 时,第二个 execute 参数类型从 schema 推断:

typescript
const configSchema = Type.Object({
  apiKey: Type.String(),
});

export default defineToolPlugin({
  id: "configured-tools",
  name: "Configured Tools",
  description: "Adds configured tools.",
  configSchema,
  tools: (tool) => [
    tool({
      name: "configured_ping",
      description: "Check whether configuration is available.",
      parameters: Type.Object({}),
      execute: (_params, config) => ({ hasKey: config.apiKey.length > 0 }),
    }),
  ],
});

OpenClaw 从 Gateway 配置中的插件条目读取插件配置。不要在源码或文档示例中硬编码密钥。根据插件安全模型使用配置、环境变量或 SecretRef。

生成的元数据

OpenClaw 从冷元数据发现已安装插件,必须在导入插件运行时代码前读取插件清单。因此 defineToolPlugin 暴露静态元数据,openclaw plugins build 将元数据写入包。

更改插件 id、name、description、配置 schema、activation 或工具名后运行生成器:

bash
npm run build
openclaw plugins build --entry ./dist/index.js

单工具插件的生成清单示例:

json
{
  "id": "stock-quotes",
  "name": "Stock Quotes",
  "description": "Fetch stock quote snapshots.",
  "version": "0.1.0",
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  },
  "activation": {
    "onStartup": true
  },
  "contracts": {
    "tools": ["stock_quote"]
  }
}

contracts.tools 是关键发现契约,告诉 OpenClaw 每个工具所属的插件,无需加载每个已安装插件的运行时。如果清单过时,工具可能缺失或注册错误归咎到错误插件。

包元数据

对于简单的工具插件工作流,openclaw plugins buildpackage.json 对齐到选定的单一运行时入口:

json
{
  "type": "module",
  "files": ["dist", "openclaw.plugin.json", "README.md"],
  "dependencies": {
    "typebox": "^1.1.38"
  },
  "peerDependencies": {
    "openclaw": ">=2026.5.17"
  },
  "openclaw": {
    "extensions": ["./dist/index.js"]
  }
}

已安装的包应使用构建后的 JavaScript 如 ./dist/index.js。源码入口在工作区开发中有用,但发布的包不应依赖 TypeScript 运行时加载。

在 CI 中验证

使用 plugins build --check 让 CI 在生成元数据过时时失败,不重写文件:

bash
npm run build
openclaw plugins build --entry ./dist/index.js --check
openclaw plugins validate --entry ./dist/index.js
npm test

plugins validate 检查:

  • openclaw.plugin.json 存在且通过常规清单加载器。
  • 当前入口导出 defineToolPlugin 元数据。
  • 生成的清单字段与入口元数据匹配。
  • contracts.tools 与声明的工具名一致。
  • package.jsonopenclaw.extensions 指向所选运行时入口。

本地安装与检查

从其他 OpenClaw 检出或已安装的 CLI 中安装包路径:

bash
openclaw plugins install ./stock-quotes
openclaw plugins inspect stock-quotes --runtime

进行打包冒烟测试,先 pack 再安装 tarball:

bash
npm pack
openclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgz
openclaw plugins inspect stock-quotes --runtime --json

安装后,启动或重启 Gateway 并要求智能体使用工具。如果调试工具可见性,在修改代码前检查插件运行时和有效工具目录。

发布

当包就绪后通过 ClawHub 发布:

bash
clawhub package publish your-org/stock-quotes --dry-run
clawhub package publish your-org/stock-quotes

使用显式 ClawHub 定位器安装:

bash
openclaw plugins install clawhub:your-org/stock-quotes

裸 npm 包规范在过渡期间仍然支持,但 ClawHub 是 OpenClaw 插件首选的发现和分发表面。

常见问题排查

plugin entry not found: ./dist/index.js 报错怎么解决?

所选入口文件不存在。运行 npm run build 构建后,重新执行 openclaw plugins build --entry ./dist/index.jsopenclaw plugins validate --entry ./dist/index.js

plugin entry does not expose defineToolPlugin metadata 如何处理?

入口未导出 defineToolPlugin 创建的值。检查模块默认导出是否为 defineToolPlugin(...) 结果,或通过 --entry 传递正确的入口文件。

openclaw.plugin.json generated metadata is stale 怎么更新?

清单不再与入口元数据匹配。运行:

bash
npm run build
openclaw plugins build --entry ./dist/index.js

提交 openclaw.plugin.jsonpackage.json 的更改。

package.json openclaw.extensions must include ./dist/index.js 错误如何修复?

包元数据指向了不同的运行时入口。运行 openclaw plugins build --entry ./dist/index.js 使生成器将包元数据对齐到你打算发布的入口。

Cannot find package 'typebox' 怎么办?

构建的插件在运行时导入 typebox。将 typebox 放在 dependencies 中,重新安装包依赖,重建并重新验证。

工具安装后不显示怎么办?

按以下顺序检查:

  1. openclaw plugins inspect <plugin-id> --runtime
  2. openclaw plugins validate --root <plugin-root> --entry ./dist/index.js
  3. openclaw.plugin.jsoncontracts.tools 是否包含期望的工具名。
  4. package.jsonopenclaw.extensions 是否为 ["./dist/index.js"]
  5. 安装插件后是否重启或重载了 Gateway。

常见问题

如何区分 defineToolPlugin 和工厂工具?

defineToolPlugin 用于固定工具列表。工厂工具(factory)用于需要运行时信息(如沙箱状态)才能决定是否创建工具的场景。如果工具名是动态的,或需要混合其他插件能力,应使用 definePluginEntry

为什么工具安装后智能体无法调用?

先确认插件已验证通过(openclaw plugins validate),然后重启 Gateway。使用 openclaw plugins inspect 检查工具是否已注册,并检查 Gateway 日志中是否有工具调用错误。如果工具标记为 optional,还需用户在渠道或工作区配置中显式启用。

typebox 版本不兼容导致构建失败怎么办?

确保 typebox 版本与 openclaw 要求匹配(package.json 中的 peerDependencies)。建议锁定 typebox^1.1.38(OpenClaw >=2026.5.17 的兼容版本)。如果仍出错,运行 npm dedupe 或删除 node_modulespackage-lock.json 后重新安装。

参考