MCP reference
Reference · v0.1.0
Mailerati is a plug-and-play email MCP server built for AI agents. One URL gives your agent a real email address it can send and receive from, and gives you a console to watch it. The reference below covers connect, activate, and the seven tools.
Connect
The connection URL is the only thing your agent needs. It looks like this:
https://mcp.mailerati.com/mcp/<token>
Get a real one from the homepage. The token is generated server-side; you never type it.
Paste it into your client as a streamable-HTTP MCP server. For Claude Desktop, Cursor, or any client that takes a JSON config, the block is:
{
"mcpServers": {
"mailerati": {
"url": "https://mcp.mailerati.com/mcp/<token>"
}
}
}
A URL that's never used expires after 24 hours. Once the agent connects, the URL keeps working until you rotate it in the console.
Activate
A fresh inbox exposes two tools: activate and verify. The agent asks its human owner for an email address and calls activate with it. The five mailbox verbs unlock immediately, and a six-digit verification code is emailed to the owner at the same moment. The agent asks the owner for the six digits and calls verify with them, or the owner enters the code at mailerati.com/activate to claim the inbox and lift the unclaimed send limits. Once the inbox is claimed, activate and verify drop off the menu and only the five mailbox verbs remain. Until then, the inbox still works, just leashed to a tight cap.
Tools
Seven tools, in the order an agent meets them. Every tool returns JSON. The send tools also return an inbox object with the current state of the world, so the agent is never blind after acting.
activate
Unlock the inbox by giving it the human owner's email. First call wins; later calls are idempotent success. The first successful call also emails the owner a six-digit code. The agent asks the owner for the six digits and calls verify with them, or the owner enters the code at mailerati.com/activate to claim the inbox and lift the unclaimed send limits.
Arguments
{
"email": "owner@example.com"
}
Returns
{
"activated": true,
"codeSent": true,
"note": "Unlocked: get_status, read_email, reply_to_email, draft_new_email, ask_user_question. A verification code was emailed to the owner. Ask them for the six digits and call verify with them, or tell them to enter it at mailerati.com/activate. Claiming lifts the unclaimed send limits. If the tools are not in your list yet, request tools/list again (or reconnect), the list changes on activation and a stateless server cannot push it."
}
get_status
The one parameterless discovery call for the idle agent. Returns what needs attention and advances the cursor, so the next call shows only what landed since this one.
Arguments
{}
Returns
{
"waiting": [
{ "thread": "t_abc123", "from": "client@acme.com", "subject": "Re: the proposal" }
],
"new_answers": [
{ "thread": "t_def456", "from": "owner@example.com", "answer": "yes, ship it" }
],
"open_asks": [
{ "thread": "t_def456", "question": "Should I ship the proposal as-is?" }
],
"held_outcomes": [
{ "thread": "t_ghi789", "to": "vendor@acme.com", "outcome": "released" }
]
}
waiting is new mail the agent has not seen. new_answers are owner replies to the agent's questions. open_asks are questions still waiting on the owner. held_outcomes are verdicts on sends the agent held for approval.
read_email
Read a thread: the full messages in it, in order. Use a thread id from get_status.
Arguments
{
"thread": "t_abc123"
}
Returns
{
"thread": "t_abc123",
"messages": [
{ "from": "client@acme.com", "subject": "Re: the proposal", "body": "Looks good. One change: ..." },
{ "from": "agent@mailerati.email", "to": "client@acme.com", "subject": "the proposal", "body": "Here is the draft." }
],
"inbox": { "waiting": [], "new_answers": [], "open_asks": [], "held_outcomes": [] }
}
reply_to_email
Send an email. Pass thread if this is a reply, so it joins the conversation. If the inbox is in Auto-Quarantine, the send is held for the owner to approve instead of going out.
Arguments
{
"to": "client@acme.com",
"subject": "Re: the proposal",
"body": "Got it. Shipping now.",
"thread": "t_abc123"
}
Returns (sent)
{
"sent": true,
"thread": "t_abc123",
"messageId": "20260904...@mailerati.email",
"inbox": { "waiting": [], "new_answers": [], "open_asks": [], "held_outcomes": [] }
}
Returns (held, Auto-Quarantine on)
{
"held": true,
"thread": "t_abc123",
"note": "Auto-Quarantine is on for this mailbox: the send is held for your owner to approve at mailerati.com/console. It has not gone out. Call get_status later to learn what happened to it.",
"inbox": { "waiting": [], "new_answers": [], "open_asks": [], "held_outcomes": [] }
}
A held send returns success, not an error, so the agent does not retry. The owner releases or denies it in the console, and the verdict lands in held_outcomes on the next get_status. If the inbox is over its sending cap, the call throws with the reason instead.
draft_new_email
Hold a draft for a second opinion before it goes out. The draft is logged and returned for re-examination. Send it with reply_to_email after review.
Arguments
{
"to": "client@acme.com",
"subject": "the proposal",
"body": "Here is the draft.",
"reason": "first contact with a new client, want a human check",
"thread": "t_abc123"
}
Returns
{
"held": true,
"thread": "t_abc123",
"note": "Held for a second opinion. The draft is in the log. Review it, then send it with reply_to_email(to, subject, body, thread) when it is ready.",
"inbox": { "waiting": [], "new_answers": [], "open_asks": [], "held_outcomes": [] }
}
ask_user_question
Ask the owner a question. They answer by replying to the email, and the answer appears in the log. Pass thread if the question is about a specific conversation.
Arguments
{
"question": "Should I ship the proposal as-is?",
"thread": "t_abc123"
}
Returns
{
"asked": true,
"note": "the owner has been emailed. The answer arrives in the log, so call get_status to check for it.",
"inbox": { "waiting": [], "new_answers": [], "open_asks": [], "held_outcomes": [] }
}
verify
Submit the six-digit verification code that was emailed to the owner to claim the inbox and lift the unclaimed send limits. Ask the owner for the code, then call this with it.
Arguments
{
"code": "123456"
}
Returns
{
"claimed": true,
"inboxes": ["inbox-id-1"],
"note": "The inbox is claimed. The unclaimed send limits are lifted. Your owner can watch this mailbox at mailerati.com/console."
}
How it works
Stateless. The server holds no session. Every request resolves the token, does the work, appends to the log, and returns. The connection URL is the whole credential, and the inbox is created on the first call.
The cursor. get_status is the only call that advances the last-seen cursor. Every other tool returns the state of the world as a side channel without consuming it, so the agent never misses an owner reply by taking another action.
Send protection. Each inbox is either YOLO (the agent sends freely) or Auto-Quarantine (every outbound send is held for the owner to approve or deny in the console). The owner sets it per inbox. A held send returns success, not an error; the verdict reaches the agent through held_outcomes on the next get_status.
Quotas. The free plan includes 100 messages a month. Paid plans raise the limit.
Questions
Write hello@mailerati.com.