
How-Tos
How to create a first Mastra agent
Run npm create mastra@latest, register an Agent on the Mastra instance, and test it in Studio.
Searcher → Analyst → Writer → Editor · subagentic-20261011-2000
Mastra is a TypeScript framework for building AI agents and applications. The docs start a new project with one create command, then treat an agent as an Agent you register on a Mastra instance. Studio is the interactive UI for that project. You use it to try messages and inspect what the agent did. It is not a separate product you install afterward.
Create the project
The quickstart command creates a general-purpose agent harness with a local workspace, shell tools, memory, task tracking, web access, and recurring schedules. It also installs Mastra skills for your installed coding agent, so you can start prompting and editing the project:
npm create mastra@latest
The same quickstart lists the other package managers:
pnpm create mastra@latest
yarn create mastra
bunx create-mastra
After that command, you can open Studio immediately. Studio is an interactive UI for your Mastra project.
The docs also include a pre-built prompt that names the project and the model provider before you run the command:
npm create mastra@latest <project-name> -- --llm <provider>
In that prompt, the default project name is my-mastra-app, and the provider is required. The listed options are openai, anthropic, google, and xai. The command creates a default Mastra project and initializes Git when appropriate, after installing Mastra skills for detected coding assistants.
Refer to official documentation for exact syntax.
These pages also include a condensed from-scratch block. That install line is not the path for an existing project. For an existing repo, follow the framework integration guides linked from the docs, including Next.js, React + Vite, Astro, Express, SvelteKit, and Hono.
The condensed from-scratch block starts by creating a package.json with { "type": "module" } and installing the packages the docs name:
npm install @mastra/core@latest zod@latest typescript@latest @types/node@latest mastra@latest
The condensed block also includes a tsconfig.json. Copy that file from the docs rather than rebuilding it from memory. Do not install an AI SDK package unless Mastra's documentation says otherwise.
Define an Agent
Agents use LLMs and tools to solve open-ended tasks. They reason about goals, decide which tools to use, and keep going until the model emits a final answer or an optional stop condition is met. With memory configured, they retain conversation history. They can return structured responses you render in a UI or handle in code.
Use an agent when the steps are not known in advance. You supply the goal and the constraints. The agent chooses which tools to call, how many times to loop, and when to stop. For a predetermined process with explicit control flow, the docs say to use a workflow instead.
Create an agent by instantiating the Agent class. The constructor takes { id, name, instructions, model }. The agents overview shows this file at src/mastra/agents/test-agent.ts:
import { Agent } from '@mastra/core/agent'
export const testAgent = new Agent({
id: 'test-agent',
name: 'Test Agent',
instructions: 'You are a helpful assistant.',
model: 'openai/gpt-5.6-sol',
})
instructions are system-level prompts. They set behavior, personality, and capabilities, and they establish the agent's core identity and expertise.
model is a string in provider/model form. The docs' example is openai/gpt-5.6-sol. Use openai/<model>, not openai:<model>, and do not import or pass a provider object. No provider import is required for this format.
That string tells Mastra which provider environment variable to read:
- OpenAI uses
OPENAI_API_KEY. Anyopenai/<model>requires it. - Anthropic uses
ANTHROPIC_API_KEY. - Google uses
GOOGLE_API_KEY.
Model IDs these pages list are openai/gpt-5.6-sol, openai/gpt-5-mini, anthropic/claude-sonnet-4-6, anthropic/claude-opus-4-7, anthropic/claude-haiku-4-5, and google/gemini-2.5-flash. The model router is described as covering thousands of models beyond that short list.
Register the agent
Registration is what lets the rest of the app call the agent. The overview puts the entry point at src/mastra/index.ts:
import { Mastra } from '@mastra/core'
import { testAgent } from './agents/test-agent'
export const mastra = new Mastra({
agents: { testAgent },
})
Once registered, the agent can be called from workflows, tools, or other agents, and it can use shared resources such as memory, logging, and observability.
Get it back with mastra.getAgentById() so those shared services stay attached. A direct import can still run on its own local configuration, but it will not have instance-level storage, logging, or the agent registry.
The overview import has no file extension. The condensed setup notes say to add extensions when importing local files. Their weather-agent registration uses a TypeScript extension on that local import. If you run TypeScript directly on Node.js 22.18.0 or later, follow that note.
Test it in Studio
Studio is the test UI for the project. Use it to send different messages, inspect tool calls and responses, and debug behavior. After you create the project, the quickstart says you can open Studio immediately.
Agent Builder is a browser alternative for a fully stored agent, instead of a TypeScript class. This path stays with Agent.
Call generate or stream
.generate() waits until tool calls and steps finish, then returns the full response. That result includes text, toolCalls, toolResults, steps, and token usage.
const agent = mastra.getAgentById('test-agent')
const response = await agent.generate('Help me organize my day')
console.log(response.text)
.stream() yields tokens as they arrive through textStream. Promises for toolCalls, toolResults, steps, and usage resolve when the stream ends.
const agent = mastra.getAgentById('test-agent')
const stream = await agent.stream('Help me organize my day')
for await (const chunk of stream.textStream) {
process.stdout.write(chunk)
}
The docs say you can also call agents from workflow steps, tools, the Mastra Client, route handlers, server adapters, or the command line.
A direct script in the condensed instructions imports the Mastra instance and calls generate by id. It targets the weather agent id, so use the id you actually registered:
// run.mjs
import { mastra } from './src/mastra/index.ts'
const agent = mastra.getAgentById('weather-agent')
const response = await agent.generate('Weather in SF')
console.log(response.text)
Add a tool only when you need one
The first agent does not need a tool. If you add one, a plain object will not run. The docs say plain object tool definitions silently fail to execute. Define the tool with createTool(), and include id, description, inputSchema (zod), and execute.
execute has one signature: execute(inputData, context). The first argument is the input checked against inputSchema. The second is execution context, always provided by the runtime, with requestContext, tracingContext, abortSignal, and other metadata. Omit the second parameter if you do not need it. Import the tool and pass it to the agent constructor as a tools object. Copy the weather tool file from the docs rather than reconstructing the import yourself.
The weather example returns a fixed object: the location you passed, a temperature in Celsius of 21, and sunny conditions. That is a shape demo, not a live forecast.
Next step
Run npm create mastra@latest, register the test agent on the Mastra instance, and open Studio as the quickstart states. Send a short message and confirm you get text back. If nothing returns, check that model uses provider/model and that the provider environment variable is set. Then use the expand-your-agent table on the agents overview for tools, memory, or structured output, and watch the Mastra agent quickstart video linked from that page.