Skip to content
AI Engineering
AI Engineering12 min read0 views

Build an AI Agent with Mastra (TypeScript Agent Framework, 2026)

Mastra v1.0 hit GA in Jan 2026 with 300K weekly downloads. Build a multi-step agent with tools, RAG, evals, and Inngest workflows in pure TypeScript.

TL;DR — Mastra (from the Gatsby founders, $13M YC W25) shipped v1.0 in January 2026 with 300K weekly npm downloads. It gives you Agents, Workflows, RAG, and Evals as separate primitives over 3,300+ models from 94 providers — all type-safe.

What you'll build

A "support concierge" agent that classifies a customer message, routes to the right specialist agent (billing, tech, scheduling), calls a tool against your CRM, and emits an eval score for every run — all from one TypeScript file.

Prerequisites

  1. Node 20+ or Bun 1.3, @mastra/core@^1, @mastra/memory, @ai-sdk/openai@^1.
  2. mastra dev CLI for the local Studio.

Architecture

flowchart TD
  IN[User message] --> CLF[Classifier agent]
  CLF -->|billing| B[Billing agent + Stripe tool]
  CLF -->|tech|    T[Tech agent + KB RAG]
  CLF -->|book|    S[Scheduling agent + cal tool]
  B & T & S --> EV[Eval scorer] --> OUT[Reply]

Step 1 — Define an agent

```ts import { Mastra } from "@mastra/core"; import { Agent } from "@mastra/core/agent"; import { openai } from "@ai-sdk/openai";

const billing = new Agent({ name: "billing", instructions: "You handle invoice + refund questions. Always call lookupInvoice first.", model: openai("gpt-4o-mini"), tools: { lookupInvoice }, }); ```

Step 2 — Type-safe tools

```ts import { createTool } from "@mastra/core/tools"; import { z } from "zod";

Hear it before you finish reading

Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.

Try Live Demo →

export const lookupInvoice = createTool({ id: "lookupInvoice", description: "Find an invoice by id", inputSchema: z.object({ id: z.string() }), outputSchema: z.object({ amount: z.number(), status: z.string() }), execute: async ({ context }) => fetch(https://api.stripe.com/v1/invoices/${context.id}, { headers: { Authorization: Bearer ${process.env.STRIPE_KEY} }, }).then((r) => r.json()), }); ```

Step 3 — Workflow with branching

```ts import { createWorkflow, createStep } from "@mastra/core/workflows";

const classify = createStep({ id: "classify", inputSchema: z.object({ message: z.string() }), outputSchema: z.object({ route: z.enum(["billing","tech","book"]) }), execute: async ({ inputData, mastra }) => { const r = await mastra.getAgent("router").generate(inputData.message, { output: z.object({ route: z.enum(["billing","tech","book"]) }) }); return r.object; }, });

export const support = createWorkflow({ id: "support", inputSchema: z.object({ message: z.string() }), outputSchema: z.object({ reply: z.string() }), }) .then(classify) .branch([ [async ({ inputData }) => inputData.route === "billing", billingStep], [async ({ inputData }) => inputData.route === "tech", techStep], [async ({ inputData }) => inputData.route === "book", bookStep], ]) .commit(); ```

Step 4 — Wire RAG + memory

```ts import { Memory } from "@mastra/memory"; import { LibSQLStore } from "@mastra/libsql";

const memory = new Memory({ storage: new LibSQLStore({ url: "file:./mastra.db" }), options: { lastMessages: 10, semanticRecall: { topK: 5, messageRange: 2 } }, }); ```

Step 5 — Add evals

```ts import { createScorer } from "@mastra/core/scores";

Still reading? Stop comparing — try CallSphere live.

CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.

const helpfulness = createScorer({ name: "helpfulness", judge: { model: openai("gpt-4o-mini"), instructions: "Score 0-1 on helpfulness." }, }).generateScore(({ run }) => parseFloat(run.text)); ```

Step 6 — Run + observe

```ts const mastra = new Mastra({ agents: { billing, tech, scheduling, router }, workflows: { support }, scorers: { helpfulness }, }); const result = await mastra.getWorkflow("support") .createRun().start({ inputData: { message: "Where is invoice in_123?" } }); ```

Pitfalls

  • Apache 2 core, commercial enterprise — RBAC/SSO/ACL need a paid license at scale.
  • Mastra Cloud pricing TBA — public pricing was promised Q1 2026 but wasn't published as of May 2026; budget conservatively.
  • mastra dev ports — defaults to 4111; collisions with Vite + Next dev servers are common.

How CallSphere does this in production

CallSphere runs 37 production agents with 90+ tools, 115+ DB tables, and 6 verticals — Healthcare (FastAPI), OneRoof (Next.js 16 + React 19), Salon (NestJS 10 + Prisma), Sales (Node.js 20 + React 18 + Vite). Mastra-style classify-then-specialize routing is shipped on the Sales product with eval scores written back to Postgres for every run. Pricing $149/$499/$1,499, 14-day trial, 22% affiliate.

FAQ

Mastra vs LangGraph? Mastra is opinionated TypeScript-first; LangGraph is graph-first and has a Python sibling. Mastra has cleaner DX for serverless deploys.

Does it support tool streaming? Yes — agent.streamVNext returns deltas including tool-call and tool-result events.

Can I run on Cloudflare Workers? Yes via the @mastra/deployer-cloudflare adapter (1.0+).

RAG store options? LibSQL (local), Postgres + pgvector, Pinecone, Chroma — all behind MastraVector.

Sources

Share

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.