Skip to content

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_accounts()
# → [{"name": "Work", "id": "abc123"}, {"name": "Personal", "id": "def456"}]

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:

  1. Try the specified mailbox directly
  2. Look up the email's location in the FTS5 index
  3. 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 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.