Give your CrewAI agents the ability to send, read, and reply to email — with graduated human oversight that matches each agent's role and trust level.
CrewAI is a multi-agent framework where each agent has a defined role, goal, and backstory. This role-based design maps naturally to MultiMail's oversight model: a senior agent might operate in autonomous mode while a junior researcher works in gated_send, where every outgoing email requires human approval.
MultiMail provides the email infrastructure your crew needs. Agents can send outreach emails, check inboxes for responses, manage contacts, and track conversation threads — all through the REST API or MCP server. Each action respects the oversight mode configured for that mailbox.
By combining CrewAI's task delegation with MultiMail's email tools, you can build crews that handle complex email workflows: a researcher agent finds contacts, a writer agent drafts messages, and a manager agent reviews the queue before delivery.
Map CrewAI agent roles to MultiMail oversight modes. A trusted outreach agent can operate in monitored mode, while a new agent starts in gated_all where both sends and replies require approval.
CrewAI crews naturally split email tasks across agents. One agent researches contacts, another drafts emails, and a third monitors replies. MultiMail supports this by providing separate tools for each step.
MultiMail maintains email threads automatically. When a CrewAI task involves following up on a previous email, the agent can retrieve the full thread context with get_thread and craft a relevant reply.
CrewAI outreach crews can use MultiMail's search_contacts and add_contact tools to build and query contact databases, tracking who has been contacted and their response history.
Assign different mailboxes to different crew agents. Your sales agent sends from sales@, support agent from help@, and each mailbox can have its own oversight mode and sending limits.
import requests
from crewai.tools import tool
MULTIMAIL_API = "https://api.multimail.dev/v1"
HEADERS = {"Authorization": "Bearer mm_live_your_api_key"}
@tool("Send Email")
def send_email(to: str, subject: str, body: str, mailbox_id: str) -> str:
"""Send an email via MultiMail. In gated_send mode, the email is queued for human approval before delivery."""
resp = requests.post(f"{MULTIMAIL_API}/send", headers=HEADERS, json={
"mailbox_id": mailbox_id,
"to": to,
"subject": subject,
"body": body
})
return str(resp.json())
@tool("Check Inbox")
def check_inbox(mailbox_id: str) -> str:
"""Check the inbox for new emails in a given mailbox."""
resp = requests.get(
f"{MULTIMAIL_API}/mailboxes/{mailbox_id}/inbox",
headers=HEADERS,
params={"limit": 10}
)
return str(resp.json())
@tool("Reply to Email")
def reply_email(message_id: str, body: str) -> str:
"""Reply to an email within its thread."""
resp = requests.post(f"{MULTIMAIL_API}/reply", headers=HEADERS, json={
"message_id": message_id,
"body": body
})
return str(resp.json())Define CrewAI-compatible tools that wrap the MultiMail REST API for sending and reading email.
from crewai import Agent, Task, Crew
researcher = Agent(
role="Lead Researcher",
goal="Find the right contacts and gather context for outreach",
backstory="You are an expert at finding decision-makers and understanding their needs.",
tools=[check_inbox, search_contacts]
)
outreach_agent = Agent(
role="Outreach Specialist",
goal="Draft and send personalized emails that get responses",
backstory="You craft compelling, concise emails. The mailbox uses gated_send mode, so a human reviews each email before delivery.",
tools=[send_email, reply_email, check_inbox]
)
research_task = Task(
description="Check the inbox for any replies to our previous outreach. Summarize who responded and what they said.",
expected_output="A summary of inbox activity with contact names and response content.",
agent=researcher
)
outreach_task = Task(
description="Based on the research summary, draft follow-up emails to contacts who replied positively. Send each email via the send_email tool.",
expected_output="Confirmation that follow-up emails have been queued for approval.",
agent=outreach_agent
)
crew = Crew(
agents=[researcher, outreach_agent],
tasks=[research_task, outreach_task],
verbose=True
)
result = crew.kickoff()Build a CrewAI crew with a researcher and outreach agent that collaborates on email campaigns.
@tool("Get Thread")
def get_thread(thread_id: str) -> str:
"""Retrieve the full email thread for context."""
resp = requests.get(
f"{MULTIMAIL_API}/threads/{thread_id}",
headers=HEADERS
)
return str(resp.json())
support_agent = Agent(
role="Customer Support Agent",
goal="Respond helpfully to customer emails in the support inbox",
backstory="You handle customer support. Always be helpful and professional. All replies go through gated_send for manager review.",
tools=[check_inbox, get_thread, reply_email]
)
support_task = Task(
description="Check the support inbox (mailbox ID: mbx_support). For each unread email, read the full thread and draft a helpful reply.",
expected_output="All customer emails have been replied to with helpful responses queued for approval.",
agent=support_agent
)
support_crew = Crew(
agents=[support_agent],
tasks=[support_task],
verbose=True
)
support_crew.kickoff()A crew that monitors an inbox and drafts responses to customer inquiries.
@tool("Search Contacts")
def search_contacts(query: str) -> str:
"""Search the contact database by name or email."""
resp = requests.get(
f"{MULTIMAIL_API}/contacts",
headers=HEADERS,
params={"q": query}
)
return str(resp.json())
@tool("Add Contact")
def add_contact(email: str, name: str, tags: str = "") -> str:
"""Add a new contact to the database."""
resp = requests.post(f"{MULTIMAIL_API}/contacts", headers=HEADERS, json={
"email": email,
"name": name,
"tags": tags.split(",") if tags else []
})
return str(resp.json())Add contact search and management to your crew's toolkit.
Sign up at multimail.dev and create one or more mailboxes for your crew. Generate an API key from the dashboard.
Install CrewAI and the requests library for API calls.
pip install crewai requestsCreate @tool decorated functions for send_email, check_inbox, reply_email, and any other MultiMail operations your crew needs.
Create agents with roles that map to email responsibilities. Assign each agent only the tools it needs — a reader agent does not need send_email.
Kick off the crew with crew.kickoff(). If using gated_send mode, review and approve pending emails in the MultiMail dashboard.
result = crew.kickoff()Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 38-tool MCP server. Formally verified in Lean 4.