Skip to main content

Tools

A file-based agent discovers tools from .ts and .js files directly under its tools/ directory. Each discovered file is imported at build time, the file must default-export a createTool() result, and the filename without its extension becomes the tool key the model can call.

Use this page for the file-based convention. For tool schemas, execution options, output shaping, and approval options, see the createTool() reference.

Quickstart
Direct link to Quickstart

Place one tool per file under tools/. This file is exposed to the agent as get_weather.

src/mastra/agents/weather/tools/get_weather.ts
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'

export default createTool({
id: 'get_weather',
description: 'Get the current weather for a city.',
inputSchema: z.object({
city: z.string(),
}),
outputSchema: z.object({
city: z.string(),
tempC: z.number(),
}),
execute: async ({ context }) => {
return { city: context.city, tempC: 21 }
},
})

Organizing tools
Direct link to Organizing tools

Use one file per tool. Name the file after the action the model should take:

  • Use get_weather.ts, search_docs.ts, or create_ticket.ts.
  • Avoid vague names like helper.ts, api.ts, or utils.ts.
  • Co-locate tests next to the tool as *.test.ts or *.spec.ts; discovery ignores those files.
  • Keep shared helper code outside tools/ or in files that don't match the discovered extensions under tools/.

Because nested directories aren't discovered as tools, group related tools with clear filename prefixes instead of subfolders, such as calendar_create_event.ts and calendar_list_events.ts.

Tool options
Direct link to Tool options

The file-based convention only controls where the tool lives and how it's registered. The tool API still comes from createTool():

  • Use description to tell the model when to call the tool.
  • Use inputSchema and outputSchema for structured inputs and outputs.
  • Use toModelOutput when the model should see a different shape than the raw value returned from execute.
  • Use requireApproval when a tool needs human confirmation before execution.

See the createTool() reference for all options and tool approval for the approval flow.

Runtime boundary
Direct link to Runtime boundary

Tool code runs in your app/server runtime when the agent calls the tool. If a tool needs filesystem or shell isolation, call workspace or sandbox APIs explicitly.

Precedence with config
Direct link to Precedence with config

Discovered tools merge with any tools in config.ts. On a key collision, config.tools wins and a warning is logged.

If config.tools is a function, discovered tools are ignored with a warning because function-valued tools can't be statically merged.

On this page