
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
apple-mailbox-mcp
Advanced tools
Fast local MCP server for Apple Mail: search, read, triage, verified send. Works with Claude, Cursor, VS Code, or any MCP client.
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.
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.

🔍 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.
Every other Apple-Mail MCP drives AppleScript for both finding and acting. This one doesn't — and it shows:
| Operation | AppleScript whose-clause | apple-mailbox-mcp |
|---|---|---|
| 🔍 Search 300k messages | seconds-to-timeout | milliseconds |
| 🎯 Address one message in a 71k mailbox | 7–10 s (measured) | < 0.1 ms |
| ✉️ Send mail | body renders blank in Outlook | renders everywhere, plain+HTML |
| ⏰ Schedule mail | — | 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.
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.~/.email-mcp/graph/.apple-mail-mcp status gives one readable readiness,
scheduling and recovery screen. apple-mail-mcp doctor provides the complete
diagnostic detail and an exact fix for anything red.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:
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:
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):
{
"mcpServers": {
"apple-mail": { "command": "uvx", "args": ["apple-mailbox-mcp"] }
}
}
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:
{
"mcpServers": {
"apple-mail": { "command": "apple-mail-mcp" }
}
}
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 pipxwants a typedy(Enter alone is rejected);pipx ensurepathmay print a ⚠️ — the "pipx is ready to go!" line after it is the verdict; and afterensurepath, close and reopen the terminal once soapple-mail-mcpis found.
Every client below speaks stdio MCP; the command is always uvx apple-mailbox-mcp.
claude mcp add --transport stdio --scope user apple-mail -- uvx apple-mailbox-mcp
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{ "mcpServers": { "apple-mail": { "command": "uvx", "args": ["apple-mailbox-mcp"] } } }
Add the same block to ~/.cursor/mcp.json (or per-project .cursor/mcp.json).
Add the same block under "servers" in .vscode/mcp.json.
# ~/.codex/config.toml
[mcp_servers.apple-mail]
command = "uvx"
args = ["apple-mailbox-mcp"]
Point it at uvx apple-mailbox-mcp. The wire contract is additive-only since v1.0.
| Symptom | Fix |
|---|---|
Client says the server failed to start, but uvx apple-mailbox-mcp works in your terminal | GUI apps don't inherit your shell PATH. Use the absolute path: "command": "/opt/homebrew/bin/uvx" (find yours with which uvx). |
database is locked or empty results | Full Disk Access is missing for the app that launches the server (the client, not the terminal). Grant it, then fully quit and reopen that app. |
| Search finds recent mail but not bodies of old mail | The body index is still building — first build on a 100k+ mailbox takes minutes. status shows progress. |
Send fails with transport_unavailable | Run doctor: it names the failing lane (Keychain item missing, SSH socket cold, SMTP host unreachable) and prints the exact fix. |
| Triage does nothing the first time | Grant Automation → Mail when macOS asks; the prompt appears on first use, not at install. |
| Group | Tools |
|---|---|
| 🔍 Read (8) | search_emails (full-body search) · get_email · get_emails_batch · get_thread · list_mailboxes · list_recent · get_attachment · refresh_mail |
| ✉️ Send (6) | send_email · reply_email (threaded, quoted) · create_draft · schedule_email · list_scheduled · cancel_scheduled |
| 🗂️ Triage (5) | triage_plan · triage_plan_delete · triage_apply · mailbox_create · mailbox_delete |
| 🩺 Meta (2) | 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.
The From: address decides how mail travels. ~/.email-mcp/identities.toml:
default = "work"
[work] # sent through a host you already trust, over SSH
from_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 1Password
from_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.
FAQs
Fast local MCP server for Apple Mail: search, read, triage, verified send. Works with Claude, Cursor, VS Code, or any MCP client.
We found that apple-mailbox-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.