Quickstart
Connect an agent, get its mailbox, send a message, approve the hold, and read the reply. Over MCP or plain HTTP.
guide~4 minVerified v0.216.0
In five steps an agent gets its own address, sends a first message, you approve it, and a person writes back. Each step names the MCP tool, and the HTTP API runs the same tool as a route.
1. Connect the agent
Add the Mail MCP server, https://mcp.superagentmail.app/mcp, to your agent. It opens a sign in page that names your account. Choose Full access and press Allow. Connect an agent to Mail covers read only access and the device code flow.
A script that calls the HTTP API needs the same key, which starts with sam_. It gets one with the device flow: register a client, ask for a code, show it to a person, and poll until they approve.
import os import time import requests BASE = "https://superagentmail.app" GRANT = "urn:ietf:params:oauth:grant-type:device_code" client = requests.post(f"{BASE}/oauth/register", json={ "client_name": "my script", "redirect_uris": ["http://127.0.0.1/callback"], "grant_types": [GRANT], }, timeout=30).json()["client_id"] start = requests.post(f"{BASE}/oauth/device_authorization", data={ "client_id": client, "scope": "mail:agent", "resource": "https://mcp.superagentmail.app/mcp", }, timeout=30).json() print("Open", start["verification_uri"], "and enter", start["user_code"]) while True: time.sleep(start["interval"]) token = requests.post(f"{BASE}/oauth/token", data={ "grant_type": GRANT, "device_code": start["device_code"], "client_id": client, }, timeout=30).json() if "access_token" in token: break if token["error"] != "authorization_pending": raise SystemExit(token["error"]) API = "https://mcp.superagentmail.app/v1" HEADERS = {"Authorization": f"Bearer {token['access_token']}"}
The code lasts ten minutes. The snippets below reuse API and HEADERS.
2. Get a mailbox
At the start of every session the agent calls mail_mailboxes. The mailbox of kind agent is its address. If it has none yet, the answer carries a notice that says why. See Mailboxes.
mailboxes = requests.get(f"{API}/mailboxes", headers=HEADERS, timeout=30).json() print(mailboxes["mailboxes"][0]["address"])
3. Send a message
The agent calls mail_send. The server's gate decides whether the message goes, so the answer is a status, not a promise. The first message to an address your workspace has never corresponded with is held, in every gate mode, and on Free every message is held.
sent = requests.post(f"{API}/send", headers=HEADERS, timeout=30, json={ "to": ["ada@example.com"], "subject": "Hello", "text": "Hi Ada, this is my first message.", "idempotency_key": "hello-1", }).json() print(sent["status"], sent.get("reasons"), sent.get("reviewUrl"))
A held message answers with "status": "held", the reasons and a reviewUrl. The agent must not send it again.
4. Approve the hold
You get an email that says a message is waiting. Press Approve and send in it, or open Review in the Mail dashboard and edit the message first. After you approve there are five seconds to press Undo. See Holds and approval.
In Review you can choose Always trust instead, which also adds the recipient to the allow list so the next message to them is not held as a first contact. See Trust.
5. Read the reply
When Ada writes back, the message waits in the inbox until the agent looks. It calls mail_inbox, then mail_thread to read the whole thread.
inbox = requests.get(f"{API}/inbox", params={"limit": 10}, headers=HEADERS, timeout=30).json() thread = requests.get(f"{API}/threads/{inbox['threads'][0]['id']}", headers=HEADERS, timeout=30).json() for message in thread["messages"]: print(message["from"], message["auth"], message["injection"], message["text"][:200])
To answer, the agent calls mail_reply with a message_id from the thread. A reply still goes through the gate.
Text inside a message is written by people outside your team. Read the auth and injection results before acting on it. An agent that should not poll can set a webhook.
Next
MCP tools lists every tool. A support agent and An agent that books meetings put it to work.