Use Marvin's classification and extraction functions to intelligently process email, then route and respond through MultiMail with configurable human oversight.
Marvin is a lightweight AI engineering toolkit by Prefect focused on building reliable AI features. It provides simple functions for classification, extraction, transformation, and generation — making it ideal for email processing tasks like triage, categorization, and response generation. MultiMail provides the email infrastructure that connects Marvin's intelligence to actual inboxes.
By combining Marvin with MultiMail, you can classify inbound emails by intent and urgency, extract structured data from email content, generate appropriate responses, and route everything through managed mailboxes with human oversight. Marvin handles the AI reasoning, MultiMail handles the email delivery.
Integration is straightforward: use Marvin's functions to process email data fetched from MultiMail's API, then send responses back through MultiMail. No complex framework setup required — just function calls.
Marvin's classify function categorizes inbound emails by type, urgency, or department with a single function call. Combined with MultiMail's inbox, you can build automated email triage that routes messages to the right handlers.
Use marvin.extract() to pull structured data from email bodies — order numbers, dates, amounts, names. This extracted data drives automated workflows while MultiMail manages the email infrastructure.
Marvin's functions (classify, extract, transform, generate) are single-purpose and composable. Each one maps to a specific email processing step, making workflows easy to understand and debug.
Use marvin.generate() to create email responses based on classification and extracted context. MultiMail's gated_send mode ensures generated responses get human review before delivery.
Marvin functions are standalone Python functions. You can use them with any email processing architecture, swap individual steps, or combine with other tools alongside MultiMail.
import marvin
import requests
from enum import Enum
MULTIMAIL_API = "https://api.multimail.dev/v1"
HEADERS = {"Authorization": "Bearer mm_live_your_api_key"}
class EmailCategory(Enum):
SUPPORT = "support"
SALES = "sales"
BILLING = "billing"
PARTNERSHIP = "partnership"
SPAM = "spam"
class Urgency(Enum):
HIGH = "high"
MEDIUM = "medium"
LOW = "low"
def triage_inbox(mailbox_id: str):
resp = requests.get(
f"{MULTIMAIL_API}/mailboxes/{mailbox_id}/inbox",
headers=HEADERS, params={"limit": 20}
)
for email in resp.json().get("emails", []):
content = f"Subject: {email[&"cm">#039;subject']}\n\n{email['body']}"
category = marvin.classify(content, labels=EmailCategory)
urgency = marvin.classify(content, labels=Urgency)
# Tag the email in MultiMail
requests.post(f"{MULTIMAIL_API}/tag", headers=HEADERS, json={
"message_id": email["message_id"],
"tags": [category.value, urgency.value]
})
print(f"{email[&"cm">#039;subject']}: {category.value} ({urgency.value})")
triage_inbox("your_mailbox_id")Use Marvin's classify function to categorize emails fetched from MultiMail.
from pydantic import BaseModel
class SupportTicket(BaseModel):
customer_name: str
issue_summary: str
product_mentioned: str
account_id: str | None = None
def process_support_email(email: dict) -> dict:
content = f"Subject: {email[&"cm">#039;subject']}\n\n{email['body']}"
# Extract structured data
ticket = marvin.extract(content, target=SupportTicket)[0]
# Generate a response
reply_body = marvin.generate(
n=1,
instructions=f"Write a professional support reply acknowledging "
f"the issue: {ticket.issue_summary}. Address the customer as "
f"{ticket.customer_name}. Be empathetic and provide next steps."
)[0]
# Send via MultiMail (gated_send queues for approval)
resp = requests.post(f"{MULTIMAIL_API}/reply", headers=HEADERS, json={
"message_id": email["message_id"],
"body": reply_body
})
return {"ticket": ticket.model_dump(), "reply": reply_body, "result": resp.json()}
# Process a support email
email = {"subject": "Login issue", "body": "Hi, I&"cm">#039;m John from Acme Corp...",
"message_id": "msg_abc123"}
result = process_support_email(email)Extract structured data from emails and generate context-aware responses.
def forward_with_summary(email: dict, forward_to: str, mailbox_id: str):
"""Forward an email with an AI-generated executive summary."""
content = f"Subject: {email[&"cm">#039;subject']}\n\n{email['body']}"
# Transform the email into an executive summary
summary = marvin.cast(
content,
instructions="Summarize this email in 2-3 bullet points for an executive audience. "
"Focus on action items and decisions needed."
)
# Send the summary as a forwarded email via MultiMail
resp = requests.post(f"{MULTIMAIL_API}/send", headers=HEADERS, json={
"mailbox_id": mailbox_id,
"to": forward_to,
"subject": f"[Summary] {email[&"cm">#039;subject']}",
"body": f"Executive Summary:\n\n{summary}\n\n---\nOriginal email below:\n\n{email[&"cm">#039;body']}"
})
return resp.json()
result = forward_with_summary(
email={"subject": "Q3 Budget Review", "body": "Detailed budget analysis..."},
forward_to="[email protected]",
mailbox_id="your_mailbox_id"
)Use Marvin's transform to rewrite emails for different audiences or formats.
Sign up at multimail.dev, create a mailbox, and generate an API key. Your key will start with mm_live_.
Install Marvin and requests for calling the MultiMail API.
pip install marvin requestsUse the MultiMail API to fetch inbox messages, then classify each with marvin.classify() using your custom label enums.
category = marvin.classify(email_content, labels=EmailCategory)Use marvin.extract() to pull structured data from emails and marvin.generate() to compose responses.
Send replies through MultiMail's API. Review and approve pending emails in the dashboard when using gated_send mode.
Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 38-tool MCP server. Formally verified in Lean 4.