
How-Tos
How to create a first Mastra agent
Mastra’s docs show how to scaffold a project with npm create mastra and register a first Agent with instructions and a model.
Searcher → Analyst → Writer → Editor · subagentic-20261029-2000
Mastra is a TypeScript framework for building AI agents and applications. The getting-started page describes creating a first agent with a single command, and it also shows the code for an Agent you construct and register yourself. This guide stays on that setup path: the documented create command, the constructor, and registration on a Mastra instance.
Scaffold with the create command
The quickstart is one command. With npm:
npm create mastra@latest
The same page prints the scaffold for other package managers:
pnpm create mastra@latest
yarn create mastra
bunx create-mastra
Copy those forms as published. The Yarn line is yarn create mastra. The Bun line is bunx create-mastra.
The docs say that command creates a general-purpose agent harness with a local workspace, shell tools, memory, task tracking, web access, and recurring schedules. They also say it installs Mastra skills for your installed coding agent, so you can start prompting and editing the project. After creation, the page says you can open Studio immediately. Studio is the interactive UI for your Mastra project.
A prompt block on the same page shows a named variant, with a provider chosen up front:
npm create mastra@latest <project-name> -- --llm <provider>
Provider values named there are openai, anthropic, google, and xai. The page says that command creates a default Mastra project and initializes Git when appropriate, after installing Mastra skills for detected coding assistants. It then says to enter the project directory and start the dev server with:
npx bgproc start -n <project-name> -w -- npm run dev
In that flow, the page says to open Mastra Studio at http://localhost:4111. It calls Studio the interface for building, testing, and managing agents, workflows, and tools.
The page does not list the files that command writes. The constructor and registration below are the from-scratch example. Do not assume the scaffold drops those same files.
Define an Agent
The from-scratch section says to create a file and use import { Agent } from "@mastra/core/agent". The constructor takes { id, name, instructions, model }.
model is a string in Mastra’s model-router format, provider/model. The page says no provider import is needed for that format, and that you should not install an AI SDK package unless Mastra’s documentation says otherwise. For OpenAI it says to use openai/<model>, not openai:<model>, and not to pass a provider object.
With that string, the docs say Mastra looks for the provider’s environment variable. Named on the page: OPENAI_API_KEY for OpenAI, ANTHROPIC_API_KEY for Anthropic, and GOOGLE_API_KEY for Google. Any openai/<model> value requires OPENAI_API_KEY. The page points to a fuller provider list and a models list instead of inlining either one, and it says the model router provides access to thousands of models.
The short list of model IDs printed on the page is openai/gpt-6.1-sol, openai/gpt-6-luna, anthropic/claude-sonnet-5-5, anthropic/claude-opus-5-5, anthropic/claude-haiku-5-5, and google/gemini-3.8-flash. The worked example uses openai/gpt-6.1-sol. This guide copies those strings as the page publishes them. It does not independently confirm that a provider currently serves a given ID. If a call fails on the model string, use the models list the docs point to rather than substituting an ID from memory.
The example agent uses a tool. The page is strict about tools: plain object definitions silently fail to execute. A tool must be created with createTool(), using import { createTool } from "@mastra/core/tools", and it needs id, description, inputSchema (zod), and execute(). The documented signature is execute(inputData, context). The first argument is the input validated against inputSchema. The second is the execution context, which the runtime always provides, including requestContext, tracingContext, abortSignal, and other execution metadata. You may omit the second parameter when you do not need it.
The tool file from the docs:
// src/mastra/tools/weather-tool.ts
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const weatherTool = createTool({
id: 'get-weather',
description: 'Get current weather for a location',
inputSchema: z.object({
location: z.string().describe('City name'),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
execute: async ({ location }) => {
return {
location,
temperatureCelsius: 21,
conditions: 'sunny',
}
},
})
That execute body returns fixed values. It is the example as published, not a live weather request.
The page says to add a tool by importing it and passing it to the agent constructor as a tools object. Local imports in the example keep their file extensions. The page says to add file extensions when importing local files.
// src/mastra/agents/weather-agent.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool.ts'
export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: `
You are a helpful weather assistant that provides accurate weather information.
Your primary function is to help users get weather details for specific locations. When responding:
- Include relevant details like humidity, wind conditions, and precipitation
- Keep responses concise but informative
Use the weatherTool to fetch current weather data.
`,
// Use a string in provider/model format, not provider:model or a provider object.
model: 'openai/gpt-6.1-sol',
tools: { weatherTool },
})
Register it on a Mastra instance
Create the entry point at src/mastra/index.ts and register the agent under agents:
import { Mastra } from '@mastra/core'
import { weatherAgent } from './agents/weather-agent.ts'
export const mastra = new Mastra({
agents: { weatherAgent },
})
The page says you can then run the agent directly. Import the Mastra instance, retrieve the agent by its id, and generate a reply. It notes that Node.js 22.18.0 and later can run TypeScript files directly. The example script is:
// 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)
The id passed to that retrieval call is weather-agent, which is the agent’s id, not the export name weatherAgent.
If you are building the files by hand
Skip this section if you used the create command. The from-scratch notes say to create a package.json with { "type": "module" } and install:
npm install @mastra/core@latest zod@latest typescript@latest @types/node@latest mastra@latest
The tsconfig.json printed on the page is:
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"types": ["node"],
"noEmit": true,
"allowImportingTsExtensions": true,
"outDir": "dist"
},
"include": ["src/**/*"]
}
Those are the compiler options the page shows. It does not document additional keys. The same page also says you can add Mastra to an existing project, and it names Next.js, React + Vite, Astro, Express, SvelteKit, and Hono. Those setups live in separate integration guides, not in the constructor example above.
Next step
Run npm create mastra@latest if you want the documented harness, then open Studio and try the project it created. If you are defining the agent in code, copy the tool, the Agent constructor, and the src/mastra/index.ts registration from the getting-started page, set the environment variable that matches your provider/model string, and run the script that page shows. If a model ID or signature here and the docs page ever diverge, follow the page.