Notebook
Using Amazon Bedrock and Bedrock Guardrails with Mastra
This note explains how to call Amazon Bedrock models and Bedrock Guardrails from Mastra.
Guide
Contents
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.
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-hereFor 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 NameBlockGuardrailCreate 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=400Summary
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.