apple-mail-mcp is an MCP server that runs locally on macOS to operate Apple Mail for agent clients. It opens the Mail store read-only, returns only what a client asks for, and sends email only when the client explicitly calls the send tool, without third-party relay or cloud copying of mail.
π οΈ Key Features
Local operation on your Mac (macOS)
Read-only access to the Apple Mail store
Indexed search
Full-text email bodies
Verified sending
Triage support
π Use Cases
Searching emails quickly
Reading full email content
Email triage workflows
Delegating email tasks to MCP-capable clients
β‘ Developer Benefits
Works with local MCP clients such as Claude Code, Claude Desktop, Codex, Cursor, and VS Code
Tool-driven workflow: fetches requested content and sends only via the explicit send tool
No third-party relay and no cloud copy of mail
β οΈ Limitations
Designed to send only when the client explicitly calls the send tool
Runs locally on your Mac. It opens the Mail store read-only, returns only
what a client asks for, and sends only when the client explicitly calls the
send tool. No third-party relay, no cloud copy of your mail.
code
uvx apple-mailbox-mcp setup
Measured on a 300k-message store: addressing one message 0.1 ms via Mail's own
index, against 7 to 10 s for the AppleScript whose-clause; full-text search
p95 under 1 ms. Method and script: docs/benchmarks.md.
Use Claude Code, Claude Desktop, Codex, Cursor, VS Code, or any local MCP client to search,
read, triage, and send email through Apple Mail β your mailbox becomes
something you can
ask, search and delegate to β find anything in seconds, file hundreds of
messages through a reviewed plan, send polished mail as the right identity,
and let Exchange deliver scheduled messages even while your Mac is asleep.
demo: uvx install, status, and a Claude search over a 298k-message store
β¨ What you can do
π Ask your mailbox questions."What did Maria send me about the memo
last week?" Search runs at database speed β sender, mailbox, dates, unread,
attachments β and reconstructs whole conversations.
π³οΈ Find what Mail itself can't. Mail's built-in search only skims the
first line of most messages. apple-mail-mcp indexes every message body on your
Mac β and for Exchange accounts it even fetches the bodies Mail never
downloaded, straight from your own mailbox on the server. Queries that
returned nothing return twenty.
π Send as the right you. Work mail through the work lane, personal
through Gmail β one parameter picks the identity. Every message is composed
from scratch as clean, standards-correct email that renders everywhere,
including Outlook (the AppleScript compose path that arrives blank in
Outlook is the reason this project exists).
β° Schedule like "Send Later", but scriptable. A scheduled message is
frozen in full β attachments, identity, exact text. Exchange can execute it
server-side at the requested time, lid closed; other providers use a local
background sender and deliver on its next pass (or just after the Mac wakes).
ποΈ Triage at scale, without fear."File these 40 newsletters" becomes a
reviewable plan: nothing moves until it is approved, every message is
re-checked before it is touched, and the result is verified against Mail's
own records afterward. Delete means Mail's Trash β nothing is ever erased.
π Draft where your drafts live. Compose into your real Exchange Drafts
folder, ready to open in Outlook or OWA β created, never auto-sent.
β‘ Why it's different
Every other Apple-Mail MCP drives AppleScript for both finding and acting.
This one doesn't β and it shows:
server-side on Exchange; reliable local queue everywhere else
ποΈ Bulk triage
one call per message, fire-and-forget
one reviewed plan, one apply, verified
Every number above was measured on a live ~300,000-message store; the
script and full method are in docs/benchmarks.md.
If the benchmarks hold up on your mailbox, a β helps others find this.
π‘οΈ Built to be trusted
β Plan β review β apply β verify. Bulk actions are frozen into a plan
you can read before anything happens; the outcome is confirmed against
Mail's own store afterward β never assumed.
ποΈ Nothing is ever erased. "Delete" files into Mail's Trash, and
destructive plans have their own separate, capped door.
π Read-only mail mode. Set EMAIL_MCP_READ_ONLY=1 and only the 11
non-mutating mail tools exist in the session. Search may still maintain its
local body index, and attachment retrieval writes the requested file to the
configured temporary directory.
πΎ A crash-safe scheduled queue. Manifest updates are flushed and
atomically replaced, so an interrupted rewrite keeps the last valid record.
If a file is damaged independently, diagnostics name it instead of claiming
the queue is empty, while healthy scheduled messages keep moving.
π§Ύ A local, best-effort activity ledger. Sends, schedules,
cancellations and triage runs are recorded without making an unwritable log
block mail. For reconciliation, the message itself, its Message-ID and its
scheduled record remain authoritative.
π No third-party mail relay. Mail content stays local except for mail
you send and optional access to your own provider for Exchange/IMAP body
backfill, drafts and server-side scheduling. SMTP passwords stay in the
macOS Keychain or 1Password; Microsoft OAuth tokens live in a private 0600
cache under ~/.email-mcp/graph/.
π A written contract. Since v1.0 every tool's shapes, error codes and
caps evolve additively, held in place by 800+ automated tests.
π€ Clear to every MCP client. All 21 tools identify what they do, explain
every input, and declare whether they read, change or can remove data. Newer
clients receive structured results; older clients keep the same JSON text.
Both the maintained MCP 1.x line and current MCP 2.x are tested.
π§± Built to evolve without breaking your workflow. Email rules are
isolated from MCP, Mail.app, Exchange, delivery, and local storage. Provider
or SDK changes stay at the edge while the 21-tool contract remains stable.
The dependency rules are enforced in CI and explained in the
architecture guide.
π¦ Releases you can verify. Every tagged release is built and installed
in a clean environment before publishing. GitHub includes the wheel, source
archive, SHA-256 checksums and signed build provenanceβnot just source code.
Grant Full Disk Access to your terminal app
(System Settings β Privacy & Security β Full Disk Access), then quit and
reopen the terminal. This is Apple's one manual toggle β there is no
pop-up for it.
Install and set up:
bash
uvx apple-mailbox-mcp setup # or: pipx install apple-mailbox-mcp# or via Homebrew:
brew install parasxos/tap/apple-mail-mcp && apple-mail-mcp setup
Register with your client β one line for Claude Code:
bash
claude mcp add --transport stdio --scope user apple-mail -- uvx apple-mailbox-mcp
or the same JSON block for Claude Desktop / Cursor / VS Code
(claude_desktop_config.json / .cursor/mcp.json / .vscode/mcp.json):
Verify:uvx apple-mailbox-mcp status prints one readiness screen β
or just ask your client to run the doctor tool; every red line comes
with its exact fix. The first body-index build on a large mailbox runs in
the background and can take a few minutes; search works immediately and
completes as the index fills.
Before running setup, grant your terminal app Full Disk Access
(System Settings β Privacy & Security β Full Disk Access) β that is how
reading stays fast and local. There is no pop-up for this one; it is Apple's
one manual toggle, and setup walks you to the exact pane if it finds it
missing.
setup asks everything in plain words (bare Enter accepts the recommended
answer), offers a sending identity, builds the body-search index, verifies
the nightly refresh actually runs, and ends by printing the one block you
paste into your MCP client:
Setup ends with a clear ready verdict or numbered recovery steps. Grant
Automation β Mail when triage first asks for it. Check the installation,
the next scheduled message, and failed scheduled sends anytime with
apple-mail-mcp status; use apple-mail-mcp doctor for the full technical detail.
π‘ New to the terminal? Three things that look wrong and aren't:
brew install pipx wants a typed y (Enter alone is rejected);
pipx ensurepath may print a β οΈ β the "pipx is ready to go!" line after it
is the verdict; and after ensurepath, close and reopen the terminal once
so apple-mail-mcp is found.
π Works with
Every client below speaks stdio MCP; the command is always uvx apple-mailbox-mcp.
Claude Code
bash
claude mcp add --transport stdio --scope user apple-mail -- uvx apple-mailbox-mcp
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
doctor (full diagnostics with fix-it strings) Β· audit (the local ledger)
Attachments both ways, size-budgeted. Replies thread correctly in every
client. Scheduling survives sleep β a message due while the lid was closed
goes out on the first tick after wake, or exactly on time via Exchange.
π Your addresses, your lanes
The From: address decides how mail travels. ~/.email-mcp/identities.toml:
toml
default = "work"[work]# sent through a host you already trust, over SSHfrom_addr = "you@example.org"driver = "ssh_sendmail"host = "bastion.example.org"# any login host you already SSH to[gmail]# classic SMTP β the app password stays in 1Passwordfrom_addr = "you@gmail.com"driver = "smtp"host = "smtp.gmail.com"op = "op://Personal/gmail app password/password"
Exchange identities can add one sign-in to unlock the extras: drafts filed in
your real Drafts folder, and scheduled sends executed by the server itself β
lid closed, Mac asleep. setup offers it in one plain question. Reading
needs no sending configuration at all.
21 tools Β· 926 tests Β· additive wire contract since v1.0
Live-calibrated end-to-end on a 305k-message store.
Built for one Mac β and for anyone else whose Mac runs Mail.app.