createTool()
The createTool() function is used to define custom tools that your Mastra agents can execute. Tools extend an agent's capabilities by allowing it to interact with external systems, perform calculations, or access specific data.
Usage exampleDirect link to Usage example
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
export const tool = createTool({
id: "test-tool",
description: "Reverse the input string",
inputSchema: z.object({
input: z.string(),
}),
outputSchema: z.object({
output: z.string(),
}),
execute: async (inputData) => {
const reversed = inputData.input.split("").reverse().join("");
return {
output: reversed,
};
},
});
Example with MCP AnnotationsDirect link to Example with MCP Annotations
When exposing tools via MCP (Model Context Protocol), you can add annotations to describe tool behavior and customize how clients display the tool. These MCP-specific properties are grouped under the mcp property:
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
export const weatherTool = createTool({
id: "get-weather",
description: "Get current weather for a location",
inputSchema: z.object({
location: z.string().describe("City name or coordinates"),
}),
// MCP-specific properties
mcp: {
// Annotations for client behavior hints
annotations: {
title: "Weather Lookup", // Human-readable display name
readOnlyHint: true, // Tool doesn't modify environment
destructiveHint: false, // Tool doesn't perform destructive updates
idempotentHint: true, // Same args = same result
openWorldHint: true, // Interacts with external API
},
// Custom metadata for client-specific functionality
_meta: {
version: "1.0.0",
category: "weather",
},
},
execute: async (inputData) => {
const weather = await fetchWeather(inputData.location);
return { weather };
},
});
ParametersDirect link to Parameters
id:
description:
inputSchema?:
outputSchema?:
suspendSchema?:
resumeSchema?:
requireApproval?:
mcp?:
execute:
input:
context?:
onInputStart?:
onInputDelta?:
onInputAvailable?:
onOutput?:
ReturnsDirect link to Returns
The createTool() function returns a Tool object.
Tool:
Tool Lifecycle HooksDirect link to Tool Lifecycle Hooks
Tools support lifecycle hooks that allow you to monitor and react to different stages of tool execution. These hooks are particularly useful for logging, analytics, validation, and real-time updates during streaming.
Available HooksDirect link to Available Hooks
onInputStartDirect link to onInputStart
Called when tool call input streaming begins, before any input data is received.
export const tool = createTool({
id: "example-tool",
description: "Example tool with hooks",
onInputStart: ({ toolCallId, messages, abortSignal }) => {
console.log(`Tool ${toolCallId} input streaming started`);
},
});
onInputDeltaDirect link to onInputDelta
Called for each incremental chunk of input text as it streams in. Useful for showing real-time progress or parsing partial JSON.
export const tool = createTool({
id: "example-tool",
description: "Example tool with hooks",
onInputDelta: ({ inputTextDelta, toolCallId, messages, abortSignal }) => {
console.log(`Received input chunk: ${inputTextDelta}`);
},
});
onInputAvailableDirect link to onInputAvailable
Called when the complete tool input is available and has been parsed and validated against the inputSchema.
export const tool = createTool({
id: "example-tool",
description: "Example tool with hooks",
inputSchema: z.object({
city: z.string(),
}),
onInputAvailable: ({ input, toolCallId, messages, abortSignal }) => {
console.log(`Tool received complete input:`, input);
// input is fully typed based on inputSchema
},
});
onOutputDirect link to onOutput
Called after the tool has successfully executed and returned output. Useful for logging results, triggering follow-up actions, or analytics.
export const tool = createTool({
id: "example-tool",
description: "Example tool with hooks",
outputSchema: z.object({
result: z.string(),
}),
execute: async (input) => {
return { result: "Success" };
},
onOutput: ({ output, toolCallId, toolName, abortSignal }) => {
console.log(`${toolName} execution completed:`, output);
// output is fully typed based on outputSchema
},
});
Hook Execution OrderDirect link to Hook Execution Order
For a typical streaming tool call, the hooks are invoked in this order:
- onInputStart - Input streaming begins
- onInputDelta - Called multiple times as chunks arrive
- onInputAvailable - Complete input is parsed and validated
- Tool's execute function runs
- onOutput - Tool has completed successfully
Hook ParametersDirect link to Hook Parameters
All hooks receive a parameter object with these common properties:
toolCallId(string): Unique identifier for this specific tool callabortSignal(AbortSignal): Signal for detecting if the operation should be cancelled
Additionally:
onInputStart,onInputDelta, andonInputAvailablereceivemessages(array): The conversation messages at the time of the tool callonInputDeltareceivesinputTextDelta(string): The incremental text chunkonInputAvailablereceivesinput: The validated input data (typed according toinputSchema)onOutputreceivesoutput: The tool's return value (typed according tooutputSchema) andtoolName(string): The name of the tool
Error HandlingDirect link to Error Handling
Hook errors are caught and logged automatically, but do not prevent tool execution from continuing. If a hook throws an error, it will be logged to the console but will not fail the tool call.
MCP Tool AnnotationsDirect link to MCP Tool Annotations
When exposing tools via the Model Context Protocol (MCP), you can provide annotations that describe tool behavior. These annotations help MCP clients like OpenAI Apps SDK understand how to present and handle your tools.
MCP-specific properties are grouped under the mcp property, which includes annotations and _meta:
mcp: {
annotations: { /* behavior hints */ },
_meta: { /* custom metadata */ },
}
ToolAnnotations PropertiesDirect link to ToolAnnotations Properties
title?:
readOnlyHint?:
destructiveHint?:
idempotentHint?:
openWorldHint?:
These annotations follow the MCP specification and are passed through when tools are listed via MCP.