How to let Claude send and receive email
Claude can call tools, so the question is not whether it can send email but what you connect it to. This is the short path: an MCP email server, one block of config, and a Claude that can send, read threads, and wait for a reply on its own address. It works the same way for [ChatGPT](/with/gpt), the [Vercel AI SDK](/with/vercel-ai-sdk), [LangChain](/with/langchain), the [OpenAI Agents SDK](/with/openai-agents), [n8n](/with/n8n), and the [Cloudflare Agents SDK](/with/cloudflare-agents); the config block is the only thing that changes.
5 min read
What you need first
An address the agent owns. Not your Gmail password, not an app-specific password on a shared mailbox: an identity with its own key, so that what Claude may do is scoped and revocable. Sign up, pick a handle, and you get a working address on a mcpmailer.email subdomain immediately, before you touch DNS. Moving to your own domain later is a handful of DNS records, covered in domains.
Why not just hand over IMAP credentials to an inbox you already have? Because a mail password grants everything to everyone who holds it, and because Claude then has to parse MIME, reassemble threads from headers, and strip quoted history before it can answer anything. The comparison is worked through in agent inbox or shared mailbox.
The config
Add the MCP server to your Claude client. The endpoint speaks Streamable HTTP, and the key is a bearer token scoped to one agent identity.
{
"mcpServers": {
"mcpmailer": {
"type": "http",
"url": "https://connect.mcpmailer.com/mcp",
"headers": { "Authorization": "Bearer mmk_live_..." }
}
}
}Restart the client and the mail tools appear next to whatever else Claude has. There is nothing to install and no adapter to write, which is the whole point of an MCP email server.
If your client cannot hold a static key, authorize over OAuth 2.1 instead. Discovery, PKCE, and the resource audience requirements are in OAuth. One detail catches people: an OAuth token identifies a person, so if you own several agents you must say which one you are acting as with an X-MCPmailer-Agent header, otherwise the call is refused as ambiguous rather than guessed at.
The first send
Ask Claude to email you. It will call send_email, and the tool returns a message id rather than a cheerful confirmation, because an id is what the next call needs.
send_email {
to: ["you@yourcompany.com"],
subject: "First message from an agent",
body: "This came from Claude. Reply and I will read the thread."
}Bodies are markdown and are delivered as both plain text and HTML, so headings and lists survive into a normal-looking email. Attachments go as base64 through the same call, and there is a hard cap of five recipients per message: this is not a bulk sending tool, deliberately.
Holding an actual conversation
The tool that changes what is possible is wait_for_reply. Claude sends, then blocks server-side until the reply arrives or the timeout expires, and continues with the answer in hand. No polling loop, no cron job, no session burning tokens while it waits.
send_email { to: ["anna@customer.com"], subject: "Quote", body: "..." }
wait_for_reply { thread_id: "thr_...", timeout_seconds: 86400 }
reply_all { message_id: "msg_...", body: "Great, I will send the contract today." }Everything else you would expect is there: get_thread for the whole conversation, search_inbox with quoted phrases and exclusions, lookup_contact for who this person is and what previous runs recorded about them, archive_message for keeping the inbox useful. The full list with arguments is in the tools reference, and the same capabilities are available over REST if part of your stack does not speak MCP.
Limits worth knowing before you point it at customers
- Five recipients per message. Bulk email is a different product and this is not it.
- 300 requests per minute per key, across MCP and REST. A 429 carries retry-after in seconds; wait it out rather than retrying harder.
- Replies and cold sends share one daily allowance, and cold sends are watched more closely. First contact with a new address carries an unsubscribe link and is subject to the duplicate-content and velocity tripwires. The reasoning is in keeping an autonomous agent from becoming a spam problem.
- Refusals are readable. A rejected send returns a reason such as
daily_send_quota_exhaustedwith a reset time, so Claude can decide to wait, ask you, or do something else. Write your prompt so it treats a refusal as information rather than as an error to retry. - Scope is per identity. One key, one agent. It cannot read another agent's mail, notes, or vault secrets unless you grant it.
From a laptop to something that runs
A Claude desktop client with an inbox is a great way to try the idea. For anything that has to answer mail while you are asleep, you want the agent running somewhere persistent, reacting to a message.received webhook rather than to you opening a window. The SDKs cover TypeScript and Python, and the Agents SDK page covers running one as a Durable Object on Cloudflare.
If your stack is OpenAI tooling rather than Claude, the same two paths are in giving an OpenAI-based agent an email address. The use case pages are the fastest way to see what people build with this: customer support, sales, recruiting, invoice chasing, and scheduling.
Questions
- Can Claude send email?
- Yes, once you connect it to an email tool server. With MCPmailer that is one MCP config block pointing at the endpoint with a scoped bearer key, and Claude gains send, read, thread, search, and wait-for-reply tools.
- Can Claude read my Gmail instead?
- You would be handing a model credentials to a mailbox shared with people, with no per-agent scope and no clean audit of what it sent. A dedicated agent identity is safer, and the agent reads structured threads instead of raw MIME. See agent inbox or shared mailbox.
- Do I need my own domain?
- No. A workspace gets a working subdomain immediately, so you can run the whole flow before touching DNS, and move to your own domain when you are ready.
- How does Claude wait for a reply that takes hours?
wait_for_replyblocks server-side and returns when the reply lands or the timeout expires. There is no polling loop and no external scheduler.- What stops it from emailing hundreds of people?
- Structural limits rather than instructions: five recipients per message, per-key rate limits, a daily and monthly send allowance, and duplicate-content and velocity tripwires on cold sends. A refused send returns a reason the agent can act on.
Give your agent an address it can answer from.
Create an inbox