August 1, 2026
MastraAWSLLM Guardrails

Notebook

Using Amazon Bedrock and Bedrock Guardrails with Mastra

This note explains how to call Amazon Bedrock models and Bedrock Guardrails from Mastra.

MastraAmazon BedrockLLMAmazon Bedrock Guardrails
日本語

Guide

Contents

  1. Prerequisites
  2. Code for Using Bedrock
  3. Testing with curl
  4. Adding Bedrock Guardrails
  5. Testing with curl
  6. Returning a Non-200 Status When Guardrails Detect an Error
  7. Summary

The official Mastra documentation was a little hard to follow for using Bedrock from Mastra, so I summarized what I found while trying it myself.

Prerequisites

This example uses Hono so the Agent can be called from an API endpoint. I created the environment by following this guide.

Mastra Hono guide

Code for Using Bedrock

Create code like this.

import { Agent } from '@mastra/core/agent';
import { Memory } from '@mastra/memory';
import { weatherTool } from '../tools/weather-tool.js';
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
 
const amazonBedrock = createAmazonBedrock({
  region: 'us-east-1',
});
 
export const bedrockTutorialAgent = new Agent({
  id: 'bedrock-tutorial-agent',
  name: 'Bedrock Tutorial 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: amazonBedrock('us.anthropic.claude-haiku-4-5-20251001-v1:0'),
  tools: { weatherTool },
  memory: new Memory(),
});

Next, set the Bedrock API key in the AWS_BEARER_TOKEN_BEDROCK environment variable.

export AWS_BEARER_TOKEN_BEDROCK=your-api-key-here

For this example, I used a Bedrock API key to keep the setup simple.
If you want to use another authentication method such as IAM authentication, you can do that by changing the parameters passed to createAmazonBedrock.
See AI SDK -> Amazon Bedrock Provider for details.

Then update the Hono API to call this Agent.

app.post('/bedrock', async c => {
  const { message } = await c.req.json<{ message?: unknown }>()
 
  if (typeof message !== 'string' || message.trim().length === 0) {
    return c.json({ error: 'message is required' }, 400)
  }
 
  const result = await bedrockTutorialAgent.generate(message)
  return c.text(result.text)
})

Testing with curl

Test it with curl.

$ curl -X POST http://localhost:3000/bedrock -H "Content-Type: application/json" -d '{"message":"I am in Tokyo. What is the weather now?"}'
 
Here's the current weather in Tokyo:
 
**Temperature:** 27.5°C (feels like 32.8°C)
**Conditions:** Partly cloudy
**Humidity:** 78%
**Wind Speed:** 2.6 m/s
**Wind Gust:** 18 m/s
 
It's quite warm and humid in Tokyo right now with moderately strong winds. The "feels like" temperature is noticeably higher due to the humidity, so it may feel more oppressive than the actual temperature suggests. You might want to stay hydrated and consider lighter clothing!

Adding Bedrock Guardrails

Next, here is an example of applying Bedrock Guardrails.

AWSTemplateFormatVersion: '2010-09-09'
Description: Bedrock Guardrail that blocks names in user input or model output.
 
Resources:
  NameBlockGuardrail:
    Type: AWS::Bedrock::Guardrail
    Properties:
      Name: "name-block-guardrail"
      Description: "Checks that text does not include a person's name."
      BlockedInputMessaging: "Your input includes a person's name."
      BlockedOutputsMessaging: "The answer includes a person's name."
      SensitiveInformationPolicyConfig:
        PiiEntitiesConfig:
          - Type: NAME
            Action: BLOCK
            InputAction: BLOCK
            OutputAction: BLOCK
            InputEnabled: true
            OutputEnabled: true
 
Outputs:
  GuardrailId:
    Description: Guardrail ID
    Value: !Ref NameBlockGuardrail

Create the Guardrail.

$ aws cloudformation deploy --template-file guardrail.yaml --stack-name guardrail
$ aws cloudformation describe-stacks --stack-name guardrail --query "Stacks[0].Outputs"
[
    {
        "OutputKey": "GuardrailId",
        "OutputValue": "arn:aws:bedrock:us-east-1:123456789012:guardrail/xxxxxxxx",
        "Description": "Guardrail ID"
    }
]

Add the Guardrail settings to defaultOptions where the Agent instance is created.

@@ -25,4 +25,16 @@ Use the weatherTool to fetch current weather data.`,
   model: amazonBedrock('us.anthropic.claude-haiku-4-5-20251001-v1:0'),
   tools: { weatherTool },
   memory: new Memory(),
+  defaultOptions: {
+    providerOptions: {
+      bedrock: {
+        guardrailConfig: {
+          guardrailIdentifier: 'xxxxxxxx',
+          guardrailVersion: 'DRAFT',
+          trace: 'enabled',
+          streamProcessingMode: 'async',
+        },
+      },
+    },
+  },
 });

Testing with curl

Test it with curl.

curl -X POST http://localhost:3000/bedrock -H "Content-Type: application/json" -d '{"message":"I am Taro. What is your name?"}'
Your input includes a person's name.

Instead of returning a name, the API returned the message configured in Bedrock.

Returning a Non-200 Status When Guardrails Detect an Error

When a Guardrail blocks the request, result.finishReason becomes content-filter, so you can use that value for branching.

@@ -21,6 +21,13 @@ app.post('/bedrock', async c => {
   }
 
   const result = await bedrockTutorialAgent.generate(message)
+
+  const blocked = result.finishReason === 'content-filter'
+
+  if (blocked) {
+    return c.text(result.text, 400)
+  }
+
   return c.text(result.text)
 })
$ curl -s -X POST http://localhost:3000/bedrock -H "Content-Type: application/json" -d '{"message":"I am Taro. What is your name?"}' -w '\nHTTP_STATUS=%{http_code}\n'
Your input includes a person's name.
HTTP_STATUS=400

Summary

To use Amazon Bedrock from Mastra, create a Bedrock provider with @ai-sdk/amazon-bedrock and pass it to the Agent's model.

Bedrock-specific settings such as Bedrock Guardrails can also be applied through defaultOptions.providerOptions.bedrock. When a Guardrail blocks a request, you can handle it as a normal API response by checking result.text and result.finishReason.

Combining a Mastra Agent with Bedrock keeps the application-side implementation simple while still using AWS-side model management and Guardrails. This makes it a practical option when adding LLM features to business applications.