Connect AWS Bedrock Agents to MultiMail for sending, reading, and managing email — with enterprise guardrails and configurable human oversight.
AWS Bedrock provides managed access to foundation models from multiple providers, along with Bedrock Agents for building agentic applications with tool use, knowledge bases, and guardrails. MultiMail gives Bedrock Agents the email infrastructure layer they need to send, receive, and manage email within the AWS ecosystem.
By integrating MultiMail with AWS Bedrock, enterprises get defense-in-depth for AI-initiated email: Bedrock Guardrails filter content at the model level, and MultiMail's oversight modes control send authorization. The default gated_send mode means your Bedrock Agent drafts emails but a human approves before delivery.
Connect Bedrock to MultiMail by defining email actions as Lambda-backed action groups in Bedrock Agents, or by using the Converse API with tool definitions that call the MultiMail REST API.
Bedrock Guardrails filter harmful content at the model level. MultiMail adds email-specific oversight on top — content safety from AWS, send authorization from MultiMail. Two independent safety layers for enterprise compliance.
Define MultiMail email operations as action groups in Bedrock Agents. Each action group maps to a Lambda function that calls the MultiMail API, giving your agent structured email capabilities.
Bedrock provides access to Claude, Llama, Mistral, and other models. Test different models for email quality while keeping the same MultiMail integration — switch the model ID without changing your action groups.
MultiMail's comprehensive audit logs complement AWS CloudTrail. Together, they provide end-to-end traceability for every AI-initiated email action, satisfying enterprise governance requirements.
Start with gated_send (agent composes, human approves) and progress to autonomous as trust builds. MultiMail's oversight modes align with enterprise change management processes.
import boto3
import requests
import json
bedrock = boto3.client(&"cm">#039;bedrock-runtime', region_name='us-east-1')
MULTIMAIL_API = "https://api.multimail.dev/v1"
MM_HEADERS = {"Authorization": "Bearer mm_live_your_api_key"}
tool_config = {
"tools": [
{
"toolSpec": {
"name": "send_email",
"description": "Send an email through MultiMail. In gated_send mode, queues for human approval.",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"mailbox_id": {"type": "string", "description": "Mailbox to send from"},
"to": {"type": "string", "description": "Recipient email"},
"subject": {"type": "string", "description": "Subject line"},
"body": {"type": "string", "description": "Email body"}
},
"required": ["mailbox_id", "to", "subject", "body"]
}
}
}
},
{
"toolSpec": {
"name": "check_inbox",
"description": "Check inbox for recent messages.",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"mailbox_id": {"type": "string", "description": "Mailbox to check"},
"limit": {"type": "integer", "description": "Max messages"}
},
"required": ["mailbox_id"]
}
}
}
}
]
}Define email tools using the Bedrock Converse API's tool configuration and call MultiMail.
def execute_tool(name, args):
if name == "send_email":
resp = requests.post(f"{MULTIMAIL_API}/send", headers=MM_HEADERS, json=args)
elif name == "check_inbox":
resp = requests.get(
f"{MULTIMAIL_API}/mailboxes/{args[&"cm">#039;mailbox_id']}/inbox",
headers=MM_HEADERS, params={"limit": args.get("limit", 10)}
)
elif name == "reply_email":
resp = requests.post(f"{MULTIMAIL_API}/reply", headers=MM_HEADERS, json=args)
else:
return {"error": f"Unknown tool: {name}"}
return resp.json()
def run_bedrock_email_agent(user_message, mailbox_id):
messages = [{"role": "user", "content": [{"text": user_message}]}]
system = [{"text": f"You are an email assistant for mailbox {mailbox_id}. "
f"Emails use gated_send mode and queue for human approval."}]
while True:
response = bedrock.converse(
modelId="anthropic.claude-sonnet-4-20250514-v1:0",
messages=messages,
system=system,
toolConfig=tool_config
)
output = response["output"]["message"]
messages.append(output)
if response["stopReason"] == "tool_use":
tool_results = []
for block in output["content"]:
if "toolUse" in block:
result = execute_tool(block["toolUse"]["name"], block["toolUse"]["input"])
tool_results.append({
"toolResult": {
"toolUseId": block["toolUse"]["toolUseId"],
"content": [{"json": result}]
}
})
messages.append({"role": "user", "content": tool_results})
else:
return output["content"][0]["text"]
print(run_bedrock_email_agent("Check my inbox", "mbx_abc123"))Create an agentic loop using the Bedrock Converse API with MultiMail tools.
import json
import urllib3
http = urllib3.PoolManager()
MULTIMAIL_API = "https://api.multimail.dev/v1"
def lambda_handler(event, context):
"""Bedrock Agent action group Lambda for MultiMail email operations."""
action = event.get("actionGroup")
api_path = event.get("apiPath")
parameters = {p["name"]: p["value"] for p in event.get("parameters", [])}
body = json.loads(event.get("requestBody", {}).get("content", {}).get(
"application/json", {}).get("properties", "[]"))
body_dict = {item["name"]: item["value"] for item in body} if body else {}
api_key = get_secret("multimail-api-key") "cm"># AWS Secrets Manager
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
if api_path == "/send":
resp = http.request("POST", f"{MULTIMAIL_API}/send",
headers=headers, body=json.dumps(body_dict))
elif api_path == "/inbox":
mailbox_id = parameters.get("mailbox_id")
resp = http.request("GET", f"{MULTIMAIL_API}/mailboxes/{mailbox_id}/inbox",
headers=headers)
else:
return {"statusCode": 400, "body": "Unknown action"}
return {
"messageVersion": "1.0",
"response": {
"actionGroup": action,
"apiPath": api_path,
"httpMethod": event.get("httpMethod"),
"httpStatusCode": resp.status,
"responseBody": {"application/json": {"body": resp.data.decode()}}
}
}Create a Lambda function that serves as a Bedrock Agent action group for MultiMail email operations.
Sign up at multimail.dev, create a mailbox, and generate an API key. Store the key in AWS Secrets Manager for secure access from Lambda functions.
Install boto3 and requests for the Converse API approach, or set up a Lambda function for the Bedrock Agents approach.
pip install boto3 requestsFor the Converse API, define toolSpec objects for email operations. For Bedrock Agents, create an OpenAPI schema and Lambda function for email action groups.
Implement the agent loop using the Converse API, or configure your Bedrock Agent with email action groups and test via the Bedrock console.
response = bedrock.converse(
modelId="anthropic.claude-sonnet-4-20250514-v1:0",
messages=messages,
toolConfig=tool_config
)If your mailbox uses gated_send mode (the default), review and approve pending emails in the MultiMail dashboard before they are delivered.
Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 38-tool MCP server. Formally verified in Lean 4.