Workik.

Mastra Tutorial for Beginners: Build AI Agents in TypeScript

Mastra Tools: Giving Your Agent Tools

Give your Mastra agent tools with createTool and Zod schemas. Build an order status tool, control steps with maxSteps, and test it in Mastra Studio.

Large language models are trained on historical data. They cannot look inside your live database or check current package tracking numbers on their own. Tools bridge this gap by turning your TypeScript functions into actions that an AI agent can execute on demand.

In the previous lesson, you built a basic support agent that answers general text queries. Now you will expand your online store assistant by giving it an order lookup tool so it can fetch real-time shipping data for customers.

Previous lesson: Building Your First Mastra Agent | Next lesson: Adding Memory to Your Mastra Agent


How AI Agents Use Tools

A tool is a typed TypeScript function exposed to a model along with a schema that describes what the function does and what arguments it expects.

Think of a tool like a database lookup terminal on a support rep's desk. The representative knows when to type an order number into that terminal based on what the customer asks.

When you pass tools to a Mastra agent, the following interaction happens:

  1. The user asks a question, such as: "Where is order ORD-1001?"
  2. The agent inspects the tool descriptions and parameter schemas.
  3. The model determines that it needs external data and emits a structured function call request containing the extracted parameters.
  4. Mastra validates the parameters against your schema and runs your local TypeScript function.
  5. Mastra returns the function output back to the model.
  6. The model reads the data and formulates a helpful, plain-English response.

The model never touches your database directly. It only produces the parameters, and your code executes the actual logic.

Quick Insight: The model decides whether to call a tool based on the text description you write for that tool. If your description is vague, the model will not know when to invoke it.


Defining Tools with createTool and Zod Schemas

Mastra uses Zod schemas to validate inputs and outputs at runtime. The createTool function from @mastra/core/tools requires an id, a descriptive string, an inputSchema, an outputSchema, and an execute function.

Create a new file in your project at src/mastra/tools/order-status-tool.ts:

ts
Copy

The execute function receives the validated input object directly as its first parameter. You can destructure fields like orderId right in the parameter list.

Common Mistake: Do not wrap your arguments inside a context parameter like execute: async ({ context }) => context.orderId. Mastra provides the validated properties directly on the root input object.


Attaching Tools to an Agent

Once a tool is created, you attach it to an agent using the tools configuration property. The key you use in the tools object becomes the tool identifier the model observes during inference.

Update your support agent definition in src/mastra/agents/support-agent.ts:

ts
Copy

Make sure your agent is exported in src/mastra/index.ts so the Mastra CLI and runtime detect it:

ts
Copy

Pro Tip: The agent instructions should explicitly mention that the agent has access to the tool. Clear guidance prevents the model from apologizing and claiming it lacks live information.


Controlling Execution Steps with maxSteps

When an agent calls a tool, it uses one step to call the function and another step to generate the final response from the tool output. If an agent needs to call multiple tools in sequence, it requires several steps.

Mastra agents run up to 5 steps per call by default, which is enough for a single tool call and a final answer. Use the maxSteps option on agent.generate() or agent.stream() to raise or lower that limit. A lower limit keeps costs predictable. A higher limit lets the agent chain several tool calls in one request.

Create a test script at src/test-tool.ts to run the agent from the command line:

ts
Copy

Run this file with tsx:

bash
Copy

If you set maxSteps to 1, the agent stops right after the tool call and never writes a final answer, because reading the tool result takes a second step.

Quick Challenge: Change the prompt in src/test-tool.ts to ask for ORD-9999 instead of ORD-1001. Observe how the agent handles the not_found status returned by your tool without crashing.


Testing Tools in Mastra Studio

Mastra includes a local development environment called Mastra Studio. It provides an interface to execute tools independently from the model, inspect schema validations, and trace agent tool calls.

Start the Mastra development server:

bash
Copy

Open your browser and navigate to http://localhost:4111.

In Mastra Studio:

  1. Navigate to the Tools section in the sidebar.
  2. Select get-order-status.
  3. Provide an input payload such as {"orderId": "ORD-1002"} and click Run.
  4. Review the raw JSON output to verify your TypeScript function works as expected before testing with the LLM.
  5. Navigate to the Agents section, open Support Agent, and type: "What is the status of ORD-1003?"

Studio displays the trace showing the user prompt, the tool invocation with arguments, and the final response.

Try This: Add a second property named carrier (a string) to both the outputSchema and the return value of orderStatusTool. Run the agent in Studio and see if the assistant mentions the carrier in its final answer.


Summary

FeaturePurposeKey Property
createToolDefines typed functions the model can execute@mastra/core/tools
inputSchemaEnforces and documents argument typesZod object schema
outputSchemaValidates data sent back to the modelZod object schema
toolsRegisters the tool on the Agent instanceObject map on Agent
maxStepsSets maximum multi-step execution loopsParameter in agent.generate

In the next lesson, Adding Memory to Your Mastra Agent, you will add stateful conversation threads and persistent working memory so your agent remembers customer details between messages.

Was this lesson helpful?