Skip to Content
DocsAgentsRuntime/Dynamic Variables

Agent Runtime Variables

Mastra provides a robust dependency injection system that enables you to configure your agents and tools with runtime variables. This feature is essential for creating flexible and reusable agents that can adapt their behavior based on runtime configuration.

Overview

The dependency injection system allows you to:

  1. Pass runtime configuration variables to agents through a type-safe container
  2. Access these variables within tool execution contexts
  3. Modify agent behavior without changing the underlying code
  4. Share configuration across multiple tools within the same agent

Basic Usage

const agent = mastra.getAgent("weatherAgent"); // Define your container's type structure type WeatherContainer = { "temperature-scale": "celsius" | "fahrenheit" // Fixed typo in "fahrenheit" } const container = new Container<WeatherContainer>(); container.set("temperature-scale", "celsius"); const response = await agent.generate("What's the weather like today?", { container }); console.log(response.text);

Using with REST API

Here’s how to dynamically set temperature units based on a user’s location using the Cloudflare CF-IPCountry header:

src/index.ts
import { Mastra } from "@mastra/core"; import { Container } from "@mastra/core/di"; import { agent as weatherAgent } from "./agents/weather"; // Define container type with clear, descriptive types type WeatherContainer = { "temperature-scale": "celsius" | "fahrenheit" } export const mastra = new Mastra({ agents: { weather: weatherAgent, }, server: { middleware: [ async (c, next) => { const country = c.req.header("CF-IPCountry"); const container = c.get<WeatherContainer>("container"); // Set temperature scale based on country container.set( "temperature-scale", country === "US" ? "fahrenheit" : "celsius", ); await next(); // Don't forget to call next() }, ], }, });

Creating Tools with Variables

Tools can access container variables and must conform to the agent’s container type:

import { createTool } from "@mastra/core/tools"; import { z } from "zod"; export const weatherTool = createTool({ id: "getWeather", description: "Get the current weather for a location", inputSchema: z.object({ location: z.string().describe("The location to get weather for"), }), execute: async ({ context, container }) => { // Type-safe access to container variables const temperatureUnit = container.get("temperature-scale"); const weather = await fetchWeather(context.location, { temperatureUnit, }); return { result: weather }; }, }); async function fetchWeather( location: string, { temperatureUnit }: { temperatureUnit: "celsius" | "fahrenheit" } ): Promise<WeatherResponse> { // Implementation of weather API call const response = await weatherApi.fetch(location, temperatureUnit); return { location, temperature: "72°F", conditions: "Sunny", unit: temperatureUnit, }; }

Error Handling

When working with runtime variables, it’s important to handle potential errors:

  1. Missing Variables: Always check if required variables exist in the container
  2. Type Mismatches: Use TypeScript’s type system to catch type errors at compile time
  3. Invalid Values: Validate variable values before using them in your tools
// Example of defensive programming with container variables const temperatureUnit = container.get("temperature-scale"); if (!temperatureUnit) { throw new Error("Temperature scale not configured in container"); } // Type guard for additional runtime safety if (temperatureUnit !== "celsius" && temperatureUnit !== "fahrenheit") { throw new Error(`Invalid temperature unit: ${temperatureUnit}`); }