Use OpenAI's function calling to connect GPT-4 agents to MultiMail for sending, reading, and managing email with configurable human oversight.
OpenAI's API provides function calling capabilities that let GPT-4 and other models invoke external tools with structured arguments. MultiMail gives these models a complete email infrastructure layer, so your agents can send, receive, read, and reply to emails on behalf of users through well-defined function calls.
By integrating MultiMail with the OpenAI API, your agents can handle email workflows while respecting human oversight boundaries. The default gated_send mode means your GPT-4 agent drafts emails but a human approves before delivery, adding a critical safety layer that the OpenAI API itself does not provide for external tool execution.
Connect OpenAI to MultiMail by defining email functions in OpenAI's function calling format and routing calls to the MultiMail REST API. You can also use the @multimail/mcp-server for automatic tool discovery with compatible adapters.
OpenAI's function calling uses JSON Schema definitions that map directly to MultiMail's API endpoints. Define send_email, check_inbox, and reply_email as functions, and GPT-4 generates structured calls with typed parameters.
OpenAI's API does not gate external tool execution. MultiMail's oversight modes add the missing safety layer — from gated_send (human approves every email) to autonomous (full agent control) — so you can deploy email agents with confidence.
MultiMail works with both the Chat Completions API and the Assistants API. Define email functions as tools in either API, and your agent can manage email as part of broader multi-tool workflows.
MultiMail tracks email threads and contacts automatically. Your OpenAI agent can retrieve conversation context with get_thread and manage relationships with search_contacts, enabling sophisticated email workflows.
The @multimail/mcp-server package exposes email tools in the Model Context Protocol format. Use MCP adapters to automatically discover and register all MultiMail tools with your OpenAI-powered agent.
from openai import OpenAI
import requests
import json
client = OpenAI()
MULTIMAIL_API = "https://api.multimail.dev/v1"
MM_HEADERS = {"Authorization": "Bearer mm_live_your_api_key"}
email_functions = [
{
"type": "function",
"function": {
"name": "send_email",
"description": "Send an email. In gated_send mode, queues for human approval.",
"parameters": {
"type": "object",
"properties": {
"mailbox_id": {"type": "string", "description": "Mailbox to send from"},
"to": {"type": "string", "description": "Recipient email"},
"subject": {"type": "string", "description": "Subject line"},
"body": {"type": "string", "description": "Email body"}
},
"required": ["mailbox_id", "to", "subject", "body"]
}
}
},
{
"type": "function",
"function": {
"name": "check_inbox",
"description": "Check inbox for recent messages.",
"parameters": {
"type": "object",
"properties": {
"mailbox_id": {"type": "string", "description": "Mailbox to check"},
"limit": {"type": "integer", "description": "Max messages", "default": 10}
},
"required": ["mailbox_id"]
}
}
}
]Create function definitions for email tools using OpenAI's function calling schema.
def execute_function(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)}
)
elif name == "reply_email":
resp = requests.post(f"{MULTIMAIL_API}/reply", headers=MM_HEADERS, json=args)
else:
return json.dumps({"error": f"Unknown function: {name}"})
return json.dumps(resp.json())
def run_email_agent(user_message, mailbox_id):
messages = [
{"role": "system", "content": f"You are an email assistant for mailbox {mailbox_id}. "
f"Emails are sent in gated_send mode and queue for human approval."},
{"role": "user", "content": user_message}
]
while True:
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=email_functions
)
msg = response.choices[0].message
if msg.tool_calls:
messages.append(msg)
for tool_call in msg.tool_calls:
result = execute_function(
tool_call.function.name,
json.loads(tool_call.function.arguments)
)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
else:
return msg.content
print(run_email_agent("Check my inbox and summarize unread messages", "mbx_abc123"))Create an agentic loop where GPT-4 calls MultiMail functions and processes results.
"cm"># GPT-4 may return multiple tool_calls in one response
"cm"># Example: checking inbox AND searching contacts simultaneously
search_contacts_fn = {
"type": "function",
"function": {
"name": "search_contacts",
"description": "Search contacts by name or email.",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search term"}
},
"required": ["query"]
}
}
}
all_functions = email_functions + [search_contacts_fn]
def execute_function(name, args):
endpoints = {
"send_email": lambda: requests.post(f"{MULTIMAIL_API}/send", headers=MM_HEADERS, json=args),
"check_inbox": lambda: requests.get(
f"{MULTIMAIL_API}/mailboxes/{args[&"cm">#039;mailbox_id']}/inbox",
headers=MM_HEADERS, params={"limit": args.get("limit", 10)}
),
"search_contacts": lambda: requests.get(
f"{MULTIMAIL_API}/contacts/search",
headers=MM_HEADERS, params={"q": args["query"]}
)
}
resp = endpoints.get(name, lambda: None)()
return json.dumps(resp.json()) if resp else json.dumps({"error": "Unknown"})GPT-4 can call multiple functions in parallel. Handle parallel check_inbox and search_contacts calls.
import OpenAI from 'openai';
const openai = new OpenAI();
const MULTIMAIL_API = 'https://api.multimail.dev/v1';
const MM_HEADERS = { Authorization: 'Bearer mm_live_your_api_key' };
const tools: OpenAI.Chat.Completions.ChatCompletionTool[] = [
{
type: 'function',
function: {
name: 'send_email',
description: 'Send an email. In gated_send mode, queues for approval.',
parameters: {
type: 'object',
properties: {
mailbox_id: { type: 'string' },
to: { type: 'string' },
subject: { type: 'string' },
body: { type: 'string' }
},
required: ['mailbox_id', 'to', 'subject', 'body']
}
}
}
];
async function executeFunction(name: string, args: Record<string, unknown>) {
const resp = await fetch(`${MULTIMAIL_API}/send`, {
method: 'POST',
headers: { ...MM_HEADERS, 'Content-Type': 'application/json' },
body: JSON.stringify(args)
});
return resp.json();
}
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Send a meeting reminder to [email protected]' }],
tools
});Use the OpenAI Node.js SDK with MultiMail's REST API for TypeScript projects.
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 OpenAI Python SDK and requests library for calling the MultiMail API.
pip install openai requestsCreate function definitions for send_email, check_inbox, and other MultiMail operations using OpenAI's tools format with JSON Schema parameters.
Implement a loop that sends messages to GPT-4, checks for tool_calls in the response, executes functions against MultiMail, and returns results as tool messages.
response = client.chat.completions.create(
model="gpt-4o",
tools=email_functions,
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.