Build Your First AI Agent in 10 Minutes (or Less)
Until recently, I assumed building AI agents was too complex. The complexity may vary from agent to agent, but they’re fairly simple to start with. The purpose of this post is to share my excitement on getting my “Hello World”-like experience running my own AI weather agent. I’ll show you how to create and run an agent that can tell the current time, weather, and suggest activities based on that.
Prerequisite
You’re going to build your first agent using TypeScript and Node.js, so make sure you have those tools installed. Besides that, you need an API key to the LLM that will run your agent. I recommend Gemini because it’s easy to create an API key if you have a Google account, and there’s a free plan so you don’t have to worry about cost. To get an API key, go to https://aistudio.google.com/apikey and click the “Create API Key” button at the top right. Follow the instructions in the dialog window that appears, then copy/save your API Key when it’s generated.
If you prefer to use Open AI or Claude models, refer to their documentation for how to create an API Key.
Scaffolding The Project
You’re going to build the project using the Mastra SDK. Mastra provides an SDK and framework for building AI apps in JavaScript/TypeScript. Run the command npx create-mastra@latest --project-name weather-ai --example --components tools,agents,workflows --llm google
to scaffold a new project with the name weather-ai
. The generated project will include a sample weather agent and tool.
Once the project is created, open the .env
file in it and add your Gemini API key as value for GOOGLE_GENERATIVE_AI_API_KEY
.
Test that it works by running the command npm run dev
and open the Mastra playground available at http://localhost:4111.
Understanding the Project Structure
In just a few minutes you have an agent that can tell the current weather condition and recommend activities or outfit based on that data. How does this work behind the scenes?
Mastra framework convention splits the logic into three folders — agents, tools, and workflows. The weather-agent.ts
file defines the weather agents you saw in the demo:
export const weatherAgent = new Agent({
name: "Weather Agent",
instructions: `
You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
Your primary function is to help users get weather details for specific locations. When responding:
- Always ask for a location if none is provided
- If the location name isn't in English, please translate it
- If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
- Include relevant details like humidity, wind conditions, and precipitation
- Keep responses concise but informative
- If the user asks for activities and provides the weather forecast, suggest activities based on the weather forecast.
- If the user asks for activities, respond in the format they request.
Use the weatherTool to fetch current weather data.
`,
model: google("gemini-2.5-flash"),
tools: { weatherTool },
memory: new Memory({
storage: new LibSQLStore({
url: "file:../mastra.db", // path is relative to the .mastra/output directory
}),
}),
});
It exports an Agent
object which contains information about the model, tools, memory, and instruction. The instruction is the system prompt that tells the agent how to behave and it’s interesting to see the amount of details that go into such instructions. Before now, I didn’t understand what to do with system instructions when using Playgrounds like Google’s AI Studio or OpenAI GPT playground, and now that I do, I’m exploring different instructions to learn more how to control agent output and behaviour. If you’ve got more time, play around with the system instruction in this project, or in Google’s AI Studio.
Tools are functions that your model (or agent, not sure about the right terminology here 🙃) uses to retrieve information or perform actions (e.g. delete a file). The weatherTool
is used to retrieve weather information. Here’s a truncated version of what it should look like:
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({
temperature: z.number(),
feelsLike: z.number(),
humidity: z.number(),
windSpeed: z.number(),
windGust: z.number(),
conditions: z.string(),
location: z.string(),
}),
execute: async ({ context }) => {
return await getWeather(context.location);
},
});
const getWeather = async (location: string) => {
const geocodingUrl = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(location)}&count=1`;
const geocodingResponse = await fetch(geocodingUrl);
const geocodingData = (await geocodingResponse.json()) as GeocodingResponse;
if (!geocodingData.results?.[0]) {
throw new Error(`Location '${location}' not found`);
}
const { latitude, longitude, name } = geocodingData.results[0];
const weatherUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,wind_gusts_10m,weather_code`;
const response = await fetch(weatherUrl);
const data = (await response.json()) as WeatherResponse;
return {
temperature: data.current.temperature_2m,
feelsLike: data.current.apparent_temperature,
humidity: data.current.relative_humidity_2m,
windSpeed: data.current.wind_speed_10m,
windGust: data.current.wind_gusts_10m,
conditions: getWeatherCondition(data.current.weather_code),
location: name,
};
};
It uses the createTool()
function from Mastra to define a tool with a name, input and and output schema, and a function to execute when the tool is called. It uses Zod to define the schema and I believe it supports JSON schema as well. When the weatherTool
is called by the agent, the getWeather()
function is called with the given arguments and return the JSON.
Give them tools, give them superpowers
Tools are the hands that allow an LLM’s brain to interact with the world. The weather agent just knows the current weather; it can’t tell if it’s a good time for sunbathing or going to a nightclub. Let’s extend the weatherAgent
with a timeTool
that it can use to get the current time and recommend a suitable activity.
Create a new file time-tool.ts in the src/mastra/tools
folder and paste the code below in it:
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
export const timeTool = createTool({
id: "get-current-time",
description: "Get the current time and date information",
inputSchema: z.object({
timezone: z
.string()
.optional()
.describe(
'Timezone to format the time in (e.g., "America/New_York", "Europe/London"). Defaults to system timezone',
),
}),
outputSchema: z.object({
date: z.string(),
time: z.string(),
timestamp: z.number(),
}),
execute: async ({ context }) => {
return getCurrentTime(context.timezone);
},
});
const getCurrentTime = (timezone?: string) => {
const now = new Date();
const timestamp = now.getTime();
// Use provided timezone or system default
const targetTimezone =
timezone || Intl.DateTimeFormat().resolvedOptions().timeZone;
const dateFormatter = new Intl.DateTimeFormat("en-US", {
timeZone: targetTimezone,
weekday: "long",
year: "numeric",
month: "2-digit",
day: "2-digit",
});
const timeFormatter = new Intl.DateTimeFormat("en-US", {
timeZone: targetTimezone,
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
});
const date = dateFormatter.format(now);
const time = timeFormatter.format(now);
return {
date,
time,
timestamp,
};
};
Now that you have the tool, add it to the agent’s tools list. First import the module:
import { timeTool } from "../tools/time-tool";
Then update the weatherAgent
export const weatherAgent = new Agent({
//... rest of the code
model: google("gemini-2.5-flash"),
tools: { weatherTool, timeTool },
//.... rest of the code
});
Finally, update the system instruction to get the current time. Add the following prompt to the instruction
field:
- If the user asks for activities, use the timeTool to get the current time based on the location's timezone and suggest activities accordingly.
Your dev server should still be running. If not, restart it and open the playground to try it out.
That’s A Wrap
In this post, you’ve seen how quick and simple it is to build an AI agent. You started with a weather agent and extended it with a tool to get the current time, making it smarter with activity suggestions. This is just the beginning. You can add more tools to give your agent more capabilities, like searching the web or interacting with other APIs. The possibilities are endless. I hope this has sparked your interest in building AI agents, just like it did for me.
I’m curious to see what you build with these models/tools! I’ll keep sharing what I learn along the way. Subscribe to my newsletter (see below) for updates.