-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Unified Apple Mail MCP server — fast on-disk reads/search plus complete AppleScript writes, behind one safety layer. 31 MCP tools. Author: Ernesto Cobos. License: GPL-3.0-or-later.
This Wiki is the deep documentation; the README is the quickstart and pitch. CLAUDE.md is the fast-routing index for anyone (human or agent) working on the code itself.
uvx cobos-apple-mail-mcp serve # zero-install run (canonical MCP path)
# or: pipx install cobos-apple-mail-mcp (add [attachments] for PDF/DOCX text search)
apple-mail-mcp init && apple-mail-mcp index buildThen register apple-mail-mcp serve with your client — see
Install per client.
The install-to-first-run flow and the required macOS permissions (Full Disk Access + Automation)
are on Permissions and troubleshooting.
flowchart LR
A["1 · Install<br/>uvx / pipx / .pyz"] --> B["2 · Permissions<br/>Full Disk Access + Automation"]
B --> C["3 · init + index build"]
C --> D["4 · Register with<br/>your MCP client"]
D --> E["5 · Ask your agent<br/>about your inbox"]
classDef done fill:#3f9142,stroke:#245127,color:#fff
class A,B,C,D,E done
flowchart TB
Agent["MCP client / agent"] --> Tools["tools/*<br/>MCP tool surface"]
Tools --> Resolver["core/resolver.py<br/>id → live message"]
Resolver --> Identity["core/identity.py<br/>canonical Message-ID"]
Tools -->|reads| ReadPath["Read path<br/>direct-on-disk"]
Tools -->|writes| WritePath["Write path<br/>via guard()"]
subgraph Reads["Read path (never writes Mail)"]
direction TB
EnvReader["read/envelope_reader.py<br/>Envelope Index immutable=1"]
Emlx["read/emlx_parser.py<br/>.emlx from disk"]
Indexer["read/indexer.py + watcher.py"]
IndexDB[("index.db<br/>disposable, rebuildable")]
Search["read/search.py + vector_search.py<br/>FTS5 + hybrid"]
Threader["read/threader.py + knowledge/*<br/>JWZ threading + triage"]
EnvReader --> Indexer
Emlx --> Indexer
Indexer --> IndexDB
IndexDB --> Search
IndexDB --> Threader
end
subgraph Writes["Write path"]
direction TB
Guard["core/safety.py guard()<br/>read_only + batch caps + dry_run"]
Undo["core/undo.py<br/>journal + undo_last"]
JXA["write/jxa_executor.py<br/>osascript, timeout + kill"]
Guard --> JXA
Guard --> Undo
end
ReadPath --> Reads
WritePath --> Writes
JXA --> Mail["Mail.app<br/>AppleScript / JXA"]
Resolver -.verify id.-> JXA
High-level subsystem map: an MCP client hits tools/*, which resolve a canonical Message-ID via core/resolver.py and split into a direct-on-disk read path (Envelope Index and .emlx feeding the disposable index.db for search and threading) and a write path that always passes through core.safety.guard() before write/jxa_executor.py drives Mail.app.
- Architecture — the dual-path design, the diagram, the read→write flow, module map.
-
Apple Mail on-disk format — Envelope Index schema,
.emlx/.partial.emlxlayout, ROWID↔Message-ID mapping, Cocoa-epoch timestamps, version directories. -
Identity & resolution — the canonical-id design, the
resolver algorithm,
MultipleMatches, theresolve_cache. -
Safety, confirmation & undo —
guard(), batch caps, dry_run/confirm, the undo journal and its honest limits. -
Indexing and watch — the inventory-diff algorithm, crash-safe
bulk build, the
--watchloop, dead-letter handling, staleness. -
Search — the FTS5 schema, BM25 weights, scopes, the
SearchBackendseam, trigram, hybrid/semantic search. - Threading and knowledge — JWZ threading, the awaiting-reply/needs-response heuristics, analytics.
- Tools reference — every tool's parameters, output shape, and backend.
-
Resources and prompts-recipes — the
email://...resources and how to author/run a recipe. -
Configuration reference —
config.toml,APPLE_MAIL_*env vars, precedence, every setting. - Permissions and troubleshooting — Full Disk Access, Automation, common errors.
-
Single-file packaging — building and running
apple-mail-mcp.pyz. - Install per client — Claude Desktop/Cowork, Codex, Kimi, plus the MCP Inspector.
- Performance and benchmarks — methodology and numbers.
- Development and contributing — testing without a Mac, CI, release process.
The authoritative copy of this table lives in CLAUDE.md — it's the fast routing index used when working on the code; this Wiki is where each row's page actually lives.