Plugin SDK reference
Plugin SDK defineToolPlugin helper
The entry helper for plugins that only add agent tools. Part of the Plugin entry points reference.
defineToolPlugin
Import: openclaw/plugin-sdk/tool-plugin
For plugins that only add agent tools. Keeps the source small, infers config
and tool-parameter types from TypeBox schemas, wraps plain return values in
the OpenClaw tool-result format, and exposes static metadata that
openclaw plugins build writes into the plugin manifest (contracts.tools,
configSchema).
import { Type } from "typebox";import { defineToolPlugin } from "openclaw/plugin-sdk/tool-plugin"; export default defineToolPlugin({ id: "stock-quotes", name: "Stock Quotes", description: "Fetch stock quotes.", configSchema: Type.Object({ apiKey: Type.Optional(Type.String({ description: "API key." })), }), tools: (tool) => [ tool({ name: "quote", label: "Quote", description: "Fetch a quote.", parameters: Type.Object({ symbol: Type.String({ description: "Ticker symbol." }), }), outputSchema: Type.Object( { symbol: Type.String(), hasKey: Type.Boolean(), }, { additionalProperties: false }, ), execute: async ({ symbol }, config) => ({ symbol, hasKey: Boolean(config.apiKey) }), }), ],});configSchemais optional; omitting it uses a strict empty object schema (the generated manifest still includesconfigSchema).executereturns a plain string or JSON-serializable value; the helper wraps it as a text tool result withdetailsset to the original (unstringified) return value.outputSchemaoptionally describes that originaldetailsvalue for Code Mode and Tool Search. Catalog calls reject an invalid schema before execution and validate the final value before returning it.- For custom tool results,
openclaw/plugin-sdk/tool-resultsexportstextResultandjsonResult. - Tool names are static, so
openclaw plugins buildderivescontracts.toolsfrom the declared tools without hand-duplicated names. - Runtime loading stays strict: installed plugins still need
openclaw.plugin.jsonandpackage.jsonopenclaw.extensions. OpenClaw never executes plugin code to infer missing manifest data.
Was this useful?