Email-Enabled Multi-Agent Conversations with AutoGen

Give your AutoGen agents the ability to send, read, and manage email through MultiMail — with configurable human approval before any message leaves the outbox.


AutoGen is Microsoft's framework for building multi-agent conversational systems. Agents communicate through messages and can include human proxies, enabling complex multi-turn conversations between specialized agents. MultiMail extends AutoGen's capabilities by providing a production email infrastructure that agents can use to communicate with the outside world.

By integrating MultiMail with AutoGen, your agent teams can draft and send emails, check inboxes, manage contacts, and handle threads — all coordinated through AutoGen's group chat and nested chat patterns. The default gated_send mode ensures that emails drafted by any agent in the group require human approval before delivery.

Connect AutoGen agents to MultiMail by registering custom functions that call the REST API, or use the @multimail/mcp-server for tool discovery. Both approaches work with AutoGen's AssistantAgent and ConversableAgent patterns.

Built for AutoGen developers

Multi-Agent Email Coordination

AutoGen's group chat lets multiple specialized agents collaborate on email tasks. One agent triages inbound mail, another drafts replies, and a third manages contacts — all coordinated through AutoGen's conversation protocol with MultiMail handling delivery.

Human Proxy Meets Email Oversight

AutoGen's UserProxyAgent already supports human-in-the-loop for chat. MultiMail extends this to email specifically, letting agents draft emails that flow through a dedicated approval queue rather than requiring inline chat approval.

Graduated Trust for Agent Teams

Start your AutoGen agent team in gated_send mode where every email requires approval. As the team proves reliable, graduate to monitored mode where emails send but humans can review, or autonomous mode for fully trusted workflows.

Thread-Aware Multi-Turn Conversations

MultiMail tracks email threads automatically. Your AutoGen agents can retrieve full email conversation history with get_thread, enabling context-aware replies that reference prior messages in the chain.

Audit Trail for Agent Actions

Every email action taken by your AutoGen agents is logged in MultiMail's audit log. This provides accountability for multi-agent systems where it may be unclear which agent initiated a particular email.


Get started in minutes

Register MultiMail Tools with AutoGen
python
import requests
from autogen import AssistantAgent, UserProxyAgent

MULTIMAIL_API = "https://api.multimail.dev/v1"
HEADERS = {"Authorization": "Bearer mm_live_your_api_key"}

def send_email(to: str, subject: str, body: str, mailbox_id: str) -> dict:
    """Send an email via MultiMail. In gated_send mode, queues for approval."""
    resp = requests.post(f"{MULTIMAIL_API}/send", headers=HEADERS, json={
        "mailbox_id": mailbox_id, "to": to,
        "subject": subject, "body": body
    })
    return resp.json()

def check_inbox(mailbox_id: str, limit: int = 10) -> dict:
    """Check inbox for recent emails."""
    resp = requests.get(
        f"{MULTIMAIL_API}/mailboxes/{mailbox_id}/inbox",
        headers=HEADERS, params={"limit": limit}
    )
    return resp.json()

def reply_email(message_id: str, body: str) -> dict:
    """Reply to an email, maintaining thread context."""
    resp = requests.post(f"{MULTIMAIL_API}/reply", headers=HEADERS, json={
        "message_id": message_id, "body": body
    })
    return resp.json()

Define email functions and register them with an AutoGen AssistantAgent for tool calling.

Build an Email Assistant Agent
python
from autogen import AssistantAgent, UserProxyAgent

assistant = AssistantAgent(
    name="email_assistant",
    system_message="""You are an email assistant with access to MultiMail.
    The mailbox uses gated_send mode, so sent emails will be queued
    for human approval before delivery. Available tools:
    - send_email: Send a new email
    - check_inbox: Check for new messages
    - reply_email: Reply to a message in its thread""",
    llm_config={"config_list": [{"model": "gpt-4o"}]}
)

user_proxy = UserProxyAgent(
    name="human",
    human_input_mode="TERMINATE",
    code_execution_config=False
)

"cm"># Register tools with the assistant
assistant.register_for_llm(name="send_email", description="Send an email")(send_email)
assistant.register_for_llm(name="check_inbox", description="Check inbox")(check_inbox)
assistant.register_for_llm(name="reply_email", description="Reply to email")(reply_email)

