mailflat-mcp
OfficialOne line: MailFlat MCP gives an AI assistant full control of permanent email inboxes over mailflat.net — create addresses, wait for OTPs and replies, send mail, and manage calendar invites.
Inbox management:
create_inbox(label, prefix, subdomain, custom domain, retention window),list_inboxes,burn_inbox(clear messages, keep address),delete_inbox(irreversible).Reading mail:
read_messagesnewest-first, filtered by direction (in,out,all);mark_readso later polls skip a message;delete_message.Waiting for codes:
wait_for_otppolls until an OTP arrives, returning{otp_code, email}— one-line OTP retrieval for signup flows.Waiting for replies:
wait_for_messagepolls until new received mail arrives, ignoring your own outgoing mail.Sending:
send_email(to/cc/bcc/html, DKIM-signed, no attachments),replyto keep the same conversation with correct threading headers, andwait_until_sentto confirm queue delivery/failure bymessage_id.Calendar:
list_calendar_events,rsvp_to_invite(accepted/declined/tentative),create_calendar_event(attendees, timezone, all-day, location, optional attendees),update_calendar_event,cancel_calendar_event.Calendar subscriptions:
get_calendar_feedfor a stable read-only subscribe link (plus one-click links per app), androtate_calendar_feedif it leaks.
Practically: automate email signup/verification tests, agent-to-agent email threads, outbound automation, and meeting scheduling/RSVP workflows — all through one permanent address reused across runs.
MailFlat SDKs
Official client libraries for MailFlat: email inboxes your code owns, with one-line OTP retrieval. Built for test suites (Selenium, pytest, Playwright) and AI agents.
Addresses are permanent, so a suite does not need a fresh one per run. Only the messages expire, on a retention window you choose.
This repo holds only the open-source SDKs. The MailFlat service itself is closed-source.
Packages
Package | For | Install |
Python |
| |
JavaScript / TypeScript |
| |
AI assistants (Claude, Cursor) — MCP |
| |
Vercel AI SDK agents |
| |
| LangChain agents |
|
| Java / Selenium | via JitPack — see below |
Each client is a thin, typed wrapper over the same /api/v1 Agent API, so they behave identically.
Authenticate with your account key (mf_live_…) from the dashboard (Agents → API keys).
Related MCP server: useblip/email
Java / Selenium (JitPack)
JitPack derives the
groupIdfrom the GitHub owner. This repo moved to the officialMailFlataccount in August 2026, so releases fromv0.4.4on publish ascom.github.MailFlat:mailflat-sdks. Earlier versions still resolve under the old coordinatecom.github.onderyentar21:mailflat-sdks; the old repo stays up for them. The client is moving to Maven Central (net.mailflat) next, which ends the owner coupling.
<repositories>
<repository><id>jitpack.io</id><url>https://jitpack.io</url></repository>
</repositories>
<dependency>
<groupId>com.github.MailFlat</groupId>
<artifactId>mailflat-sdks</artifactId>
<version>v0.8.1</version>
</dependency>MailFlat mf = new MailFlat("mf_live_…");
Inbox inbox = mf.create("signup");
driver.findElement(By.id("email")).sendKeys(inbox.address());
String otp = inbox.waitForOtp(30); // polls until the code arrives
driver.findElement(By.id("code")).sendKeys(otp);Quick examples
Python
from mailflat import MailFlat
mf = MailFlat(api_key="mf_live_…")
inbox = mf.create(label="signup")
otp = inbox.wait_for_otp(timeout=30)JavaScript / TypeScript
import { MailFlat } from "@mailflat/sdk";
const mf = new MailFlat({ apiKey: process.env.MAILFLAT_API_KEY });
const inbox = await mf.create({ label: "signup" });
const otp = await inbox.waitForOtp({ timeout: 30000 });License
MIT. The full text is in LICENSE at the repository root; each package directory carries an identical copy.
Available Tools
19 toolsburn_inboxA
Delete every message in an inbox but KEEP the address.
Use between scenarios: the address stays registered wherever you already used it.
Inputs: address (required).
cancel_calendar_eventB
Cancel a meeting this inbox organized; it disappears from every attendee's calendar.
Inputs: address (required), event_id (required), message.
create_calendar_eventA
Schedule a meeting from this inbox and email the invitations (you are the organizer).
Attendees get a normal invitation with Yes / No / Maybe buttons in Gmail, Outlook or Apple
Calendar. Their answers show up in list_calendar_events under attendees[].status.
start: ISO 8601 with an offset ("2026-10-06T14:00:00-04:00"), or without one plus
timezone ("America/New_York"). Set end or duration_minutes (default 30 minutes).
For an all-day event set all_day=true and use dates ("2026-10-06"); end is exclusive.
message is a short note at the top of the invitation email. in_reply_to (a message's
Message-ID) threads the invitation under an email you already exchanged.
Call it ONCE per meeting: it emails every attendee. Normal send rules apply.
Inputs: start (required), title (required), address (required), attendees (required), +9 more.
create_inboxA
Open an email inbox and return its address. Use this when you need an address to sign up for a service or to receive a one-time code.
The address is permanent and stays until you delete it, so a test suite can reuse one address across runs instead of opening a new inbox each time. Only the messages inside expire, on the retention window you choose.
label needs a paid plan; on free it is reported back in ignored_fields.
retention_hours is optional (0 = your plan's max); requests above your plan are capped.
subdomain picks the part after the @ on mailflat.net (prefix@subdomain.mailflat.net);
it needs a paid plan and is random when omitted.
domain opens the inbox on a custom domain instead (prefix@acme.com). Pass it ONLY when
the user named a domain they have already verified on this account; never guess one. Leave
it empty and the address is created on mailflat.net. domain wins over subdomain.
Inputs: label, domain, prefix, subdomain, +1 more.
delete_inboxA
Delete an inbox and all its messages by address. Irreversible.
Inputs: address (required).
delete_messageA
Delete a single message in an inbox by its id (the inbox itself stays).
Inputs: address (required), message_id (required).
get_calendar_feedA
Read-only subscribe link for this inbox's calendar, to give to a human.
They add it in Google Calendar, Apple Calendar or Outlook and see this inbox's meetings
there, with attendees and their answers. Calling again returns the SAME link, so sharing
it twice never breaks a subscription. subscribe_links holds one-click add links per app.
Google refreshes subscribed calendars every 8 to 24 hours; for live state use
list_calendar_events.
Inputs: address (required).
list_calendar_eventsA
List the meetings on an inbox's calendar, soonest first.
Events come from calendar invitations this inbox received (Google Calendar, Outlook, ...).
Each has an id, title, start/end in UTC, organizer, attendees, status
("confirmed" or "cancelled") and my_status (this inbox's answer: "needs-action",
"accepted", "declined" or "tentative"). If the organizer moves a meeting, the event is
updated in place and my_status goes back to "needs-action". Messages that carry an
invitation also show it under calendar_event in read_messages.
Inputs: address (required), include_cancelled.
list_inboxesA
List all inboxes available to this API key.
Inputs: no named parameters.
mark_readA
Mark one message as read so later polls can skip it.
Inputs: address (required), message_id (required).
read_messagesA
Read messages in the given inbox address (newest first).
direction is "in" for received mail (default), "out" for mail sent from this
address, or "all" for both. Received mail is the default so that a reply you are
waiting for is not confused with a message you just sent.
Inputs: address (required), direction.
replyA
Reply to a message so it stays in the SAME conversation.
Prefer this over send_email when answering: it fills in the recipient, an Re: subject
and the threading headers. A plain send_email starts a new conversation in the
recipient's client, which does not look like a reply.
Inputs: address (required), message_id (required), cc, bcc, +2 more.
rotate_calendar_feedA
Replace this inbox's calendar subscribe link; the old link stops working at once.
Use only when the link leaked. Everyone subscribed has to add the new link.
Inputs: address (required).
rsvp_to_inviteA
Answer a calendar invitation: response is "accepted", "declined" or "tentative".
Sends a standard calendar reply email to the organizer, so their Google or Outlook
calendar shows your answer. event_id comes from list_calendar_events (or
calendar_event.event_id on a message). Call it ONCE per answer: the reply is queued like
any email; use wait_until_sent with the returned message_id to confirm delivery.
Inputs: address (required), event_id (required), response (required), comment.
send_emailA
Send an email FROM the given inbox address (DKIM-signed via MailFlat's MTA).
Use for replies or outbound automation. html is optional.
Returns once the mail is ACCEPTED for delivery, not once it is delivered: delivery runs on a queue and the result arrives via webhook or by reading the message back.
cc addresses appear in the mail's headers; bcc addresses never do — not even in
their own copy. Attachments are not available here; send those from the SDK.
Inputs: to (required), address (required), cc, bcc, +3 more.
update_calendar_eventA
Change a meeting this inbox organized; attendees get the updated invitation.
Pass only what changes (empty = unchanged). Moving start keeps the duration. A new
time resets every attendee's answer to "needs-action" (they are asked again). The same
event is updated in their calendars, no duplicate. Invitations you RECEIVED cannot be
changed here; answer those with rsvp_to_invite.
Inputs: address (required), event_id (required), end, start, +6 more.
wait_for_messageA
Poll the inbox until a new message ARRIVES (or timeout). Returns {email}.
Only received mail counts, so you can send to a peer and then wait for their reply without matching your own outgoing message.
Inputs: address (required), timeout.
wait_for_otpA
Poll the inbox until an OTP code arrives (or timeout). Returns {otp_code, email}.
Inputs: address (required), timeout.
wait_until_sentA
Find out whether a mail you sent was actually delivered.
send_email only means "accepted for delivery"; the mail goes out later on a queue. Call this with the message_id send_email returned to learn the outcome.
Returns delivered: true once it went out. If it is still queued when the timeout
elapses you get timed_out: true with delivered: false — that is NOT a failure and
you must NOT send the mail again; the queue is still retrying. status tells you
whether it has been attempted yet (queued) or attempted and rescheduled (retrying),
and error carries what the last attempt reported. Permanent failure comes back the
same way, as status: failed with the reason in error — read note before you
resend anything.
Inputs: address (required), message_id (required), timeout.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 19 tools
Each tool targets a distinct resource/action: inbox lifecycle, message lifecycle, sending/waiting, and calendar event lifecycle are cleanly separated. The only close pair, send_email and reply, is explicitly differentiated in the descriptions.
Almost all tools use consistent snake_case with an action_resource/entity pattern. A few names like reply and wait_until_sent are verb-only phrases, but they remain readable and snake_case throughout.
19 tools is slightly heavy for the typical 3-15 sweet spot, but the server spans two domains (email inbox and calendar) so most tools are justified. No tool appears obviously redundant.
The surface covers most email inbox and calendar workflows: create/list/delete inboxes, read/mark/delete messages, send/reply/wait, and calendar create/list/update/cancel/rsvp/feed. Minor gaps exist, such as no explicit message update and attachment sending being delegated to the SDK.
Maintenance
Related MCP Connectors
Real email inboxes for AI agents: register, receive, read and send mail over MCP. Free to receive.
Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.
MCP server for e-mail testing: create disposable inboxes, wait for delivery, and extract e-mail content or links - all from your AI agent or test automation workflow. Get a free API key on https://app.zyntra.app/
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Related MCP Servers
- AlicenseBqualityDmaintenanceDisposable email MCP server for autonomous AI agents. Create labeled temporary inboxes, wait for verification emails, extract OTP codes and confirmation links — zero human intervention required.632 PyPIMIT
- AlicenseAqualityBmaintenanceMCP server for disposable email — create inboxes, receive emails, and extract OTP codes. Let your AI agent sign up for services, wait for verification emails, and extract codes autonomously.751 npm1MIT
- AlicenseNot gradedqualityBmaintenanceOpen-source, self-hosted Inbox-as-a-Service API for AI agents. It enables agents to manage email inboxes, send/receive emails, search messages, and wait for replies via REST or MCP.30Apache 2.0
- AlicenseAqualityBmaintenanceMCP server that gives an AI agent a throwaway test identity — a real disposable email address and a real UK phone number — so it can sign up for something it's testing and read back the verification email/SMS itself, without a human in the loop.580 npmMIT