Skip to content
prod e051e98
Browse

Tools

Capabilities

An agent reasons; a tool is how it acts. A tool is a typed function the model may call — query a database, hit an API, run a calculation. Its input and output schemas (Zod, Valibot, or ArkType) mean the model’s arguments are validated before your code runs, and the result shape is predictable. That validation boundary is the whole point: the non-deterministic model can only reach your deterministic code through a typed contract.

One tool call, end to end

One tool call, end to end 1. Model decides (picks tool + args) → 2. Validate input (Zod inputSchema) → 3. execute() (your code runs) → 4. Validate output (Zod outputSchema) → 5. Back to model (typed result) Model decides picks tool + args Validate input Zod inputSchema execute() your code runs Validate output Zod outputSchema Back to model typed result
The model proposes arguments; Mastra validates them against the input schema before execute() runs, then validates the result before handing it back to the model.

createTool takes an id, a description (the model reads this to decide when to call it), the two schemas, and an execute function. The execute receives the validated input directly.

import { createTool } from '@mastra/core/tools';
import { z } from 'zod';
export const weatherTool = createTool({
id: 'get-weather',
description: 'Get the current weather for a location',
inputSchema: z.object({
location: z.string().describe('City name, e.g. "San Francisco"'),
}),
outputSchema: z.object({ weather: z.string() }),
execute: async ({ location }) => {
const res = await fetch(`https://wttr.in/${location}?format=3`);
return { weather: await res.text() };
},
});

Register tools on the agent under a name. The model decides which tool to call and when; you never invoke it by hand.

import { Agent } from '@mastra/core/agent';
import { weatherTool } from './tools/weather-tool';
export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: 'Use get-weather before answering questions about conditions.',
model: 'openai/gpt-4o',
tools: { weatherTool },
});
  1. One job per tool. A focused get-weather beats a vague do-stuff the model can’t reason about.
  2. Tight schemas. Constrain inputs (.min(), .max(), enums) so invalid calls fail validation, not at runtime.
  3. Describe everything. description + .describe() on each field are how the model learns the contract.
  4. Make execute idempotent where you can — the model may retry, and workflows may replay around it.

Reference: Using tools · createTool · Dynamic tools

Next: Workflows — when one agent call isn’t enough.