Skip to main content

Tools with Workflows

You can use workflows with tools to create reusable, multi-step processes that behave like standard tools. This is useful when you want to encapsulate complex logic behind a simple interface.

Creating a workflow

This example defines a two-step workflow:

  1. getCityCoordinates: Looks up geolocation data for a given city.
  2. getCityTemperature: Uses the coordinates to fetch the current temperature.

The workflow takes a city as input and outputs the temperature.

import { createWorkflow, createStep } from "@mastra/core/workflows";
import { z } from "zod";

const getCityCoordinates = createStep({
id: "get-city-coordinates",
description: "Get geocoding details for a city",
inputSchema: z.object({
city: z.string(),
}),
outputSchema: z.object({
longitude: z.number(),
latitude: z.number(),
}),
execute: async ({ inputData }) => {
const { city } = inputData;

const response = await fetch(
`https://geocoding-api.open-meteo.com/v1/search?name=${city}&count=1`,
);

const { results } = await response.json();
const { latitude, longitude } = results[0];

return {
latitude,
longitude,
};
},
});

const getCityTemperature = createStep({
id: "get-city-temperature",
description: "Get temperature for latitude/longitude",
inputSchema: z.object({
latitude: z.number(),
longitude: z.number(),
}),
outputSchema: z.object({
temperature: z.string(),
}),
execute: async ({ inputData }) => {
const { latitude, longitude } = inputData;

const response = await fetch(
`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current_weather=true`,
);

const { current_weather, current_weather_units } = await response.json();

return {
temperature: `${current_weather.temperature} ${current_weather_units.temperature}`,
};
},
});

export const temperatureWorkflow = createWorkflow({
id: "temperature-workflow",
inputSchema: z.object({
city: z.string(),
}),
outputSchema: z.object({
temperature: z.string(),
}),
})
.then(getCityCoordinates)
.then(getCityTemperature)
.commit();

Running a workflow from a tool

This tool wraps the workflow and exposes it through a standard tool interface. It takes a city as input, runs the underlying workflow, and returns the resulting temperature.

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

export const getTemperatureTool = createTool({
id: "get-temperature-tool",
description: "Gets the temperature for a city",
inputSchema: z.object({
city: z.string(),
}),
outputSchema: z.object({
temperature: z.string(),
}),
execute: async ({ context, mastra }) => {
const { city } = context;
const workflow = mastra!.getWorkflow("temperatureWorkflow");
const run = await workflow!.createRunAsync({});

const runResult = await run!.start({
inputData: {
city,
},
});

const { temperature } = (runResult as any).result;

return {
temperature,
};
},
});
View source on GitHub