Guía10 min

Mastra: guía práctica de agentes TypeScript con Studio

Resumen

Guía práctica de Mastra en 2026: instalar @mastra/core 1.64.0 y el CLI mastra 1.27.3 con Node 22.13+, crear un Agent con model en formato provider/model, tools con createTool y execute(inputData, context), registrarlas en new Mastra(), y probarlas en Studio en localhost:4111. Distinto de Pydantic AI, LangGraph y de un coding agent de terminal.

OpenAIGitHub
Diagrama de un agente TypeScript Mastra con tools, workflows y Studio local

Qué resuelve

Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.

Mastra es un framework TypeScript para agentes y apps de IA: defines un Agent, le das tools con contrato Zod (u otro Standard JSON Schema), lo registras en new Mastra() y lo corres con .generate() / .stream() o lo pruebas en Studio. No es un coding agent de terminal como Kimi Code CLI. No es el SDK Python de Pydantic AI. No es un canvas no-code como Dify. Es código de producto en Node.

Esta guía cubre el recorte del hub Construir agentes que sí pegas en un repo hoy: versiones, scaffolding, primer agente, tools, cuándo usar un workflow en vez del loop, y Studio. El curso Instalar un agente cubre el harness de producto; aquí el contrato es el de @mastra/core.

Versiones y arranque

npm publica @mastra/core 1.64.0 y el CLI mastra 1.27.3 (verificado 2026-09-07). Ambos declaran engines.node: >=22.13.0. Las docs de Agents añaden que Node 22.18.0+ puede correr TypeScript directo si importas con extensión .ts. No uses Node 20 “porque el resto del monorepo ya lo tiene”: el install avisa y el runtime rompe.

Scaffold oficial (elige uno; en este repo el estándar es pnpm):

pnpm create mastra@latest

Equivalentes documentados: npm create mastra@latest, yarn create mastra, bunx create-mastra. El scaffolding deja un harness con workspace local, tools de shell, memoria, schedules y skills para el coding agent que tengas instalado. Si ya tienes un package.json con "type": "module", las docs de Get started listan el mínimo a mano: @mastra/core, zod, typescript, @types/node, mastra.

