Run open-source LLMs locally with Ollama and connect them to MultiMail for email capabilities — with human oversight as a safety net for local models.
Ollama lets you run open-source LLMs like Llama 3, Mistral, and Qwen locally with an OpenAI-compatible API. MultiMail provides the email infrastructure layer that turns local models into functional email agents capable of sending, receiving, and managing email.
Local LLMs via Ollama may have weaker instruction following than cloud models, making human oversight especially important. MultiMail's default gated_send mode ensures every email drafted by a local model requires human approval before delivery, protecting against lower-quality model outputs.
Connect Ollama to MultiMail using the OpenAI-compatible API with tool calling support. Your data stays local during inference while MultiMail handles the email transport, creating a privacy-friendly architecture for sensitive email workflows.
Local LLMs may produce lower-quality outputs than cloud models. MultiMail's oversight modes are especially critical here — gated_send ensures every email is human-reviewed before delivery, catching issues that local models are more prone to.
Your prompts and reasoning stay on your machine with Ollama. Only the final email content is sent through MultiMail's API, creating a hybrid architecture that minimizes data exposure while providing full email capabilities.
Ollama provides an OpenAI-compatible API, so you can use the same tool calling patterns as cloud providers. Define MultiMail email tools once and they work with any local model that supports function calling.
Running models locally with Ollama means no per-token costs. Combined with MultiMail's free Starter tier (200 emails/month), you can prototype email agents with zero running costs.
Start with gated_all (human approves every action) for untested local models, then move to gated_send as you validate quality. MultiMail's five oversight modes let you safely experiment with different models.
import ollama
import requests
import json
MULTIMAIL_API = "https://api.multimail.dev/v1"
MM_HEADERS = {"Authorization": "Bearer mm_live_your_api_key"}
email_tools = [
{
"type": "function",
"function": {
"name": "send_email",
"description": "Send an email through MultiMail. 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"}
},
"required": ["mailbox_id"]
}
}
}
]Create tool definitions using Ollama's OpenAI-compatible function calling format.
def execute_tool(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 {"error": f"Unknown tool: {name}"}
return resp.json()
def run_local_email_agent(user_message, mailbox_id):
messages = [
{"role": "system", "content": f"You are an email assistant for mailbox {mailbox_id}. "
f"Emails use gated_send mode and queue for human approval."},
{"role": "user", "content": user_message}
]
while True:
response = ollama.chat(
model="llama3.3",
messages=messages,
tools=email_tools
)
msg = response["message"]
if msg.get("tool_calls"):
messages.append(msg)
for tc in msg["tool_calls"]:
result = execute_tool(
tc["function"]["name"],
tc["function"]["arguments"]
)
messages.append({
"role": "tool",
"content": json.dumps(result)
})
else:
return msg["content"]
print(run_local_email_agent("Check my inbox", "mbx_abc123"))Create an agentic loop using Ollama's chat API with MultiMail tools.
from openai import OpenAI
import json
"cm"># Point OpenAI client at Ollama's local server
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama" "cm"># Ollama doesn't require a real key
)
email_functions = [
{
"type": "function",
"function": {
"name": "send_email",
"description": "Send an email. Queues for human approval in gated_send mode.",
"parameters": {
"type": "object",
"properties": {
"mailbox_id": {"type": "string"},
"to": {"type": "string"},
"subject": {"type": "string"},
"body": {"type": "string"}
},
"required": ["mailbox_id", "to", "subject", "body"]
}
}
}
]
"cm"># Same code as OpenAI, running locally
response = client.chat.completions.create(
model="llama3.3",
messages=[
{"role": "system", "content": "Email assistant. gated_send mode."},
{"role": "user", "content": "Draft an email to [email protected] about the meeting"}
],
tools=email_functions
)
if response.choices[0].message.tool_calls:
tc = response.choices[0].message.tool_calls[0]
args = json.loads(tc.function.arguments)
print(f"Would send to: {args[&"cm">#039;to']}")
print(f"Subject: {args[&"cm">#039;subject']}")Use the OpenAI Python SDK pointed at Ollama's local server for a familiar API experience.
Sign up at multimail.dev, create a mailbox, and generate an API key from your dashboard. Your key will start with mm_live_.
Install Ollama and download a model with tool calling support like Llama 3.3.
brew install ollama && ollama pull llama3.3Install the Ollama Python library and requests for calling the MultiMail API.
pip install ollama requestsDefine email tools and implement the agent loop using Ollama's chat API with tool calling.
response = ollama.chat(
model="llama3.3",
messages=messages,
tools=email_tools
)Review and approve pending emails in the MultiMail dashboard. This step is especially important with local models that may produce lower-quality outputs.
Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 38-tool MCP server. Formally verified in Lean 4.