---
title: "Reference: createTool() | Tools & MCP"
description: Documentation for the `createTool()` function in Mastra, used to define custom tools for agents.
packages:
  - "@mastra/core"
---

# 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 example

```typescript title="src/mastra/tools/reverse-tool.ts"
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,
    };
  },
});
```

## Parameters

<PropertiesTable
  content={[
    {
      name: "id",
      type: "string",
      description: "A unique identifier for the tool.",
      isOptional: false,
    },
    {
      name: "description",
      type: "string",
      description:
        "A description of what the tool does. This is used by the agent to decide when to use the tool.",
      isOptional: false,
    },
    {
      name: "inputSchema",
      type: "Zod schema",
      description:
        "A Zod schema defining the expected input parameters for the tool's `execute` function.",
      isOptional: true,
    },
    {
      name: "outputSchema",
      type: "Zod schema",
      description:
        "A Zod schema defining the expected output structure of the tool's `execute` function.",
      isOptional: true,
    },
    {
      name: "suspendSchema",
      type: "Zod schema",
      description:
        "A Zod schema defining the structure of the payload passed to `suspend()`. This payload is returned to the client when the tool suspends execution.",
      isOptional: true,
    },
    {
      name: "resumeSchema",
      type: "Zod schema",
      description:
        "A Zod schema defining the expected structure of `resumeData` when the tool is resumed. Used by the agent to extract data from user messages when `autoResumeSuspendedTools` is enabled.",
      isOptional: true,
    },
    {
      name: "requireApproval",
      type: "boolean",
      description:
        "When true, the tool requires explicit approval before execution. The agent will emit a `tool-call-approval` chunk and pause until approved or declined.",
      isOptional: true,
    },
    {
      name: "execute",
      type: "function",
      description:
        "The function that contains the tool's logic. It receives two parameters: the validated input data (first parameter) and an optional execution context object (second parameter) containing `requestContext`, `tracingContext`, `abortSignal`, and other execution metadata.",
      isOptional: false,
      properties: [
        {
          parameters: [
            {
              name: "input",
              type: "z.infer<TInput>",
              description: "The validated input data based on inputSchema",
            },
          ],
        },
        {
          parameters: [
            {
              name: "context",
              type: "ToolExecutionContext",
              isOptional: true,
              description: "Optional execution context containing metadata",
              properties: [
                {
                  name: "requestContext",
                  type: "RequestContext",
                  isOptional: true,
                  description:
                    "Request Context for accessing shared state and dependencies",
                },
                {
                  name: "tracingContext",
                  type: "TracingContext",
                  isOptional: true,
                  description:
                    "Tracing context for creating child spans and adding metadata",
                },
                {
                  name: "abortSignal",
                  type: "AbortSignal",
                  isOptional: true,
                  description: "Signal for aborting the tool execution",
                },
                {
                  name: "agent",
                  type: "AgentToolExecutionContext",
                  isOptional: true,
                  description: "Agent-specific context (messages, suspend, resumeData, etc.)",
                },
                {
                  name: "workflow",
                  type: "WorkflowToolExecutionContext",
                  isOptional: true,
                  description: "Workflow-specific context (state, setState, suspend, etc.)",
                },
                {
                  name: "mcp",
                  type: "MCPToolExecutionContext",
                  isOptional: true,
                  description: "MCP-specific context (elicitation, etc.)",
                },
              ],
            },
          ],
        },
      ],
    },
    {
      name: "onInputStart",
      type: "function",
      description:
        "Optional callback invoked when the tool call input streaming begins. Receives `toolCallId`, `messages`, and `abortSignal`.",
      isOptional: true,
    },
    {
      name: "onInputDelta",
      type: "function",
      description:
        "Optional callback invoked for each incremental chunk of input text as it streams in. Receives `inputTextDelta`, `toolCallId`, `messages`, and `abortSignal`.",
      isOptional: true,
    },
    {
      name: "onInputAvailable",
      type: "function",
      description:
        "Optional callback invoked when the complete tool input is available and parsed. Receives the validated `input` object, `toolCallId`, `messages`, and `abortSignal`.",
      isOptional: true,
    },
    {
      name: "onOutput",
      type: "function",
      description:
        "Optional callback invoked after the tool has successfully executed and returned output. Receives the tool's `output`, `toolCallId`, `messages`, and `abortSignal`.",
      isOptional: true,
    },
  ]}
/>

## Returns

The `createTool()` function returns a `Tool` object.

<PropertiesTable
  content={[
    {
      name: "Tool",
      type: "object",
      description:
        "An object representing the defined tool, ready to be added to an agent.",
    },
  ]}
/>

## 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 Hooks

#### onInputStart

Called when tool call input streaming begins, before any input data is received.

```typescript
export const tool = createTool({
  id: "example-tool",
  description: "Example tool with hooks",
  onInputStart: ({ toolCallId, messages, abortSignal }) => {
    console.log(`Tool ${toolCallId} input streaming started`);
  },
});
```

#### onInputDelta

Called for each incremental chunk of input text as it streams in. Useful for showing real-time progress or parsing partial JSON.

```typescript
export const tool = createTool({
  id: "example-tool",
  description: "Example tool with hooks",
  onInputDelta: ({ inputTextDelta, toolCallId, messages, abortSignal }) => {
    console.log(`Received input chunk: ${inputTextDelta}`);
  },
});
```

#### onInputAvailable

Called when the complete tool input is available and has been parsed and validated against the `inputSchema`.

```typescript
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
  },
});
```

#### onOutput

Called after the tool has successfully executed and returned output. Useful for logging results, triggering follow-up actions, or analytics.

```typescript
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 Order

For a typical streaming tool call, the hooks are invoked in this order:

1. **onInputStart** - Input streaming begins
2. **onInputDelta** - Called multiple times as chunks arrive
3. **onInputAvailable** - Complete input is parsed and validated
4. Tool's **execute** function runs
5. **onOutput** - Tool has completed successfully

### Hook Parameters

All hooks receive a parameter object with these common properties:

- `toolCallId` (string): Unique identifier for this specific tool call
- `abortSignal` (AbortSignal): Signal for detecting if the operation should be cancelled

Additionally:
- `onInputStart`, `onInputDelta`, and `onInputAvailable` receive `messages` (array): The conversation messages at the time of the tool call
- `onInputDelta` receives `inputTextDelta` (string): The incremental text chunk
- `onInputAvailable` receives `input`: The validated input data (typed according to `inputSchema`)
- `onOutput` receives `output`: The tool's return value (typed according to `outputSchema`) and `toolName` (string): The name of the tool

### 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.

## Related

- [MCP Overview](/docs/v1/mcp/overview)
- [Using Tools with Agents](/docs/v1/agents/using-tools)
- [Agent Approval](/docs/v1/agents/agent-approval)
- [Tool Streaming](/docs/v1/streaming/tool-streaming)
- [Request Context](/docs/v1/server/request-context#accessing-values-with-tools)
