apple-mail-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": true
} |
| resources | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| search-messagesA | Use when: finding messages by query/sender/subject/date/read/flag filters and you need their ids for follow-up operations. Returns: matching messages with id, date, subject, sender, and read state (plus partial-coverage diagnostics when some mailboxes were skipped). Do not use when: you want a plain mailbox listing without filters (use list-messages), already have an id and want the body (use get-message), or want a whole conversation (use get-thread). Prefer this first to obtain the message ids that get-message/mark-as-read/delete-message/move-message and the batch tools require. |
| get-messageA | Use when: reading the full body of one message whose id you already have (numeric or imap:…); set preferHtml to get the HTML body instead of plain text. Returns: the message subject and body (plain text by default, HTML when preferHtml is true). Do not use when: you don't yet have an id (use search-messages or list-messages first), or you want the whole conversation (use get-thread). |
| get-threadA | Use when: you have one message id and want the whole conversation it belongs to, oldest-first. With an imap: id it threads by References/Message-ID; otherwise it groups by normalized subject. Returns: the thread's normalized subject and its messages (id, date, subject, sender, read state). Do not use when: you only need the single message (use get-message) or are searching by arbitrary criteria (use search-messages). |
| list-messagesA | Use when: browsing a mailbox's recent messages (optionally filtered by sender or unread-only) with pagination via limit/offset, and you need their ids. Returns: messages with id, date, subject, and sender (plus partial-coverage diagnostics when some mailboxes were skipped). Do not use when: you have specific search criteria like subject/date/flags (use search-messages) or already have an id and want the body (use get-message). Like search-messages, use this to obtain the ids that read/mark/delete/move and batch tools require. |
| send-emailA | Use when: the user has explicitly confirmed they want to send a single email now to the given recipients (to/cc/bcc are arrays), optionally with attachments and a chosen transport. Returns: a confirmation naming the recipients and attachment count. Do not use when: the user wants to review first (use create-draft), is replying to or forwarding an existing message (use reply-to-message / forward-message), or wants per-recipient personalized copies (use send-serial-email). Safety: this SENDS real email immediately and it cannot be unsent — require explicit user confirmation of the exact recipients, subject, and body before calling. Prefer create-draft when there is any doubt. |
| send-serial-emailA | Use when: the user has confirmed a mail-merge — sending individually personalized copies to many recipients (max 100), with {{Key}} placeholders in subject/body replaced per-recipient from each recipient's variables. Recipients do not see each other. Returns: a per-recipient sent/failed report with counts. Do not use when: sending one message to a shared recipient list (use send-email) or saving for review (use create-draft). Safety: this SENDS many real emails immediately and they cannot be unsent — require explicit user confirmation of the recipient list, the subject/body template, and the placeholder substitutions before calling. |
| create-draftA | Use when: composing an email the user should review in Mail.app before sending — the safe default for any new message (to/cc/bcc are arrays, optional attachments). Returns: a confirmation that the draft was created, with recipients and attachment count. Do not use when: the user has already confirmed they want it sent now (use send-email). Safety: low risk — creates a draft only and sends nothing; the user must open Mail.app and send it themselves. |
| reply-to-messageA | Use when: replying to an existing message by id, preserving its threading headers. Set replyAll for all recipients; set send=false to save as a draft instead of sending. Returns: a confirmation that the reply was sent or saved as a draft. Do not use when: composing a brand-new message (use send-email / create-draft) or forwarding to new recipients (use forward-message). Safety: with the default send=true this SENDS real email immediately and cannot be unsent — require explicit user confirmation of the recipients and body, or pass send=false to let the user review. |
| forward-messageA | Use when: forwarding an existing message (by id) to new recipients (to is an array), with an optional body to prepend. Set send=false to save as a draft. Returns: a confirmation that the message was forwarded or saved as a draft. Do not use when: replying to the sender/recipients (use reply-to-message) or composing a new message (use send-email / create-draft). Safety: with the default send=true this SENDS real email immediately and cannot be unsent — require explicit user confirmation of the recipients and any prepended body, or pass send=false to let the user review. |
| mark-as-readA | Use when: marking a single message (by id) as read. Returns: a confirmation that the message was marked read. Do not use when: marking several at once (use batch-mark-as-read) or marking unread (use mark-as-unread). Get the id from search-messages or list-messages first. |
| mark-as-unreadA | Use when: marking a single message (by id) as unread. Returns: a confirmation that the message was marked unread. Do not use when: marking several at once (use batch-mark-as-unread) or marking read (use mark-as-read). Get the id from search-messages or list-messages first. |
| flag-messageA | Use when: flagging a single message (by id), optionally with a color (red/orange/yellow/green/blue/purple/gray). Returns: a confirmation that the message was flagged (and the color, when applied). Do not use when: flagging several at once (use batch-flag-messages) or removing a flag (use unflag-message). Get the id from search-messages or list-messages first. Note: flag colors are a Mail.app feature applied via AppleScript; for an IMAP-routed id the flag is set but the color is not applied (IMAP flags are colorless). |
| unflag-messageA | Use when: removing the flag from a single message (by id). Returns: a confirmation that the message was unflagged. Do not use when: unflagging several at once (use batch-unflag-messages) or adding a flag (use flag-message). Get the id from search-messages or list-messages first. |
| delete-messageA | Use when: deleting a single message by id (moves it to Trash). Returns: a confirmation that the message was deleted. Do not use when: deleting several at once (use batch-delete-messages) or just filing it away (use move-message). Safety: destructive — require explicit user confirmation, and search-messages/list-messages first to confirm you have the right id before deleting. |
| move-messageA | Use when: moving a single message (by id) into another mailbox/folder, e.g. archiving or filing. Returns: a confirmation naming the destination mailbox. Do not use when: moving several at once (use batch-move-messages) or deleting (use delete-message). Use list-mailboxes to confirm the destination name exists. Safety: moves a real message between folders — confirm the destination mailbox, and search-messages/list-messages first to confirm the id. |
| batch-delete-messagesA | Use when: deleting multiple messages in one call (1–100 ids; moves them to Trash). Returns: counts of how many were deleted and how many failed. Do not use when: deleting just one (use delete-message) or filing messages away (use batch-move-messages). Safety: destructive and applies to many messages at once — require explicit user confirmation, and search-messages/list-messages first to confirm every id is correct before deleting. |
| batch-move-messagesA | Use when: moving multiple messages (1–100 ids) into the same destination mailbox/folder in one call, e.g. bulk archiving. Returns: counts of how many were moved and how many failed. Do not use when: moving just one (use move-message) or deleting (use batch-delete-messages). Use list-mailboxes to confirm the destination name exists. Safety: moves many real messages at once — confirm the destination mailbox, and search-messages/list-messages first to confirm the ids. |
| batch-mark-as-readA | Use when: marking multiple messages (1–100 ids) as read in one call. Returns: counts of how many were marked read and how many failed. Do not use when: marking just one (use mark-as-read) or marking unread (use batch-mark-as-unread). Get the ids from search-messages or list-messages first. |
| batch-mark-as-unreadA | Use when: marking multiple messages (1–100 ids) as unread in one call. Returns: counts of how many were marked unread and how many failed. Do not use when: marking just one (use mark-as-unread) or marking read (use batch-mark-as-read). Get the ids from search-messages or list-messages first. |
| batch-flag-messagesA | Use when: flagging multiple messages (1–100 ids) in one call, optionally with a color (red/orange/yellow/green/blue/purple/gray). Returns: counts of how many were flagged and how many failed. Do not use when: flagging just one (use flag-message) or removing flags (use batch-unflag-messages). Get the ids from search-messages or list-messages first. Note: flag colors are applied via Mail.app (AppleScript); any IMAP-routed ids in the batch are flagged but not colored (IMAP flags are colorless). |
| batch-unflag-messagesA | Use when: removing flags from multiple messages (1–100 ids) in one call. Returns: counts of how many were unflagged and how many failed. Do not use when: unflagging just one (use unflag-message) or adding flags (use batch-flag-messages). Get the ids from search-messages or list-messages first. |
| resolve-message-idA | Use when: you have |
| list-attachmentsA | Use when: enumerating a message's attachments (by id) to discover their names, MIME types, and sizes — typically before saving or fetching one. Returns: each attachment's name, MIME type, and size, plus a count. Do not use when: you want the bytes (use fetch-attachment for inline base64, or save-attachment to write to disk). Get the message id from search-messages or list-messages first. |
| save-attachmentA | Use when: writing one of a message's attachments to disk, by message id and attachmentName, into the savePath directory (saved as savePath/attachmentName). Returns: a confirmation of the saved file path. Do not use when: you don't know the attachment name (use list-attachments first) or want the bytes inline rather than on disk (use fetch-attachment). Safety: writes a file to disk — savePath must be a directory inside the configured allowed roots, and attachmentName may not contain path separators or '..'; calls outside those constraints are rejected. |
| fetch-attachmentA | Use when: retrieving an attachment's raw bytes inline as base64 (by message id and attachmentName), e.g. to process its contents without touching disk. Returns: the attachment's bytes base64-encoded, with its size and (for IMAP) MIME type. Do not use when: you don't know the attachment name (use list-attachments first) or you just want it saved to disk (use save-attachment). |
| list-mailboxesA | Use when: discovering the mailbox/folder names (and unread/message counts) available in an account, e.g. before moving messages or searching a specific mailbox. Returns: each mailbox's name with its unread (and, for IMAP, total message) count, plus a count. Do not use when: you want the messages inside a mailbox (use list-messages or search-messages) or the list of accounts (use list-accounts). |
| get-unread-countA | Use when: you only need the number of unread messages (optionally scoped to one mailbox and/or account), without listing the messages themselves. Returns: the unread count for the requested scope. Do not use when: you need the actual unread messages and their ids (use list-messages with unreadOnly, or search-messages with isRead=false) or broader totals (use get-mail-stats). |
| create-mailboxA | Use when: creating a new mailbox/folder in an account. Returns: a confirmation that the mailbox was created. Do not use when: renaming an existing one (use rename-mailbox) or deleting one (use delete-mailbox). Use list-mailboxes to see what already exists. Safety: creates a real folder in the mail account — confirm the name and target account first. |
| delete-mailboxA | Use when: deleting a mailbox/folder from an account. Returns: a confirmation that the mailbox was deleted. Do not use when: renaming it (use rename-mailbox) or deleting messages within it (use delete-message / batch-delete-messages). Safety: destructive — deleting a mailbox removes the folder and any messages it contains. Require explicit user confirmation and use list-mailboxes first to confirm the exact name. |
| rename-mailboxA | Use when: renaming an existing mailbox/folder from oldName to newName within an account. Returns: a confirmation naming the old and new mailbox names. Do not use when: creating a new folder (use create-mailbox) or deleting one (use delete-mailbox). Use list-mailboxes to confirm the current name. Safety: renames a real folder in the mail account — confirm oldName matches exactly (case-sensitive) before calling. |
| list-accountsA | Use when: discovering the configured Mail accounts (e.g. iCloud, Gmail) so you can pass an exact account name to other tools. Returns: the account names and a count. Do not use when: you want the folders within an account (use list-mailboxes) or messages (use list-messages / search-messages). |
| list-rulesA | Use when: discovering the Mail rules that exist and whether each is enabled or disabled, e.g. before enabling/disabling/deleting one. Returns: each rule's name and enabled/disabled state. Do not use when: you want to change a rule (use enable-rule / disable-rule / create-rule / delete-rule). |
| enable-ruleA | Use when: turning on an existing Mail rule by name. Returns: a confirmation that the rule was enabled. Do not use when: turning a rule off (use disable-rule), creating one (use create-rule), or deleting one (use delete-rule). Use list-rules to confirm the exact rule name. |
| disable-ruleA | Use when: turning off an existing Mail rule by name (without deleting it). Returns: a confirmation that the rule was disabled. Do not use when: turning a rule on (use enable-rule), creating one (use create-rule), or removing it permanently (use delete-rule). Use list-rules to confirm the exact rule name. |
| create-ruleA | Use when: creating a new Mail rule with one or more conditions (field/operator/value) and at least one action (markRead, markFlagged, delete, or moveTo). Set matchAll to require all conditions vs. any. Returns: a confirmation naming the rule and its condition count. Do not use when: toggling an existing rule (use enable-rule / disable-rule) or removing one (use delete-rule). Use list-rules to avoid duplicating an existing rule. Safety: creates a rule that automatically acts on real mail (including delete/move actions) on an ongoing basis — confirm the conditions and actions with the user before calling. |
| delete-ruleA | Use when: permanently removing a Mail rule by name. Returns: a confirmation that the rule was deleted. Do not use when: you only want to pause it (use disable-rule) or create one (use create-rule). Safety: destructive — the rule is removed permanently. Require explicit user confirmation and use list-rules first to confirm the exact name. |
| search-contactsA | Use when: looking up a person in Contacts.app by name to find their email address(es) before composing or sending mail. Returns: matching contacts with their names and email addresses. Do not use when: searching email messages (use search-messages) — this queries Contacts, not the mailbox. |
| save-templateA | Use when: creating a reusable email template (name, subject, body, optional default to/cc), or updating one by passing its existing id. Subject/body may contain placeholders for later use. Returns: the saved template's name and id (reuse the id with use-template / get-template / delete-template). Do not use when: composing a one-off message (use create-draft / send-email) or filling in a template to send (use use-template). Safety: writes the template to the on-disk templates store (APPLE_MAIL_MCP_TEMPLATES_FILE) and persists across restarts; passing an existing id overwrites that template. |
| list-templatesA | Use when: discovering the saved email templates and their ids, e.g. before using or editing one. Returns: each template's id, name, and subject. Do not use when: you want a single template's full body (use get-template) or want to apply one (use use-template). |
| get-templateA | Use when: reading the full contents of one saved template by id — its name, subject, default to/cc, and body. Returns: the template's name, subject, default recipients, and body text. Do not use when: you don't have the id (use list-templates first) or want to apply the template into a draft (use use-template). |
| delete-templateA | Use when: permanently removing a saved email template by id. Returns: a confirmation that the template was deleted. Do not use when: you only want to view it (use get-template) or update it (use save-template with the existing id). Safety: destructive — removes the template from the on-disk store permanently. Require explicit user confirmation and use list-templates first to confirm the id. |
| use-templateA | Use when: composing a new draft from a saved template (by id), optionally overriding the recipients, subject, or body. Creates a draft in Mail.app for the user to review and send. Returns: a confirmation that a draft was created from the template. Do not use when: you want to inspect the template without composing (use get-template) or send immediately without a draft (use send-email). |
| health-checkA | Use when: doing a quick check that Mail.app is reachable and the server's basic checks pass. Returns: an overall healthy/unhealthy status with a pass/fail line per check. Do not use when: you need detailed permission/account/IMAP/SMTP diagnostics with remediation steps (use doctor). |
| doctorA | Use when: troubleshooting setup problems — diagnoses Mail.app automation permissions, account state, and the IMAP/SMTP backends with actionable remediation messages. Returns: a detailed diagnostic report (formatted text plus structured checks). Do not use when: you just want a quick up/down status (use health-check) or message counts (use get-mail-stats). |
| get-mail-statsA | Use when: you want aggregate mailbox statistics — total and unread message counts, recently-received counts (last 24h/7d/30d), and (for the all-accounts path) a per-account breakdown. Returns: totals, unread counts, recent-activity counts, and per-account figures. Do not use when: you only need a single unread number (use get-unread-count) or want to list the messages themselves (use list-messages / search-messages). |
| get-sync-statusA | Use when: checking whether Mail.app is running and actively syncing, e.g. to explain why new mail hasn't appeared yet. Returns: whether Mail.app is running and whether sync activity was detected. Do not use when: you need message counts (use get-mail-stats) or a full setup diagnosis (use doctor). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| triage-inbox | Review unread mail and propose actions (archive, reply, flag, delete). |
| compose-reply | Draft a reply to a specific message in a chosen tone. |
| weekly-summary | Summarize the week's mail activity into a short briefing. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| accounts | All configured Mail accounts (name, email, enabled state). |
| templates | Saved, reusable email templates. |
Latest Blog Posts
- 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/sweetrb/apple-mail-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server