El modelo se declara como string provider/model, no como objeto del AI SDK. Ejemplos canónicos de las docs al 2026-09-07: openai/gpt-5.6-sol, openai/gpt-5-mini, anthropic/claude-sonnet-4-6, google/gemini-2.5-flash. OpenAI es openai/<modelo>, nunca openai:<modelo>. El router busca la env del proveedor: OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY. Lista completa: mastra.ai/models. No instales @ai-sdk/* “por si acaso”: las docs lo dicen explícito.

Primer agente: id, instructions, model

import { Agent } from "@mastra/core/agent";

export const weatherAgent = new Agent({
  id: "weather-agent",
  name: "Weather Agent",
  instructions: `Eres un asistente de clima. Usa weatherTool para datos actuales.`,
  model: "openai/gpt-5.6-sol",
});

instructions es el system prompt: identidad, límites y cuándo llamar tools. Trátalo como el cerebro que cubre system prompts para agentes, no como un comentario decorativo. id es la llave de registro; name es la etiqueta humana de Studio.

Regístralo en src/mastra/index.ts. Un agente importado “a pelo” corre, pero no hereda storage, logging ni el registry de la instancia:

import { Mastra } from "@mastra/core";
import { weatherAgent } from "./agents/weather-agent.ts";

export const mastra = new Mastra({
  agents: { weatherAgent },
});

Uso:

const agent = mastra.getAgentById("weather-agent");
const response = await agent.generate("Clima en SF");
console.log(response.text);

.generate() espera el ciclo completo y devuelve text, toolCalls, toolResults, steps y usage. .stream() expone textStream y las mismas promesas al cerrar el stream. Llama agentes desde steps de workflow, tools, el Mastra Client, route handlers o la CLI. Recupera siempre con getAgentById() si quieres los servicios compartidos.

Tools: createTool o no existen

Un objeto suelto { name, execute } falla en silencio. Las docs de Tools lo marcan: la tool tiene que nacer con createTool() y id, description, inputSchema, execute(). Firma única: execute(inputData, context). El runtime siempre pasa context (requestContext, tracingContext, abortSignal). Si no lo usas, omítelo. Cualquier otra forma está obsoleta.

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 }, { abortSignal }) => {
    const response = await fetch(`https://wttr.in/${location}?format=j1`, {
      signal: abortSignal,
    });
    const data = await response.json();
    return {
      location,
      temperatureCelsius: Number(data.current_condition[0].temp_C),
      conditions: data.current_condition[0].weatherDesc[0].value,
    };
  },
});

Pásala en tools: { weatherTool }. Menciona la tool en instructions para que el modelo sepa cuándo usarla. Schema: Zod, Valibot o ArkType vía Standard JSON Schema. Prueba aislada con el server vivo:

npx mastra dev
npx mastra api tool execute weather-tool '{"location":"San Francisco"}'

--schema imprime el input antes de inventar un JSON. npx skills add mastra-ai/skills --skill mastra instala la skill de descubrimiento de la API CLI. MCP remoto también entra como tools; no copies un wrapper a mano si ya hay servidor.

Flujo Agent → createTool → generate o stream

Agente vs workflow

Usa el agente cuando la tarea es abierta: no sabes los pasos, el modelo elige tools y para cuando emite respuesta final (o un stop condition). Usa un workflow cuando el proceso ya está descompuesto: createStep + createWorkflow, schemas de entrada/salida, orden explícito, suspend/resume.

Un workflow no es orquestación multi-agente ni el checkpoint casero de ejecución durable. El motor built-in cubre la secuencia; runners managed (Inngest aparece en las docs de workflows) son infra aparte. Si tu “agente” es un DAG de 8 pasos con ramas humanas, no lo disfraces de instructions.

PiezaCuándoQué no es
Agent + toolsMeta abierta, loop de toolsCoding CLI, canvas no-code
createWorkflowPasos conocidos, control de datosUn prompt largo con “primero haz X”
Studio :4111Probar, traces, scorersProducción sin auth
Pydantic AIMismo problema en PythonEste paquete

La comparativa LangGraph vs CrewAI vs SDK sigue siendo la brújula si el dolor es un grafo persistente. Mastra cubre agentes + workflows en TypeScript con Studio; no sustituye LangGraph si ya operas checkpoints de grafo en Python.

Studio en :4111

Con el scaffold, pnpm run dev (o mastra dev) abre Studio en localhost:4111 y Swagger en /swagger-ui. Ahí chateas con el agente, cambias modelo, ves tool calls, traces, processors/guardrails, MCP, tools sueltas y workspaces. Scorers y datasets viven en las pestañas de evaluación. Deploy de Studio a producción es otro doc (studio/deployment + auth); no expongas :4111 a internet sin eso.

Agent Builder (agent-builder.mastra.ai) es la vía browser para un agente almacenado, no un reemplazo del repo. Si el equipo no-técnico itera prompts, usa Editor de Studio; el código sigue siendo la fuente.

Studio local, tools aisladas y traces del agente

Checklist operativo

  1. Node ≥22.13.0 (ideal 22.18+ para .ts directo). Pinea @mastra/[email protected] y [email protected] o el último que hayas verificado en npm.
  2. pnpm create mastra@latest o el mínimo ESM a mano. "type": "module" no es opcional.
  3. model: "openai/gpt-5.6-sol" (u otro id de mastra.ai/models). Cero openai:… y cero objeto provider.
  4. Tools solo con createTool. Firma execute(inputData, context). Objetos planos = tool muerta.
  5. Registra en new Mastra({ agents }) y llama getAgentById. Import directo pierde storage/logging.
  6. Tarea abierta → agente. Pasos conocidos → workflow. No mezcles.
  7. Prueba en Studio :4111 y mastra api tool execute antes de pegar el agente en un webhook.
  8. Secretos en env del proveedor, nunca en instructions.

FAQ

¿Sirve para un bot de Telegram? Sí como cerebro: el webhook construye el mensaje, llama agent.generate() / .stream() y responde. El ack de 3 s sigue siendo tuyo.

¿Puedo usar Ollama o un gateway? El router lista proveedores y sus env en mastra.ai/models/environment-variables. Confirma el id ahí; no asumas que ollama/… existe porque otro SDK lo tiene.

¿En qué se diferencia de Vercel AI SDK? Mastra es el runtime de agentes (registry, tools, workflows, Studio). El model router no te pide instalar el AI SDK. Si ya tienes generateText de AI SDK en una ruta, no lo envuelvas en un Agent de adorno.

¿Es un coding agent? No. El create-mastra puede instalar skills para Cursor/Claude Code; eso no convierte a Mastra en Aider. Para editar este repo sigue el CLI que ya usas.

Cuándo sí / cuándo no

Usa Mastra cuando el agente es TypeScript de producto: Next, Hono, Express o un server propio, 5–12 tools con schema, Studio para el equipo y, si hace falta, un workflow al lado. No lo uses para reemplazar Cursor/Claude Code, ni para un clasificador de un paso (un generate tipado basta), ni como atajo para saltarte evals: scorers y datasets existen, el ground truth lo pones tú.