Building plugins
टूल Plugin
Tool Plugin, OpenClaw में channel, model provider, hook, service, या setup backend जोड़े बिना agent-callable टूल जोड़ते हैं। defineToolPlugin का उपयोग तब करें जब
Plugin टूल की एक निश्चित सूची का स्वामी हो और आप चाहते हों कि OpenClaw वह manifest
metadata जनरेट करे जो runtime code लोड किए बिना उन टूल को खोजने योग्य बनाए रखता है।
अनुशंसित प्रवाह यह है:
openclaw plugins initके साथ package scaffold करें।defineToolPluginके साथ टूल लिखें।- JavaScript build करें।
openclaw plugins buildके साथopenclaw.plugin.jsonऔरpackage.jsonmetadata जनरेट करें।- प्रकाशित या इंस्टॉल करने से पहले जनरेट किए गए metadata को validate करें।
provider, channel, hook, service, या mixed-capability Plugins के लिए, इसके बजाय Building plugins, Channel Plugins, या Provider Plugins से शुरू करें।
आवश्यकताएँ
- Node >= 22.
- TypeScript ESM package output.
- config और tool parameter schemas के लिए
typebox. openclaw >=2026.5.17, पहला OpenClaw version जोopenclaw/plugin-sdk/tool-pluginexport करता है।- ऐसा package root जो
dist/,openclaw.plugin.json, औरpackage.jsonship कर सके।
जनरेट किया गया Plugin runtime पर typebox import करता है, इसलिए typebox को
सिर्फ devDependencies में नहीं, बल्कि dependencies में रखें।
Quickstart
नया Plugin package बनाएँ:
openclaw plugins init stock-quotes --name "Stock Quotes"cd stock-quotesnpm installnpm run plugin:buildnpm run plugin:validatenpm testscaffold बनाता है:
src/index.ts:echotool के साथ एकdefineToolPluginentry.src/index.test.ts: एक छोटा metadata test.tsconfig.json:dist/में NodeNext TypeScript output.package.json: scripts, runtime dependencies, औरopenclaw.extensions: ["./dist/index.js"].openclaw.plugin.json: शुरुआती tool के लिए जनरेट किया गया manifest metadata.
अपेक्षित validation output:
Plugin stock-quotes is valid.टूल लिखें
defineToolPlugin Plugin identity, एक वैकल्पिक config schema, और
टूल की static सूची लेता है। Parameter और config types TypeBox schemas से infer किए जाते हैं।
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", }; }, }), ],});Tool names स्थिर API हैं। ऐसे names चुनें जो unique, lowercase, और core tools या दूसरे Plugins से टकराव से बचने के लिए पर्याप्त specific हों।
वैकल्पिक और factory टूल
जब users को tool model को भेजे जाने से पहले उसे स्पष्ट रूप से allowlist करना चाहिए, तब optional: true set करें:
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
manifest entry लिखता है, ताकि OpenClaw Plugin runtime code लोड किए बिना tool खोज सके।
जब किसी tool को बनने से पहले runtime tool context की आवश्यकता हो, तब factory का उपयोग करें। factory metadata को static रखती है और tool को किसी
specific run के लिए opt out करने, sandbox state inspect करने, या runtime helpers bind करने देती है।
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); },});Factories अब भी fixed tool names के लिए हैं। जब
Plugin tool names को dynamically compute करता है या tools को hooks,
services, providers, commands, या अन्य runtime surfaces के साथ जोड़ता है, तब सीधे definePluginEntry का उपयोग करें।
Return values
defineToolPlugin plain return values को OpenClaw tool-result
format में wrap करता है:
- जब model को वही exact text दिखना चाहिए, तब string return करें।
- जब आप चाहते हैं कि model formatted JSON देखे
और OpenClaw original value को
detailsमें रखे, तब JSON-compatible value return करें।
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 }),});जब आपको custom AgentToolResult return करना हो या मौजूदा
api.registerTool implementation reuse करना हो, तब factory tool का उपयोग करें। जब आपको पूरी तरह dynamic tools या mixed Plugin
capabilities की आवश्यकता हो, तब defineToolPlugin के बजाय definePluginEntry का उपयोग करें।
Configuration
configSchema वैकल्पिक है। यदि आप इसे omit करते हैं, तो OpenClaw strict empty object
schema का उपयोग करता है और जनरेट किए गए manifest में फिर भी configSchema शामिल होता है।
export default defineToolPlugin({ id: "no-config-tools", name: "No Config Tools", description: "Adds tools that do not need configuration.", tools: () => [],});जब आप configSchema शामिल करते हैं, तो दूसरा execute argument
schema से type किया जाता है:
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 Plugin config को Gateway config में Plugin entry से पढ़ता है। source या docs examples में secrets hard-code न करें। Plugin के security model के अनुसार config, environment variables, या SecretRefs का उपयोग करें।
जनरेट किया गया metadata
OpenClaw installed Plugins को cold metadata से discover करता है। उसे Plugin runtime code import करने से पहले
Plugin manifest पढ़ने में सक्षम होना चाहिए। इसलिए defineToolPlugin
static metadata expose करता है, और openclaw plugins build उस
metadata को package में लिखता है।
Plugin id, name, description, config schema, activation, या tool names बदलने के बाद generator चलाएँ:
npm run buildopenclaw plugins build --entry ./dist/index.jsएक one-tool Plugin के लिए, जनरेट किया गया manifest ऐसा दिखता है:
{ "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 महत्वपूर्ण discovery contract है। यह OpenClaw को बताता है कि हर tool का स्वामी कौन सा
Plugin है, बिना हर installed Plugin runtime को लोड किए। यदि
manifest stale है, तो tool discovery से missing हो सकता है या registration error के लिए गलत Plugin को दोषी माना जा सकता है।
Package metadata
सरल tool-Plugin workflow के लिए, openclaw plugins build
package.json को selected single runtime entry के साथ align करता है:
{ "type": "module", "files": ["dist", "openclaw.plugin.json", "README.md"], "dependencies": { "typebox": "^1.1.38" }, "peerDependencies": { "openclaw": ">=2026.5.17" }, "openclaw": { "extensions": ["./dist/index.js"] }}installed packages के लिए ./dist/index.js जैसी built JavaScript का उपयोग करें। Source
entries workspace development में उपयोगी हैं, लेकिन published packages को
TypeScript runtime loading पर निर्भर नहीं होना चाहिए।
CI में validate करें
जनरेट किया गया metadata stale होने पर files rewrite किए बिना CI fail करने के लिए plugins build --check का उपयोग करें:
npm run buildopenclaw plugins build --entry ./dist/index.js --checkopenclaw plugins validate --entry ./dist/index.jsnpm testplugins validate जाँचता है कि:
openclaw.plugin.jsonमौजूद है और normal manifest loader से pass होता है।- current entry
defineToolPluginmetadata export करती है। - जनरेट किए गए manifest fields entry metadata से match करते हैं।
contracts.toolsdeclared tool names से match करता है।package.jsonopenclaw.extensionsको selected runtime entry पर point करता है।
स्थानीय रूप से install और inspect करें
अलग OpenClaw checkout या installed CLI से, package path install करें:
openclaw plugins install ./stock-quotesopenclaw plugins inspect stock-quotes --runtimepackaged smoke के लिए, पहले pack करें और tarball install करें:
npm packopenclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgzopenclaw plugins inspect stock-quotes --runtime --jsoninstallation के बाद, Gateway start या restart करें और agent से tool का उपयोग करने को कहें। यदि आप tool visibility debug कर रहे हैं, तो code बदलने से पहले Plugin runtime और effective tool catalog inspect करें।
Publish
package ready होने पर ClawHub के माध्यम से publish करें:
clawhub package publish your-org/stock-quotes --dry-runclawhub package publish your-org/stock-quotesexplicit ClawHub locator के साथ install करें:
openclaw plugins install clawhub:your-org/stock-quotesBare npm package specs launch cutover के दौरान supported रहते हैं, लेकिन ClawHub OpenClaw Plugins के लिए preferred discovery और distribution surface है।
Troubleshooting
plugin entry not found: ./dist/index.js
selected entry file मौजूद नहीं है। npm run build चलाएँ, फिर
openclaw plugins build --entry ./dist/index.js या
openclaw plugins validate --entry ./dist/index.js फिर से चलाएँ।
plugin entry does not expose defineToolPlugin metadata
entry ने defineToolPlugin द्वारा created value export नहीं की। जाँचें कि
module default export defineToolPlugin(...) result है, या --entry के साथ सही
entry pass करें।
openclaw.plugin.json generated metadata is stale
manifest अब entry metadata से match नहीं करता। चलाएँ:
npm run buildopenclaw plugins build --entry ./dist/index.jsopenclaw.plugin.json और package.json दोनों changes commit करें।
package.json openclaw.extensions must include ./dist/index.js
package metadata किसी अलग runtime entry की ओर point करता है। openclaw plugins build --entry ./dist/index.js चलाएँ ताकि generator
package metadata को उस entry के साथ align करे जिसे आप ship करना चाहते हैं।
Cannot find package 'typebox'
built Plugin runtime पर typebox import करता है। typebox को
dependencies में रखें, package dependencies reinstall करें, rebuild करें, और validation फिर से चलाएँ।
install के बाद tool दिखाई नहीं देता
इन्हें क्रम में जाँचें:
openclaw plugins inspect <plugin-id> --runtimeopenclaw plugins validate --root <plugin-root> --entry ./dist/index.jsopenclaw.plugin.jsonमें expected tool names के साथcontracts.toolsहै।package.jsonमेंopenclaw.extensions: ["./dist/index.js"]है।- Plugin install करने के बाद Gateway restart या reload किया गया था।