Overview

Mastra is a TypeScript framework for building AI applications. HumanLayer adds human oversight to your AI features.

Getting Started with Mastra

Installation

The easiest way to get started with Mastra is to use create-mastra:

npx create-mastra@latest

When prompted, accept the default options for the setup.

During the create-mastra setup, you’ll be prompted to choose a model provider. While this guide uses OpenAI models in the examples, Mastra supports all models available through the Vercel AI SDK (e.g., OpenAI, Anthropic, Google, etc.). Accepting the defaults will typically select OpenAI.

This command will guide you through setting up a new Mastra project, asking for a project name and other configurations.

After the setup is complete, navigate into your new project directory:

cd your-project-name
# Replace 'your-project-name' with the name you chose during setup

For more installation and project set up details, check Mastra’s documentation here

Next, install the necessary packages for memory management and HumanLayer integration:

npm install @mastra/memory humanlayer-vercel-ai-sdk

Configuration

Set up your environment variables. Create a .env.development file in your project root and add your API keys:

.env.development
OPENAI_API_KEY=your-openai-key
HUMANLAYER_API_KEY=your-humanlayer-key

You can get your HumanLayer API key from the HumanLayer dashboard.

Chef Agent Example

This example demonstrates building a “Chef Agent” that can check available ingredients and then cook a meal. Checking ingredients is a simple read operation, while cooking the meal is an action that requires human approval via HumanLayer.

Tools Definition

Mastra offers flexibility by supporting both its native tool format and the Vercel AI SDK tool format. For seamless integration with HumanLayer, this guide utilizes the Vercel AI SDK format. Learn more about adding tools in Mastra here.

src/mastra/tools/kitchenTools.ts
import { z } from "zod";
import { tool } from "ai";
import { humanlayer } from "humanlayer-vercel-ai-sdk";

const hl = humanlayer({ verbose: true });

// Tool to check ingredients (read operation, no approval needed)
export const checkIngredients = tool({
  description: "Checks the available ingredients in the kitchen.",
  parameters: z.object({}),
  execute: async () => {
    // Hardcoded list of available ingredients
    return [
      {
        category: "Proteins",
        items: [
          { name: "Chicken breast", quantity: "1 lb", expiresIn: "2 days" },
          { name: "Ground beef", quantity: "0.5 lb", expiresIn: "1 day" },
          { name: "Eggs", quantity: "6", expiresIn: "1 week" },
          { name: "Tofu", quantity: "1 block", expiresIn: "5 days" },
        ],
      },
      {
        category: "Vegetables",
        items: [
          { name: "Onions", quantity: "3", expiresIn: "2 weeks" },
          { name: "Bell peppers", quantity: "2", expiresIn: "4 days" },
          { name: "Carrots", quantity: "5", expiresIn: "10 days" },
          { name: "Spinach", quantity: "1 bag", expiresIn: "3 days" },
          { name: "Tomatoes", quantity: "4", expiresIn: "5 days" },
        ],
      },
      // More categories...
    ];
  },
});

// Tool to cook a meal (write operation, requires approval)
const cookMealTool = tool({
  description: "Cooks a specified meal using available ingredients.",
  parameters: z.object({
    mealName: z
      .string()
      .describe("The name of the meal to cook, e.g., 'Chicken Stir-fry'"),
  }),
  execute: async ({ mealName }) => {
    // Simulate the cooking process
    console.log(`Cooking ${mealName}...`);
    // In a real scenario, this might interact with smart kitchen devices,
    // update inventory, or log the meal.
    return `${mealName} has been cooked successfully!`;
  },
});

// Wrap the cookMealTool with HumanLayer approval
export const cookMeal = hl.requireApproval({ cookMealTool });

Agent Definition

Now that the tools are defined, we can create the agent that uses them.

src/mastra/agents/chefAgent.ts
import { openai } from "@ai-sdk/openai";
import { Agent } from "@mastra/core/agent";
import { Memory } from "@mastra/memory";
import { checkIngredients, cookMeal } from "../tools/kitchenTools"; // Import the tools

export const chefAgent = new Agent({
  name: "chef-agent",
  instructions:
    "You are Michel, a practical and experienced home chef. " +
    "You help people cook with whatever ingredients they have available. " +
    "Use the checkIngredients tool to see what's available. " +
    "Use the cookMeal tool to prepare a meal, but be aware this requires approval.",
  model: openai("gpt-4o"),
  tools: { checkIngredients, cookMeal }, // Use the imported tools
  memory: new Memory(),
});

Register agent

src/mastra/index.ts
import { Mastra } from "@mastra/core";
import { chefAgent } from "./agents/chefAgent";

export const mastra = new Mastra({
  agents: { chefAgent },
});

Running the Chef Agent

To run your chef agent:

  1. Start your Mastra project:

    npm run dev
    
  2. Access the Mastra playground at http://localhost:4111

  3. Interact with your chef agent. Ask it to check ingredients (this won’t require approval). Then, ask it to cook a specific meal (e.g., “Cook chicken stir-fry”).

  4. When the agent attempts to use the cookMeal tool, HumanLayer will require approval before proceeding. The checkIngredients tool will execute without interruption.

The agent will pause execution only when attempting to use the cookMeal tool, while waiting for human approval.

Approving Actions via HumanLayer Dashboard

When your agent uses the cookMeal tool (wrapped with hl.requireApproval()), you’ll need to approve the action:

  1. Access the HumanLayer dashboard at:

    https://app.humanlayer.dev/[org]/[your-project-slug]/approvals
    
  2. View the pending approval request for cookMealTool.

  3. Review the details of the request, including:

    • The tool being used (cookMealTool)
    • Parameters passed (e.g., mealName: "Chicken Stir-fry")
    • Context of the request
  4. Choose to approve or deny the request.

If you’ve configured other notification channels (e.g., Slack), you’ll also receive approval requests through those channels.

Once approved, the agent will continue execution, receiving the confirmation message from the cookMealTool.

Integrating HumanLayer with Mastra

HumanLayer works seamlessly with Mastra by wrapping Vercel AI SDK format tools with approval requirements.

The integration follows these simple steps:

  1. Create your tools using the Vercel AI SDK tool() function.
  2. Initialize HumanLayer.
  3. Wrap the specific tools that require oversight (like cookMealTool) with hl.requireApproval().
  4. Add both standard and approval-wrapped tools to your Mastra agents.
  5. Human involvement is automatically triggered only when the wrapped tools are used.

Next Steps