AI development is evolving rapidly. While many developers have experimented with making simple API calls to language models, the real leverage lies in building AI agents, autonomous systems that can reason, use tools, and iterate on tasks without constant handholding.
In this tutorial, you’ll learn how to build an AI summarizer agent using Mastra, a TypeScript-first framework designed specifically for agent development. By the end, you’ll have a working agent that can automatically fetch content from URLs and generate intelligent, structured summaries.
Prerequisites
- Basic TypeScript and Node.js knowledge
- Node.js v18 or higher installed
- A free Google AI API key (get one here)
Understanding Mastra: Agents, Tools, and Workflows
Before we…
AI development is evolving rapidly. While many developers have experimented with making simple API calls to language models, the real leverage lies in building AI agents, autonomous systems that can reason, use tools, and iterate on tasks without constant handholding.
In this tutorial, you’ll learn how to build an AI summarizer agent using Mastra, a TypeScript-first framework designed specifically for agent development. By the end, you’ll have a working agent that can automatically fetch content from URLs and generate intelligent, structured summaries.
Prerequisites
- Basic TypeScript and Node.js knowledge
- Node.js v18 or higher installed
- A free Google AI API key (get one here)
Understanding Mastra: Agents, Tools, and Workflows
Before we start building, let’s quickly talk about what Mastra actually is and how its main parts (agents, tools, and workflows) all fit together.
Mastra is an open-source AI engineering framework that helps developers build AI agents, basically smart systems that can think, plan, and act using tools and workflows you define. It’s built for developers, especially those familiar with JavaScript or TypeScript, who want to create AI-powered apps without tons of setup.
Here’s how it works under the hood:
Tools
Tools are like small helpers that your agent can use to do things such as call an API or run a function. Think of them as utilities with clear inputs and outputs.
For example:
- A tool that fetches random advice from an API.
- A tool that summarizes text or checks a website for data.
They’re built using createTool() and use Zod for input/output validation so your agent always knows what kind of data to expect.
Agents
Agents are the brains of your app. They use a language model(like Gemini 2.5, GPT-4, or Claude) to reason about tasks and decide which tools to call and when.
If tools are the hands, agents are the mind, they figure out what to do, then take action.
Workflows
Workflows are where you define a sequence of actions or logic flow that the agent follows. They connect multiple tools together to automate a process.
For example:
“When a user asks for advice, fetch a random quote from the Advice API and send it back in a friendly format.”
Agents, tools, and workflows make Mastra a powerful system for building smart AI applications.
Setting Up Your Project
Let’s get your development environment ready. Mastra makes this incredibly easy with its CLI.
Quick Start
Open your terminal and run:
# Create a new Mastra project
npm create mastra@latest ai-summarizer
The CLI will ask you a few setup questions.
Here’s what the full CLI flow looks like when you run the command:
┌ Mastra Create
│
◇ Where should we create the Mastra files? (default: src/)
│ src/
│
◇ Select a default provider:
│ Google
│
◇ Enter your Google API key?
│
│
◆ Make your IDE into a Mastra expert? (Installs Mastra's MCP server)
│ ○ Skip for now
│ ○ Cursor (project only)
│ ○ Cursor (global, all projects)
│ ○ Windsurf
│ ● VSCode
└
Once setup completes, Mastra will scaffold your project inside the src/ directory, including everything you need to start building your first AI agent.
Finally, navigate into your project folder:
# Navigate to your project
cd ai-summarizer
Your environment is now ready. Let’s start building the AI Summarizer Agent!
Project Structure
When you create a new Mastra project, it comes with a sample weather agent to help you explore the basics.
For this tutorial, we won’t be using that example, so go ahead and delete the weather-related files inside the src/mastra/agents and src/mastra/tools folders.
After cleaning up, we’ll add two new files:
summarizer.tsinsrc/mastra/agents/- our AI Summarizer Agentweb-scraper.tsinsrc/mastra/tools/- a tool that fetches webpage content
Here’s how your project structure should look once we’re done:
ai-summarizer/
├── src/
│ ├── mastra/
│ ├── agents/
│ │ └── summarizer.ts
│ ├── tools/
│ │ └── web-scraper.ts
│ └── index.ts
├── .env
├── package.json
└── tsconfig.json
Environment Configuration
Create a .env file in your project root:
GOOGLE_GENERATIVE_AI_API_KEY=your_api_key_here
Get your free API key from Google AI Studio. The free tier is generous and perfect for development and small projects.
Click “Create API key.” A modal will pop up, select “Create project,” give your key a name, and click “Create key.” You’ll receive your Gemini API key, which we’ll add to the .env file.
Install Additional Dependencies
We’ll need a couple more packages for web scraping:
npm install cheerio axios
Now you’re ready to start building!
Building Your AI Agent
Let’s build our agent step by step, starting with the tools it needs.
Step 1: Create the Web Scraper Tool
Tools are functions your agent can call to run logic, fetch data, or communicate with external APIs. Let’s create a tool that fetches and extracts content from web pages.
In src/mastra/tools/web-scraper.ts paste this code:
import { createTool } from '@mastra/core';
import { z } from 'zod';
import axios from 'axios';
import * as cheerio from 'cheerio';
export const fetchWebContent = createTool({
id: 'fetch-web-content',
description: 'Fetches and extracts the main content from a web page URL. Use this when you need to get the text content of an article or web page.',
inputSchema: z.object({
url: z.string().url().describe('The URL of the web page to fetch'),
}),
outputSchema: z.object({
content: z.string().describe('The extracted text content'),
title: z.string().describe('The page title'),
success: z.boolean().describe('Whether the fetch was successful'),
error: z.string().optional().describe('Error message if fetch failed'),
}),
execute: async ({ context }) => {
try {
const { url } = context;
// Fetch the HTML
const response = await axios.get(url, {
timeout: 10000,
headers: {
'User-Agent': 'Mozilla/5.0 (compatible; SummarizerBot/1.0)',
},
});
// Parse HTML with Cheerio
const $ = cheerio.load(response.data);
// Remove unwanted elements
$('script, style, nav, footer, iframe, aside').remove();
// Extract title
const title = $('title').text().trim() ||
$('h1').first().text().trim() ||
'Untitled';
// Extract main content
// Try to find main content area first
let content = $('article').text() ||
$('main').text() ||
$('.content').text() ||
$('body').text();
// Clean up the content
content = content
.replace(/\s+/g, ' ') // Replace multiple spaces with single space
.replace(/\n+/g, '\n') // Replace multiple newlines with single newline
.trim();
// Limit content length to avoid token limits
const maxLength = 10000;
if (content.length > maxLength) {
content = content.substring(0, maxLength) + '...';
}
return {
content,
title,
success: true,
};
} catch (error) {
return {
content: '',
title: '',
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
};
}
},
});
Key Points:
- Input Schema: Zod is used here to define and validate inputs. The agent is able to knows what parameters the tool needs.
- Output Schema: It defines what the tool returns, helping the agent understand the results.
- Description: This tells the agent when and how to use the tool.
- Error Handling: Always return structured errors so the agent can decide what to do next.
- Content Cleaning: Removes scripts, styles, and navigation elements to get clean text.
Step 2: Initialize Mastra Core
Now, let’s set up the Mastra core configuration. This is where we register our agents so Mastra knows how to use them.
In src/mastra/index.ts, paste this code:
import { Mastra } from "@mastra/core";
import { summarizerAgent } from "./agents/summarizer";
export const mastra = new Mastra({
agents: { summarizerAgent },
});
This initializes Mastra and makes your summarizerAgent accessible throughout the app.
Step 3: Create the Summarizer Agent
Now for the exciting part, bringing everything together into an agent!
In src/mastra/agents/summarizer.ts, paste this code:
import { Agent } from '@mastra/core';
import { fetchWebContent } from '../tools/web-scraper';
export const summarizerAgent = new Agent({
name: 'summarizer',
instructions: `You are an expert content summarizer. Your job is to create clear, concise, and informative summaries.
When given a URL:
1. Use the fetch-web-content tool to retrieve the page content
2. If the fetch fails, inform the user politely
When summarizing content (from URL or direct text):
1. Create a structured summary with:
- **Main Topic**: One sentence describing what the content is about
- **Key Points**: 3-5 bullet points highlighting the most important information
- **Key Takeaway**: One sentence capturing the essential message
Guidelines:
- Be concise but informative
- Focus on facts and main ideas, not minor details
- Use clear, professional language
- If the content is too short to summarize meaningfully, say so
- If the content is unclear or low-quality, mention that in your response`,
model: 'google/gemini-2.5-pro',
tools: { fetchWebContent },
});
The Instructions:
The instructions field is where you guide your agent’s behavior. This is like hiring an employee and giving them their job description. Good instructions:
- Define the role: “You are an expert content summarizer”
- Specify the workflow: When to use tools and in what order
- Set expectations: What the output should look like
- Handle edge cases: What to do when things go wrong
Tool Registration:
The tools object contains all available tools the agent can use.
Testing Your Agent in the Playground
Mastra has a built-in playground where you can test your agent, tools, and workflows.
Run the development server:
npm run dev
You will see http://localhost:4111/ in your CLI. Open that URL in your browser and you’ll see the Mastra playground.
Testing the Agent
You can test your agent by:
- Testing with a URL:
- Paste a URL like
https://blog.google/technology/ai/google-gemini-ai/ - Click “Run”
- Watch the agent fetch the content and generate a summary
- Testing with direct text:
- Paste or type a long text
- Click “Run”
- See the agent summarize it immediately
What Just Happened?
- You passed input to the agent
- The agent read its instructions
- For the URL example:
- Agent reasoned: “This is a URL, I need to fetch it”
- Agent called the
fetch-web-contenttool - Agent received the content
- Agent generated a structured summary
- For the text example:
- Agent reasoned: “This is direct text, I can summarize immediately”
- Agent generated the summary
- Agent returned the final result
This is the power of agents - they autonomously decide what steps to take!
Conclusion
You’ve built a production-ready AI agent that can autonomously fetch content and generate intelligent summaries. More importantly, you now understand the fundamental concepts of AI agent development:
What’s Next?
In Part 2 of this series, we’ll take your agent to the next level by:
- Building a beautiful frontend interface
- Connecting your agent to a web application
- Adding real-time streaming responses
Stay tuned!
Complete Code Repository
The full working code for this tutorial is available on GitHub:
Repository: https://github.com/Timmydee/ai-summarizer
Happy coding!