Skip to main content

Overview

Tools are type-safe functions that agents and workflows can call to perform specific actions. They provide automatic input/output validation, suspend/resume capabilities, and integration with the Mastra ecosystem.

Creating Tools

createTool

createTool<TId, TSchemaIn, TSchemaOut, TSuspend, TResume, TRequestContext, TContext>(
  opts: ToolAction
): Tool<TSchemaIn, TSchemaOut, TSuspend, TResume, TContext, TId, TRequestContext>
Creates a type-safe tool with automatic input validation.
opts
ToolAction
required
Tool configuration
tool
Tool
A type-safe Tool instance with conditional typing based on schemas

Properties

id
string
Unique identifier for the tool
description
string
Description of what the tool does
inputSchema
SchemaWithValidation | undefined
Schema for validating input parameters
outputSchema
SchemaWithValidation | undefined
Schema for validating output structure
suspendSchema
SchemaWithValidation | undefined
Schema for suspend operation data
resumeSchema
SchemaWithValidation | undefined
Schema for resume operation data
requestContextSchema
SchemaWithValidation | undefined
Schema for validating request context values
mastra
Mastra | undefined
Parent Mastra instance for accessing shared resources
requireApproval
boolean | undefined
Whether the tool requires explicit user approval before execution
providerOptions
Record<string, Record<string, unknown>> | undefined
Provider-specific options passed to the model
toModelOutput
((output: TSchemaOut) => unknown) | undefined
Function to transform output before sending to model
mcp
MCPToolProperties | undefined
MCP-specific properties

Execute Function

The execute function receives validated input and an execution context.

Parameters

inputData
TSchemaIn
required
The validated input data
context
ToolExecutionContext
required
Execution context

Return Value

The execute function should return:
  • The tool output (validated against outputSchema)
  • A Promise that resolves to the output
  • A ValidationError if validation fails

Examples

Simple Tool

import { createTool } from '@mastra/core/tools';
import { z } from 'zod';

const greetTool = createTool({
  id: 'greet',
  description: 'Say hello to someone',
  inputSchema: z.object({
    name: z.string()
  }),
  outputSchema: z.object({
    message: z.string()
  }),
  execute: async ({ name }) => {
    return { message: `Hello, ${name}!` };
  }
});

Tool with Validation

const calculateTool = createTool({
  id: 'calculate',
  description: 'Perform calculations',
  inputSchema: z.object({
    operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
    a: z.number(),
    b: z.number()
  }),
  outputSchema: z.object({
    result: z.number()
  }),
  execute: async ({ operation, a, b }) => {
    let result: number;
    switch (operation) {
      case 'add':
        result = a + b;
        break;
      case 'subtract':
        result = a - b;
        break;
      case 'multiply':
        result = a * b;
        break;
      case 'divide':
        if (b === 0) throw new Error('Division by zero');
        result = a / b;
        break;
    }
    return { result };
  }
});

Tool with Mastra Integration

const saveTool = createTool({
  id: 'save-data',
  description: 'Save data to storage',
  inputSchema: z.object({
    key: z.string(),
    value: z.any()
  }),
  outputSchema: z.object({
    saved: z.boolean(),
    key: z.string()
  }),
  execute: async ({ key, value }, context) => {
    const storage = context?.mastra?.getStorage();
    if (storage) {
      // Save to Mastra storage
      await storage.set(key, value);
    }
    return { saved: true, key };
  }
});

Tool Requiring Approval

const deleteFileTool = createTool({
  id: 'delete-file',
  description: 'Delete a file (requires approval)',
  requireApproval: true,
  inputSchema: z.object({
    filepath: z.string()
  }),
  outputSchema: z.object({
    deleted: z.boolean(),
    filepath: z.string()
  }),
  execute: async ({ filepath }) => {
    // Delete the file
    await fs.unlink(filepath);
    return { deleted: true, filepath };
  }
});

Tool with Suspend/Resume

const approvalTool = createTool({
  id: 'approval',
  description: 'Request user approval',
  inputSchema: z.object({
    action: z.string(),
    details: z.any()
  }),
  outputSchema: z.object({
    approved: z.boolean()
  }),
  suspendSchema: z.object({
    requestId: z.string(),
    timestamp: z.number()
  }),
  resumeSchema: z.object({
    approved: z.boolean()
  }),
  execute: async ({ action, details }, context) => {
    // Check for resume data
    const resumeData = context?.agent?.resumeData || context?.workflow?.resumeData;
    
    if (!resumeData) {
      // First call - suspend and wait for approval
      const requestId = crypto.randomUUID();
      const suspend = context?.agent?.suspend || context?.workflow?.suspend;
      suspend?.({ requestId, timestamp: Date.now() });
      return { approved: false };
    }
    
    // Resumed after approval
    return { approved: resumeData.approved };
  }
});

Tool with Provider Options

const searchTool = createTool({
  id: 'search',
  description: 'Search the web',
  inputSchema: z.object({
    query: z.string()
  }),
  providerOptions: {
    anthropic: {
      cacheControl: { type: 'ephemeral' }
    }
  },
  execute: async ({ query }) => {
    // Perform search
    return { results: [] };
  }
});

Tool with Request Context

const userTool = createTool({
  id: 'get-user-data',
  description: 'Get current user data',
  requestContextSchema: z.object({
    userId: z.string()
  }),
  outputSchema: z.object({
    name: z.string(),
    email: z.string()
  }),
  execute: async (inputData, context) => {
    const userId = context?.requestContext?.get('userId');
    // Fetch user data using userId
    return {
      name: 'John Doe',
      email: 'john@example.com'
    };
  }
});