Skip to main content
defineToolPlugin 构建一个仅添加 agent 可调用工具的插件:不包含 channel、model provider、hook、service 或 setup 后端。它会生成 OpenClaw 发现工具所需的清单元数据,而无需加载插件运行时代码。 对于 provider、channel、hook、service 或混合能力插件,请改从 构建插件Channel Plugins,或 Provider Plugins 开始。

要求

  • Node 22.22.3+、Node 24.15+ 或 Node 25.9+。
  • TypeScript ESM 包输出。
  • dependencies 中包含 typebox(不能只放在 devDependencies 中——生成的 插件会在运行时导入它)。
  • openclaw >=2026.5.17,这是第一个导出 openclaw/plugin-sdk/tool-plugin 的版本。
  • 一个会发布 dist/openclaw.plugin.jsonpackage.json 的包根目录。

快速开始

plugins init 会生成以下内容: npm run plugin:build 先运行 npm run build(tsc),然后 运行 openclaw plugins build --entry ./dist/index.jsnpm run plugin:validate 会重新构建并运行 openclaw plugins validate --entry ./dist/index.js。 验证成功时会输出:
openclaw plugins init <id> 选项:

编写工具

defineToolPlugin 接受插件标识、一个可选的配置模式,以及一个静态的工具列表。参数和配置类型会根据 TypeBox 模式进行推断。
工具名称是稳定的 API。请选择唯一、全小写且足够具体的名称,以避免与核心工具或其他插件发生冲突。

可选工具和工厂工具

当用户应当显式将工具加入允许列表后才将其发送给模型时,设置 optional: trueopenclaw plugins build 会写入匹配的 toolMetadata.<tool>.optional 清单条目,因此 OpenClaw 无需加载插件运行时代码就能知道该工具是可选的。
当工具在创建之前需要运行时工具上下文时,使用 factory——例如为了针对特定运行选择退出、检查沙箱状态,或绑定运行时辅助函数。尽管具体工具是在运行时构建的,元数据仍然保持静态。
工厂仍然会预先声明一个固定的工具名称。当插件动态计算工具名称,或将工具与 hooks、services、providers 或 commands 组合时,直接使用 definePluginEntry

返回值

defineToolPlugin 会将普通返回值包装为 OpenClaw 工具结果格式:
  • 当模型应看到那段精确文本时,返回一个字符串。
  • 当你希望模型看到格式化的 JSON,并且 OpenClaw 将原始值保留在 details 中时,返回一个兼容 JSON 的值。
当你需要自定义 AgentToolResult,或者希望复用现有的 api.registerTool 实现时,请使用工厂工具。

Output contracts

Add outputSchema when a tool returns stable JSON-compatible data. It describes the original value stored in AgentToolResult.details, not the formatted text in content:
Code Mode and Tool Search turn this schema into a bounded TypeScript-style output hint. That lets a model call and transform a known result in one program instead of spending another model turn observing its shape. OpenClaw compiles the schema before executing a catalog call, then validates the final details value after tool hooks before returning it through the bridge. An invalid schema cannot run the tool; a result mismatch fails the completed call. Include every non-throwing result variant, including structured error variants, or omit the schema when the result is not stable. Do not put secrets or sensitive values in schema descriptions because trusted output metadata can become model-visible. Use { additionalProperties: false } on object layers when you want a complete compact output hint; open or truncated schemas remain available through tools.describe(...) but are not advertised as complete quick-index contracts. Factory tools declare outputSchema on the concrete AnyAgentTool they return. The static tool({ factory }) declaration does not accept a separate output schema because it could drift from the runtime tool.

Configuration

configSchema 是可选的。省略它时,OpenClaw 会应用严格的空对象 schema;生成的 manifest 仍然包含 configSchema
如果提供了 configSchema,第二个 execute 参数会根据它进行类型推导:
OpenClaw 会从 Gateway 配置中该插件的条目读取插件配置。请勿 在源码或文档示例中硬编码密钥;请根据插件的安全模型使用 config、环境 变量或 SecretRefs。

生成的元数据

OpenClaw 必须先读取插件清单,然后才能导入插件运行时代码。
defineToolPlugin 为此暴露了静态元数据,而
openclaw plugins build 会将其写入包中。更改插件 id、名称、描述、配置模式、激活方式或工具名称后,
请重新运行生成器:
单工具插件生成的清单:
contracts.tools 是重要的发现契约:它告诉 OpenClaw 在不加载每个已安装插件的运行时的情况下,
每个工具分别属于哪个插件。过期的清单会导致工具在发现过程中丢失,或者把注册错误归咎于错误的插件。

Package metadata

openclaw plugins build also aligns package.json to the selected runtime entry:
Publish the built JavaScript (./dist/index.js), do not use the TypeScript source entry. The source entry is only for local development in the workspace.

在 CI 中验证

当生成的元数据已过期时,plugins build --check 会在不重写文件的情况下失败:
OpenClaw SDK compatibility fields carry TypeScript @deprecated annotations, which editors surface as migration warnings. To enforce them in CI, enable a type-aware rule such as @typescript-eslint/no-deprecated. Oxlint is not type-aware, so it cannot enforce these annotations. The generated plugins init scaffold therefore does not add a deprecation lint config. plugins validate checks that:
  • openclaw.plugin.json 是否存在并通过常规清单加载器。
  • 当前入口是否导出 defineToolPlugin 元数据。
  • 生成的清单字段是否与入口元数据匹配。
  • contracts.tools 是否与声明的工具名称匹配。
  • package.json 是否将 openclaw.extensions 指向所选的运行时入口。

在本地安装和检查

从另一个 OpenClaw 检出目录或已安装的 CLI 中,安装包路径:
对于打包后的冒烟测试,先执行打包并安装 tarball:
安装后,重启或重新加载 Gateway,并让代理使用该工具。如果工具不可见,请在修改代码之前检查插件运行时和实际生效的工具目录(请参见 故障排查)。

发布

当包准备就绪后,通过 ClawHub 发布。clawhub package publish 接受以下来源:本地文件夹、GitHub 仓库(owner/repo[@ref])或 tarball URL。
使用显式的 ClawHub 定位器进行安装:
在启动切换期间,裸 npm 包规范仍然会从 npm 安装,但 ClawHub 是 OpenClaw 插件首选的发现和分发入口。有关 owner 范围和 发布审核,请参见 ClawHub 发布

故障排查

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

清单不再与入口元数据匹配。运行:
同时提交 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。请将其保留在 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.json 包含 openclaw.extensions: ["./dist/index.js"]
  5. 安装插件后,Gateway 已重启或重新加载。

另请参见