工具插件
工具插件在不新增通道、模型提供者、Hook、服務或設置後端的情況下,將可供代理呼叫的工具新增至 OpenClaw。當外掛擁有固定的工具清單,且您希望 OpenClaw 生成清單元數據,以便在不載入執行時代碼的情況下讓這些工具可被發現時,請使用 defineToolPlugin。
建議的流程如下:
- 使用
openclaw plugins init建立(腳手架)一個套件。 - 使用
defineToolPlugin撰寫工具。 - 建置 JavaScript。
- 使用
openclaw plugins build生成openclaw.plugin.json和package.json元數據。 - 在發布或安裝之前驗證生成的元數據。
對於提供者、通道、Hook、服務或混合功能外掛,請改為從 建置外掛、通道外掛 或 提供者外掛 開始。
- Node >= 22。
- TypeScript ESM 套件輸出。
- 用於配置和工具參數架構的
typebox。 openclaw >=2026.5.17,第一個匯出openclaw/plugin-sdk/tool-plugin的 OpenClaw 版本。- 可以發送
dist/、openclaw.plugin.json和package.json的套件根目錄。
生成的外掛在執行時匯入 typebox,因此請將 typebox 保留在 dependencies 中,而不僅僅是 devDependencies。
建立一個新的外掛套件:
openclaw plugins init stock-quotes --name "Stock Quotes"cd stock-quotesnpm installnpm run plugin:buildnpm run plugin:validatenpm test腳手架會建立:
src/index.ts:一個帶有echo工具的defineToolPlugin項目。src/index.test.ts:一個小型的元數據測試。tsconfig.json:輸出到dist/的 NodeNext TypeScript。package.json:腳本、執行時期相依性以及openclaw.extensions: ["./dist/index.js"]。openclaw.plugin.json:針對初始工具產生的清單元資料。
預期的驗證輸出:
Plugin stock-quotes is valid.defineToolPlugin 接收外掛身分、選用的設定架構以及
靜態的工具清單。參數與設定型別會從 TypeBox
架構推斷。
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。請選擇獨特、小寫且 足夠具體的名稱,以避免與核心工具或其他外掛衝突。
選用與工廠工具
Section titled “選用與工廠工具”當使用者應在工具傳送至模型前明確將其加入允許清單時,請設定 optional: true:
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。工廠讓中繼資料保持靜態,同時允許工具針對特定執行選擇退出、
檢查沙盒狀態或綁定執行時期輔助程式。
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); },});工廠依然適用於固定的工具名稱。當外掛動態計算工具名稱,或將工具與 Hook、
服務、供應商、指令或其他執行時期介面結合時,請直接使用 definePluginEntry。
defineToolPlugin 會將一般回傳值包裝成 OpenClaw 工具結果
格式:
- 當模型應該看到該精確文字時,請回傳字串。
- 當您希望模型看到格式化的 JSON
並讓 OpenClaw 在
details中保留原始值時,請回傳 JSON 相容值。
tool({ name: "echo_text", description: "Echo input text.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => input,});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 會使用嚴格的空白物件
架構,且產生的清單仍會包含 configSchema。
export default defineToolPlugin({ id: "no-config-tools", name: "No Config Tools", description: "Adds tools that do not need configuration.", tools: () => [],});當您包含 configSchema 時,第二個 execute 引數會根據
架構進行型別標註:
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 設定中的 plugin 項目讀取外掛程式設定。請勿在原始碼或文件範例中硬編碼機密。請根據外掛程式的安全性模型,使用設定、環境變數或 SecretRefs。
生成的元資料
Section titled “生成的元資料”OpenClaw 從冷元資料探索已安裝的外掛程式。它必須能在匯入外掛程式執行時代碼之前讀取外掛程式清單。defineToolPlugin 因此會公開靜態元資料,而 openclaw plugins build 則會將該元資料寫入套件中。
在變更外掛程式 ID、名稱、描述、設定結構描述、啟動或工具名稱後,請執行產生器:
npm run buildopenclaw plugins build --entry ./dist/index.js對於單一工具的外掛程式,產生的清單如下所示:
{ "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 build 會將 package.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 中驗證
Section titled “在 CI 中驗證”當產生的元資料過時時,請使用 plugins build --check 讓 CI 失敗,而不重新寫入檔案:
npm run buildopenclaw plugins build --entry ./dist/index.js --checkopenclaw plugins validate --entry ./dist/index.jsnpm testplugins validate 會檢查:
openclaw.plugin.json存在並通過正常的清單載入器。- 目前的項目匯出
defineToolPlugin元資料。 - 產生的清單欄位符合項目元資料。
contracts.tools符合宣告的工具名稱。package.json將openclaw.extensions指向選定的執行時項目。
在本機安裝和檢查
Section titled “在本機安裝和檢查”從單獨的 OpenClaw 簽出或已安裝的 CLI,安裝套件路徑:
openclaw plugins install ./stock-quotesopenclaw plugins inspect stock-quotes --runtime對於打包的冒煙測試,請先打包並安裝 tarball:
npm packopenclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgzopenclaw plugins inspect stock-quotes --runtime --json安裝後,請啟動或重新啟動 Gateway,並要求代理程式使用該工具。如果您正在偵錯工具的可見性,請在變更程式碼之前檢查外掛程式執行時和有效的工具目錄。
當套件準備就緒時,透過 ClawHub 發佈:
clawhub package publish your-org/stock-quotes --dry-runclawhub package publish your-org/stock-quotes使用明確的 ClawHub 定位符安裝:
openclaw plugins install clawhub:your-org/stock-quotes在啟動切換期間,仍然支援純 npm 套件規格,但 ClawHub 是 OpenClaw 外掛的首選發現和發佈平台。
plugin entry not found: ./dist/index.js
Section titled “plugin entry not found: ./dist/index.js”選取的進入檔案不存在。請執行 npm run build,然後重新執行
openclaw plugins build --entry ./dist/index.js 或
openclaw plugins validate --entry ./dist/index.js。
plugin entry does not expose defineToolPlugin metadata
Section titled “plugin entry does not expose defineToolPlugin metadata”進入點未匯出由 defineToolPlugin 建立的值。請檢查模組預設匯出是否為 defineToolPlugin(...) 結果,或使用 --entry 傳遞正確的進入點。
openclaw.plugin.json generated metadata is stale
Section titled “openclaw.plugin.json generated metadata is stale”資訊清單不再符合進入點元資料。請執行:
npm run buildopenclaw plugins build --entry ./dist/index.js提交 openclaw.plugin.json 和 package.json 的變更。
package.json openclaw.extensions must include ./dist/index.js
Section titled “package.json openclaw.extensions must include ./dist/index.js”套件元資料指向不同的執行時期進入點。請執行
openclaw plugins build --entry ./dist/index.js,以便產生器將
套件元資料與您打算發佈的進入點對齊。
Cannot find package 'typebox'
Section titled “Cannot find package 'typebox'”建置的外掛在執行時期匯入了 typebox。請將 typebox 保留在
dependencies 中,重新安裝套件相依項,重新建置,並重新執行驗證。
安裝後工具未顯示
Section titled “安裝後工具未顯示”請依序檢查下列項目:
openclaw plugins inspect <plugin-id> --runtimeopenclaw plugins validate --root <plugin-root> --entry ./dist/index.jsopenclaw.plugin.json具有預期工具名稱的contracts.tools。package.json具有openclaw.extensions: ["./dist/index.js"]。- 安裝外掛後,已重新啟動或重新載入 Gateway。