apple-mail-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_accountsA | List all configured email accounts in Apple Mail. Returns each account's id (UUID), display name, email addresses, account type, and enabled state. Account ids are stable across name changes; prefer them over names for identifying accounts. Returns: Dictionary containing the accounts list. Example: >>> list_accounts() {"success": True, "accounts": [ {"id": "B21B254B-...", "name": "Gmail", "email_addresses": ["me@gmail.com"], "account_type": "imap", "enabled": True}, ... ]} |
| list_rulesA | List all Mail.app rules (read-only). Returns each rule's display name and enabled state. Rule names are NOT guaranteed unique — Mail allows duplicates — and rules have no stable id via AppleScript. This tool is read-only; mutation (enable/disable, create, delete) is tracked as a separate enhancement. Returns: Dictionary containing the rules list. Example: >>> list_rules() {"success": True, "rules": [ {"name": "Junk filter", "enabled": True}, {"name": "News From Apple", "enabled": False}, ... ], "count": 2} |
| delete_ruleA | Delete a Mail.app rule by 1-based positional index. Destructive — requires user confirmation via MCP elicitation before running. Cannot be undone (Mail.app does not version rule history). |
| create_ruleA | Create a new Mail.app rule. Additive — no confirmation prompt. Mail.app appends new rules to the
end of the rule list, so the returned |
| update_ruleA | Update an existing Mail.app rule (patch semantics). Patch semantics: only fields you provide are changed. Conditional confirmation: prompts the user via MCP elicitation only when
the patch touches Refuses to update any rule whose existing actions include something outside the supported schema (run-AppleScript, redirect, reply text, play sound, custom highlight color); raises MailUnsupportedRuleActionError. Edit such rules in Mail.app's UI. |
| list_mailboxesA | List all mailboxes for an account. |
| search_messagesA | Search for messages matching criteria. Returns metadata-only rows. Two corpus modes:
For thread retrieval, call |
| get_messagesA | Get full details of one or more messages, with bodies. Returns a list of message dicts (possibly of length 0 or 1). Pair with
|
| update_messageA | Update one or more messages: change read state, flag, and/or move, in one atomic call (#135). Patch semantics — caller specifies only the fields to change. All
specified mutations apply in a single AppleScript pass via the
bulk-update helper. Replaces the previous Order of operations (matters for IMAP): read-state and flag changes apply first (in source mailbox), then the move. IMAP requires the message to exist in the source folder for STORE before MOVE. |
| get_threadA | Return all messages in the thread containing the given message. Looks up the anchor message by its id, then reconstructs the
conversation via the connector's tiered IMAP threading dispatch
(Tier 1 X-GM-THRID for Gmail, Tier 3 header-search BFS fallback)
or the AppleScript path. Result rows are sorted by The returned ids can be piped into Known limitation: thread members whose subject was rewritten mid-conversation are missed on the AppleScript fallback path (subject prefilter tradeoff). |
| save_attachmentsB | Save attachments from a message to a directory. |
| create_mailboxC | Create a new mailbox/folder. |
| update_mailboxA | Rename and/or re-parent (move) an existing mailbox. Two delivery paths:
At least one of Refused (#164): operations targeting the bare |
| delete_mailboxA | Delete a mailbox via IMAP. Mail.app's AppleScript dictionary doesn't expose a working delete
primitive for mailboxes, so this operation goes through IMAP. Requires
IMAP credentials in Keychain (#73 opt-in flow) — returns
Always elicits user confirmation (destructive). By default refuses
non-empty mailboxes to prevent accidental data loss; pass
Refused (#164): targeting the bare |
| delete_messagesA | Delete messages (always moves to the account's Trash mailbox). |
| list_templatesA | List all stored email templates. Templates live as files at ~/.apple_mail_mcp/templates/.md. Override the location with the APPLE_MAIL_MCP_HOME environment variable. Returns: Dictionary with each template's name and subject (or null if no subject header is set). |
| get_templateA | Read a single template by name. |
| save_templateC | Create or overwrite a template. |
| delete_templateA | Delete a template by name. Destructive — requires user confirmation via MCP elicitation before running. |
| render_templateA | Render a template into ready-to-send subject and body text. No side effects — caller is responsible for passing the rendered
text to With |
| draft_createA | Create a draft (fresh, reply, or forward). DOES NOT SEND. To actually send, call Modes (driven by
|
| draft_updateA | Update an existing draft. DOES NOT SEND. Patch semantics: only fields you pass change. IMPORTANT: Mail.app forbids mutating saved drafts, so this is
implemented as delete-and-recreate. The returned |
| draft_deleteA | Delete (move to Trash) an existing draft. No send, no recovery expected — Mail.app moves the draft to Deleted Messages. |
| draft_sendA | Send an existing draft. THIS IS THE ONLY SEND TOOL. Hard policy gate: every recipient (to/cc/bcc) on the draft must
match the outbound allowlist (see outbound_allowlist.py). If any
recipient is off-list, the send is blocked and the draft is left
INTACT for human review — you can edit it via Off-list recipients are detected BEFORE any destructive operation,
so a blocked |
| email_send_htmlA | Send an HTML email directly. Does not save a draft first. Body must be an HTML string. The email is composed via clipboard injection into Mail.app's rich-text compose window and sent immediately. Outbound allowlist policy applies — all recipients must be on the allowlist. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/TG-Techie/apple-mail-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server