Give MetaGPT's role-based agents the ability to send, read, and manage email — with oversight modes that keep external communications within approved boundaries.
MetaGPT assigns different GPT roles — product manager, architect, engineer — to form a collaborative software company. When these role-based agents need to communicate with external stakeholders via email, MultiMail provides the infrastructure with built-in safety controls.
By integrating MultiMail into MetaGPT's action system, any role can send emails, check inboxes, and manage threads. The default gated_send mode ensures that agent-composed emails are reviewed by a human before delivery, critical when multiple agents may independently decide to reach out to external contacts.
Integration works through MetaGPT's custom Action class. Define email actions that call the MultiMail REST API, then assign them to the roles that need email capabilities.
Different MetaGPT roles can have different email capabilities. A project manager role might send status updates while an engineer role only reads support tickets. MultiMail's per-mailbox oversight modes enable this granular control.
When multiple MetaGPT roles can trigger emails, coordination failures can lead to duplicate or contradictory messages. MultiMail's gated_send mode creates a review queue where a human can catch and resolve conflicts before delivery.
MetaGPT follows Standard Operating Procedures (SOPs). MultiMail's thread tracking and contact management integrate naturally into SOP-driven workflows, maintaining structured communication records.
MultiMail logs which role and action triggered each email, providing a cross-role audit trail. This helps trace communication decisions back to the specific agent and reasoning step that initiated them.
import requests
from metagpt.actions import Action
MULTIMAIL_API = "https://api.multimail.dev/v1"
HEADERS = {"Authorization": "Bearer mm_live_your_api_key"}
class SendEmail(Action):
name: str = "SendEmail"
async def run(self, to: str, subject: str, body: str, mailbox_id: str):
"""Send an email. 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()
class CheckInbox(Action):
name: str = "CheckInbox"
async def run(self, mailbox_id: str, limit: int = 10):
"""Check inbox for new messages."""
resp = requests.get(
f"{MULTIMAIL_API}/mailboxes/{mailbox_id}/inbox",
headers=HEADERS,
params={"limit": limit}
)
return resp.json()
class ReplyEmail(Action):
name: str = "ReplyEmail"
async def run(self, message_id: str, body: 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 resp.json()Create MetaGPT Action classes that wrap MultiMail API calls for sending and reading email.
from metagpt.roles import Role
from metagpt.schema import Message
class CommunicationsManager(Role):
name: str = "CommunicationsManager"
profile: str = "External Communications Manager"
goal: str = "Handle all external email communications for the team"
constraints: str = (
"All emails are sent through MultiMail in gated_send mode. "
"A human must approve each email before delivery. "
"Always maintain professional tone."
)
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.set_actions([SendEmail, CheckInbox, ReplyEmail])
self._watch([Message]) "cm"># React to internal messages
async def _act(self) -> Message:
msg = self.rc.memory.get()[-1]
if "check inbox" in msg.content.lower():
result = await CheckInbox().run(mailbox_id="your_mailbox_id")
return Message(content=str(result), role=self.profile)
elif "send email" in msg.content.lower():
result = await SendEmail().run(
to="[email protected]",
subject="Project Update",
body=msg.content,
mailbox_id="your_mailbox_id"
)
return Message(content=f"Email queued: {result}", role=self.profile)Define a MetaGPT Role that uses MultiMail actions to handle external communications.
from metagpt.team import Team
async def run_email_team():
team = Team()
"cm"># Add roles with different email responsibilities
comms = CommunicationsManager()
team.hire([comms])
team.invest(investment=5.0) "cm"># Budget in dollars
"cm"># Run the team with an email-related objective
await team.run(
idea="Check the support inbox for new customer inquiries. "
"Draft professional responses to each inquiry. "
"All responses will be queued for human approval "
"before delivery via gated_send mode."
)
import asyncio
asyncio.run(run_email_team())Set up a MetaGPT team where roles collaborate on email-driven 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 MetaGPT and the HTTP library for calling the MultiMail API.
pip install metagpt requestsCreate MetaGPT Action subclasses that wrap MultiMail API endpoints. At minimum, define SendEmail and CheckInbox actions.
Create a Role subclass that uses your email actions. Set constraints in the role definition to explain the oversight mode and communication guidelines.
Monitor the MultiMail dashboard for pending emails generated by your MetaGPT roles. Review and approve each message before it is delivered.
Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 38-tool MCP server. Formally verified in Lean 4.