> Fetch clean Markdown by appending `.md` to any page URL under https://signalwire.com/docs or requesting it with the HTTP header `Accept: text/markdown`. The root index at https://signalwire.com/docs/llms.txt lists the available documentation indexes. # defineTool > Programmatically define a SWAIG tool that the AI can invoke during conversations. [swaig-function]: /docs/swml/reference/calling/ai/swaig/functions [swml-swaig-functions-reference]: /docs/swml/reference/calling/ai/swaig/functions [functionresult]: /docs/server-sdks/reference/typescript/agents/function-result [ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [parameter-schema]: /docs/server-sdks/reference/typescript/agents/parameter-schema [on-error]: /docs/server-sdks/reference/typescript/agents/agent-base/on-error Programmatically define a SWAIG function (tool) that the AI can invoke during a conversation. > **Info** > > Tool definitions map to SWML [SWAIG function][swaig-function] > entries. See the [SWML SWAIG functions reference][swml-swaig-functions-reference] > for the full specification. > **Tip** > > For cleaner typed handler signatures with automatic parameter inference, consider > using [`defineTypedTool()`](/docs/server-sdks/reference/typescript/agents/agent-base/define-typed-tool) > instead. ## **Parameters** **`opts`** `object` — required Tool definition object. --- **`opts.name`** `string` — required Tool name. Must be unique within the agent. The AI uses this name to invoke the function. --- **`opts.description`** `string` — required Human-readable description of what the tool does. The AI reads this to decide when to call the tool. --- **`opts.parameters`** `ToolParameters` JSON Schema describing the tool's parameters. Write it either as a flat map of property name to schema (`{ city: { type: 'string' } }`) or as a wrapped object schema (`{ type: 'object', properties: { ... } }`). With the flat form the handler's `args` is typed from the schema, so `args.city` is a `string` and an `enum` narrows to its literal union. You can also build the schema with [`paramSchema()`][parameter-schema]. --- **`opts.handler`** `SwaigHandler` — required Callback invoked when the AI calls this tool. Receives `(args, rawData: SwaigRequest)` and returns a [`FunctionResult`][functionresult], a plain object, or a string. --- **`opts.secure`** `boolean` — default: true Whether to require token validation on tool calls. Tools are secure by default: the rendered webhook URL carries a per-tool token. Pass `false` only to expose the tool on the shared, unauthenticated webhook URL. --- **`opts.fillers`** `Record` Language-specific filler phrases spoken while the tool executes. Format: `{ 'en-US': ['Looking that up...', 'One moment...'] }`. --- **`opts.waitFile`** `string` URL of an audio file to play while the tool executes. --- **`opts.waitFileLoops`** `number` Number of times to loop the wait file. --- **`opts.required`** `string[]` List of required parameter names from the JSON Schema. --- **`opts.webhookUrl`** `string` External webhook URL. When set, the tool is treated as externally-hosted and the tool call is forwarded to this URL instead of being dispatched to a local handler. --- **`opts.extraFields`** `Record` Additional fields merged into the SWAIG function definition. Equivalent to Python's `**swaig_fields` kwargs (e.g., `meta_data`). --- **`opts.onError`** `SwaigErrorHandler` Per-tool error hook, called when the handler throws. Return a [`FunctionResult`][functionresult] to control what the caller hears, or nothing to fall back to `errorMessage`. Runs before the agent-level [`onError()`][on-error] hook. --- **`opts.errorMessage`** `string` Message spoken to the caller when the handler throws and no error hook supplies a response. Defaults to a generic apology asking the caller to try again. --- ## **Returns** [`AgentBase`][ref-agentbase] -- Returns `this` for method chaining. ## **Example** ```typescript {6} import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'weather-agent', route: '/weather' }); agent.setPromptText('You are a helpful assistant.'); agent.defineTool({ name: 'get_weather', description: 'Get the current weather for a city', parameters: { type: 'object', properties: { city: { type: 'string', description: 'City name' }, }, }, handler: async (args) => { const city = (args.city as string) ?? 'unknown'; return new FunctionResult(`The weather in ${city} is 72F and sunny.`); }, required: ['city'], fillers: { 'en-US': ['Checking the weather...', 'Let me look that up...'] }, }); await agent.serve(); ``` > Programmatically define a SWAIG tool that the AI can invoke during conversations.