Tools¶
Apple Mail MCP provides 6 MCP tools — a consolidated API designed for AI assistants.
Overview¶
| Tool | Purpose | Parameters |
|---|---|---|
list_accounts() |
List email accounts | — |
list_mailboxes() |
List mailboxes | account? |
get_emails() |
Get emails with filtering | account?, mailbox?, filter?, limit? |
get_email() |
Get single email with content + attachments | message_id, account?, mailbox? |
search() |
Search emails | query, account?, mailbox?, scope?, limit?, exclude_mailboxes? |
get_attachment() |
Extract attachment content | message_id, filename, account?, mailbox? |
list_accounts()¶
List all configured email accounts in Apple Mail.
Parameters: None
Returns: List of accounts with name and id fields.
list_mailboxes()¶
List all mailboxes for an email account.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
account |
string? |
env default | Account name |
Returns: List of mailboxes with name and unreadCount fields.
list_mailboxes()
# → [{"name": "INBOX", "unreadCount": 5}, {"name": "Sent", "unreadCount": 0}]
list_mailboxes("Work")
# → [{"name": "INBOX", "unreadCount": 12}, ...]
get_emails()¶
Get emails from a mailbox with optional filtering. This is the primary tool for listing emails.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
account |
string? |
env default | Account name |
mailbox |
string? |
INBOX |
Mailbox name |
filter |
string? |
all |
Filter type (see below) |
limit |
int? |
50 |
Max emails to return |
Filters:
| Filter | Description |
|---|---|
all |
All emails (default) |
unread |
Only unread emails |
flagged |
Only flagged emails |
today |
Emails received today |
this_week |
Emails from the last 7 days |
Returns: List of email summaries sorted by date (newest first), each with: id, subject, sender, date_received, read, flagged.
get_emails()
# All emails from default mailbox
get_emails(filter="unread", limit=10)
# 10 most recent unread emails
get_emails("Work", "INBOX", filter="today")
# Today's work emails
get_email()¶
Get a single email with full content. Uses a 3-strategy cascade to find the message:
- Try the specified mailbox directly
- Look up the email's location in the FTS5 index
- Iterate all mailboxes with per-mailbox error handling
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
message_id |
int |
required | Email ID (from list/search results) |
account |
string? |
env default | Helps find the message faster |
mailbox |
string? |
INBOX |
Helps find the message faster |
Returns: Full email with: id, subject, sender, content (full body text), date_received, date_sent, read, flagged, reply_to, message_id (RFC 822 Message-ID header), attachments (list of {filename, mime_type, size}).
get_email(12345)
# → {"id": 12345, "subject": "Meeting notes", "content": "Hi team,...",
# "attachments": [{"filename": "notes.pdf", "mime_type": "application/pdf", "size": 52340}], ...}
Tip
If account and mailbox are not provided, the server searches all mailboxes in the default account to find the message.
Note
The attachments list comes from JXA and only reports file attachments visible in Mail.app's UI. For reliable extraction (including inline images), use get_attachment().
search()¶
Search emails with automatic FTS5 optimization. Uses the FTS5 index for fast search (~2ms) when available, falls back to JXA-based search otherwise.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
query |
string |
required | Search term or phrase |
account |
string? |
None |
Account filter. None = search all (FTS) or default (JXA) |
mailbox |
string? |
None |
Mailbox filter. None = search all (FTS) or default (JXA) |
scope |
string? |
all |
Search scope (see below) |
limit |
int? |
20 |
Max results |
exclude_mailboxes |
list? |
["Drafts"] |
Mailboxes to exclude (FTS/attachment scopes only) |
Scopes:
| Scope | Searches | Engine |
|---|---|---|
all |
Subject + sender + body | FTS5 (if indexed) |
subject |
Subject line only | JXA (single mailbox) |
sender |
Sender field only | JXA (single mailbox) |
body |
Body content only | FTS5 (if indexed) |
attachments |
Attachment filenames | SQL (requires index) |
Returns: List of results sorted by relevance (FTS5) or date (JXA fallback), each with: id, subject, sender, date_received, score, matched_in, and optionally content_snippet, account, mailbox.
search("invoice")
# Search everywhere — uses FTS5 for instant results
search("john@example.com", scope="sender")
# Find emails from a specific sender
search("meeting notes", scope="body")
# Search body content only
search("pdf", scope="attachments")
# Find emails with PDF attachments
search("deadline", limit=5)
# Top 5 results
get_attachment()¶
Extract attachment content from an email. Parses the raw .emlx MIME structure, so it works for all attachment types including inline images.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
message_id |
int |
required | Email ID |
filename |
string |
required | Attachment filename to extract |
account |
string? |
None |
Account (helps disambiguate) |
mailbox |
string? |
None |
Mailbox (helps disambiguate) |
Returns: Dictionary with filename, mime_type, size, and content_base64. If the attachment exceeds 10 MB, returns metadata only with truncated: true.
get_attachment(12345, "invoice.pdf")
# → {"filename": "invoice.pdf", "mime_type": "application/pdf",
# "size": 52340, "content_base64": "JVBERi0x..."}
Note
Requires the FTS5 search index. If upgrading from v0.1.2, run apple-mail-mcp rebuild to populate attachment metadata.