"cm"># Register tool execution with the user proxy
user_proxy.register_for_execution(name="send_email")(send_email)
user_proxy.register_for_execution(name="check_inbox")(check_inbox)
user_proxy.register_for_execution(name="reply_email")(reply_email)

user_proxy.initiate_chat(assistant, message="Check my inbox and summarize unread emails")

Create an AutoGen agent pair where the assistant handles email tasks and the user proxy provides human oversight.

Multi-Agent Email Triage Team
python
from autogen import GroupChat, GroupChatManager

triage_agent = AssistantAgent(
    name="triage",
    system_message="You classify emails as urgent, routine, or spam. "
    "Use check_inbox to fetch emails, then announce classifications.",
    llm_config={"config_list": [{"model": "gpt-4o"}]}
)

responder = AssistantAgent(
    name="responder",
    system_message="You draft and send email replies for urgent and routine "
    "emails. Use reply_email to respond. Emails go through gated_send "
    "approval before delivery.",
    llm_config={"config_list": [{"model": "gpt-4o"}]}
)

human = UserProxyAgent(name="human", human_input_mode="TERMINATE")

"cm"># Register tools with all agents
for agent in [triage_agent, responder]:
    agent.register_for_llm(name="check_inbox", description="Check inbox")(check_inbox)
    agent.register_for_llm(name="reply_email", description="Reply to email")(reply_email)
    agent.register_for_llm(name="send_email", description="Send email")(send_email)

for fn in [check_inbox, reply_email, send_email]:
    human.register_for_execution(name=fn.__name__)(fn)

group_chat = GroupChat(agents=[human, triage_agent, responder], messages=[], max_round=10)
manager = GroupChatManager(groupchat=group_chat)

human.initiate_chat(manager, message="Process today&"cm">#039;s inbox")

Create a team of specialized agents that collaborate on email processing using AutoGen's group chat.


Step by step

1

Create a MultiMail Account and API Key

Sign up at multimail.dev, create a mailbox, and generate an API key from your dashboard. Your key will start with mm_live_.

2

Install Dependencies

Install AutoGen and the HTTP library for calling the MultiMail API.

bash
pip install autogen-agentchat requests
3

Define Email Functions

Create Python functions that wrap MultiMail API endpoints for sending, reading, and replying to emails. These will be registered as tools with your agents.

4

Create and Configure Agents

Set up an AssistantAgent with a system prompt explaining the email context and oversight mode. Register your email functions as callable tools.

bash
assistant.register_for_llm(name="send_email", description="Send an email")(send_email)
user_proxy.register_for_execution(name="send_email")(send_email)
5

Run and Approve

Start the conversation with initiate_chat. Review and approve any pending emails in the MultiMail dashboard when using gated_send mode.

bash
user_proxy.initiate_chat(assistant, message="Check my inbox")

Common questions

How does AutoGen's UserProxyAgent interact with MultiMail's oversight?
AutoGen's UserProxyAgent provides inline chat-level approval for agent actions. MultiMail's oversight operates at the email infrastructure level — gated_send queues emails regardless of how many agents are involved in the conversation. This gives you two layers of control: chat-level via UserProxyAgent and email-level via MultiMail.
Can multiple AutoGen agents share the same MultiMail mailbox?
Yes. Multiple agents can call the same mailbox_id in their API requests. MultiMail handles concurrent access and thread tracking. The audit log records which API call initiated each action, so you can trace email activity back to specific agents in your group chat.
Does AutoGen support the MultiMail MCP server?
AutoGen does not have a built-in MCP client adapter, so the recommended approach is to register custom Python functions that call the MultiMail REST API directly. This gives you the same capabilities as the MCP server with AutoGen's native function registration pattern.
How do I handle long-running email workflows with AutoGen?
Use AutoGen's nested chats or sequential chat patterns for multi-step email workflows. For workflows that span human approval delays, you can implement a polling loop that checks MultiMail's pending queue and resumes the conversation once emails are approved.
Can I use AutoGen's code execution with MultiMail?
While AutoGen supports code execution via UserProxyAgent, we recommend using registered functions rather than generated code for email operations. Registered functions enforce the correct API patterns and prevent the agent from bypassing MultiMail's oversight modes through direct HTTP calls.

Explore more

The only agent email with a verifiable sender

Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 38-tool MCP server. Formally verified in Lean 4.