Connect Anthropic's Claude API to MultiMail and let your agents send, read, and manage email — with configurable human oversight at every step.
Anthropic's Claude API provides native tool use capabilities that map directly to MultiMail's email tools. Claude can call structured tools like send_email, check_inbox, and reply_email with well-formed JSON arguments, making it a natural fit for building email agents that interact with real mailboxes.
By integrating MultiMail with the Claude API, your agents gain full email capabilities while respecting human oversight boundaries. The default gated_send mode means Claude drafts emails but a human approves before delivery, creating a trust ladder that lets you safely increase agent autonomy over time.
You can connect Claude to MultiMail by defining email tools in Claude's tool use format and calling the MultiMail REST API, or by connecting to the @multimail/mcp-server for automatic tool discovery. Both approaches give your agent structured access to the full suite of email operations.
Claude's tool_use feature accepts structured JSON tool definitions. MultiMail's email tools map directly to this format — send_email, check_inbox, reply_email — with typed parameters that Claude fills reliably.
Start with gated_send (Claude composes, human approves) and progress to monitored or autonomous as trust builds. MultiMail supports five oversight modes so you can match the level of autonomy to your confidence in the agent.
The @multimail/mcp-server package exposes email tools in the Model Context Protocol format. Claude's MCP support lets your agent discover and call all MultiMail tools without manual tool definitions.
MultiMail tracks email threads automatically. Your Claude agent can retrieve full conversation history with get_thread, enabling context-aware replies that maintain continuity across multi-turn email exchanges.
Claude excels at generating well-structured JSON tool calls. Combined with MultiMail's typed API, this means fewer malformed requests and more reliable email agent workflows compared to free-form API calls.
from anthropic import Anthropic
import requests
MULTIMAIL_API = "https://api.multimail.dev/v1"
MM_HEADERS = {"Authorization": "Bearer mm_live_your_api_key"}
email_tools = [
{
"name": "send_email",
"description": "Send an email through MultiMail. In gated_send mode, this creates a pending draft for human approval.",
"input_schema": {
"type": "object",
"properties": {
"mailbox_id": {"type": "string", "description": "The mailbox to send from"},
"to": {"type": "string", "description": "Recipient email address"},
"subject": {"type": "string", "description": "Email subject line"},
"body": {"type": "string", "description": "Email body content"}
},
"required": ["mailbox_id", "to", "subject", "body"]
}
},
{
"name": "check_inbox",
"description": "Check the inbox for a given mailbox. Returns recent messages.",
"input_schema": {
"type": "object",
"properties": {
"mailbox_id": {"type": "string", "description": "The mailbox to check"},
"limit": {"type": "integer", "description": "Max messages to return", "default": 10}
},
"required": ["mailbox_id"]
}
}
]Define email tools using Claude's native tool use schema so the model can send emails and check inboxes.
client = Anthropic()
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)}
)
else:
return {"error": f"Unknown tool: {name}"}
return resp.json()
def run_email_agent(user_message, mailbox_id):
messages = [{"role": "user", "content": user_message}]
while True:
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system=f"You are an email assistant. Mailbox ID: {mailbox_id}. "
f"Emails are sent in gated_send mode — they queue for human approval.",
tools=email_tools,
messages=messages
)
if response.stop_reason == "tool_use":
tool_block = next(b for b in response.content if b.type == "tool_use")
result = execute_tool(tool_block.name, tool_block.input)
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": [
{"type": "tool_result", "tool_use_id": tool_block.id,
"content": str(result)}
]})
else:
return response.content[0].textCreate an agentic loop where Claude calls MultiMail tools and processes the results.
reply_tools = [
{
"name": "get_thread",
"description": "Get all messages in an email thread for context.",
"input_schema": {
"type": "object",
"properties": {
"thread_id": {"type": "string", "description": "Thread ID to retrieve"}
},
"required": ["thread_id"]
}
},
{
"name": "reply_email",
"description": "Reply to an email by message ID within its thread.",
"input_schema": {
"type": "object",
"properties": {
"message_id": {"type": "string", "description": "Message ID to reply to"},
"body": {"type": "string", "description": "Reply body content"}
},
"required": ["message_id", "body"]
}
}
]
"cm"># Combine all tools for a full-featured email agent
all_tools = email_tools + reply_tools
result = run_email_agent(
"Check my inbox and reply to the latest message from Sarah",
mailbox_id="mbx_abc123"
)Add thread-aware reply tools so Claude can respond to emails with full conversation context.
def run_streaming_agent(user_message, mailbox_id):
messages = [{"role": "user", "content": user_message}]
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system=f"You are an email assistant for mailbox {mailbox_id}.",
tools=email_tools,
messages=messages
) as stream:
for event in stream:
if hasattr(event, &"cm">#039;type'):
if event.type == &"cm">#039;content_block_start':
if hasattr(event.content_block, &"cm">#039;name'):
print(f"Calling tool: {event.content_block.name}")
elif event.type == &"cm">#039;text':
print(event.text, end=&"cm">#039;', flush=True)
response = stream.get_final_message()
return responseUse Claude's streaming API for real-time feedback as the agent processes email tasks.
Sign up at multimail.dev, create a mailbox, and generate an API key from your dashboard. Your key will start with mm_live_.
Install the Anthropic Python SDK and requests library for calling the MultiMail API.
pip install anthropic requestsCreate tool definitions for send_email, check_inbox, and other MultiMail operations using Claude's input_schema format.
Implement a loop that sends messages to Claude, detects tool_use stop reasons, executes tools against MultiMail, and returns results.
response = client.messages.create(
model="claude-sonnet-4-20250514",
tools=email_tools,
messages=messages
)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.