apple-mail-readonly-mcp
Allows searching and reading downloaded Apple Mail messages, including metadata and bodies, without modifying mail state. Provides tools for listing accounts, mailboxes, searching messages, reading messages and threads, and listing attachment metadata.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@apple-mail-readonly-mcpsearch for emails from John about project updates"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Apple Mail Read-Only MCP
A local MCP server for searching and reading downloaded Apple Mail data without changing mail state. It can run with any compatible MCP client and includes optional Codex plugin packaging.
Features
List Apple Mail accounts and mailboxes
Search local metadata (subject, sender, date) without reading bodies
Read selected downloaded message bodies with strict size limits
Read bounded local threads/conversations
List attachment metadata only (no export)
Full Disk Access diagnostics
Related MCP server: apple-mail-mcp
Requirements
macOS
Python 3.11+
Apple Mail configured locally
Full Disk Access may be required for the launcher process
Quick Start
# Run the MCP server
bash scripts/run_mcp.sh
# Run tests
python3 -m unittest discover -s tests -v
# Static security check
python3 scripts/doctor.py --static
# Live smoke test (opt-in)
APPLE_MAIL_READONLY_RUN_LIVE=1 python3 scripts/smoke_test.pyMCP Tools (v0.1)
Tool | Purpose |
| Verify server, platform, Mail store discovery |
| Diagnose Full Disk Access |
| List account coverage |
| List mailboxes/folders |
| Search local metadata (no body read) |
| Read a selected downloaded message |
| Read a bounded local thread |
| List attachment metadata |
Non-Goals
This server will never:
Send email
Create drafts
Reply/forward
Move, delete, archive, mark read/unread, flag
Export/open/download attachments
Run arbitrary scripts
Update itself
Installation
Run scripts/run_mcp.sh from any MCP client that supports stdio servers. See docs/codex-install.md for Codex plugin installation instructions.
Privacy and Security
Mail content stays on the local machine. The server opens the Apple Mail index in SQLite read-only mode, registers no write-capable tools, makes no mail-provider API calls, and never exports attachment contents. See docs/security-model.md for the complete guarantees and limitations.
License
MIT
Available Tools
8 toolsmail_health_checkB
Verify server, platform, Mail store discovery, and read-only database access.
| Name | Required | Description | Default |
|---|---|---|---|
| include_paths | No | Include high-level diagnostic paths. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It mentions 'read-only database access' but does not clarify if the tool itself is read-only, safe to run repeatedly, or what happens on failure. The agent is left guessing about safety and side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, efficiently listing the verification areas. It is front-loaded with the verb 'Verify'. While effective, it could use slight structuring (e.g., bullet points) for readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema or annotations, the description covers the basic purpose but lacks behavioral context and output expectations. It is adequate but leaves the agent wanting more for informed invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%: the 'include_paths' parameter is already described in the schema. The tool description adds no extra meaning about this parameter, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Verify' and specifies distinct resource areas: server, platform, Mail store discovery, and read-only database access. It fully distinguishes from sibling tools which are data retrieval or permission check tools, not diagnostic ones.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for health checking, but provides no explicit guidance on when to use, when not to use, or alternatives. Given the sibling tools are unrelated, the context is adequate but not proactive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mail_list_accountsC
List account UUID coverage from the local Envelope Index.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max accounts to return (1-100). | |
| include_email_addresses | No | Include email addresses (sensitive). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It does not disclose behavioral traits such as whether data is read-only, performance implications, or access restrictions. The term 'local Envelope Index' adds some context but not sufficient safety or side-effect details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no extraneous information. It is front-loaded and efficient, though it could be slightly more descriptive without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple tool with two parameters and no output schema, the description is insufficient. It does not hint at return format, pagination, or behavior when limit or include_email_addresses are used. More context is needed for an agent to understand the full scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description does not add extra meaning beyond the schema's parameter descriptions, but it does not need to as the schema covers both parameters adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states it lists 'account UUID coverage' from the local Envelope Index, providing a clear verb and resource. While it distinguishes from sibling tools like mail_list_mailboxes by focusing on UUID coverage, the term 'coverage' is a bit vague but still specific to the function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives like mail_list_mailboxes or mail_search_messages. There is no mention of prerequisites, limitations, or use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mail_list_attachmentsA
List attachment metadata for one downloaded message. Does not export content.
| Name | Required | Description | Default |
|---|---|---|---|
| local_id | No | Local message ROWID. | |
| message_id | No | Message ID (mailmsg_NNN). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explains it lists metadata and does not export, implying a read-only operation. With no annotations, it carries the burden of transparency, but it lacks explicit mention of being non-destructive or requiring any permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no wasted words. It front-loads the purpose and includes a clear limitation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with no output schema, the description explains the input and operation but omits details about the return format (e.g., what metadata fields are returned) and pagination, leaving some ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with both parameters described. The tool's description adds only context ('one downloaded message') but no additional semantic meaning beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists attachment metadata for one downloaded message and explicitly says it does not export content. This distinguishes it from sibling tools like mail_read_message (message content) and mail_search_messages (searching).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description specifies the tool is for a single downloaded message, giving clear context. However, it does not provide when-not-to-use scenarios or reference alternative tools for different needs, such as exporting attachments.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mail_list_mailboxesB
List mailboxes/folders with optional filters.
| Name | Required | Description | Default |
|---|---|---|---|
| role | No | Filter by role: inbox, sent, drafts, junk, trash, archive, outbox, other. | |
| limit | No | Max mailboxes to return (1-100). | |
| query | No | Search mailbox names. | |
| account_uuid | No | Filter by account UUID. | |
| include_empty | No | Include mailboxes with zero messages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description does not disclose behavioral traits such as pagination, permissions required, rate limits, or error handling. For a read operation, missing details on output format and scope.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence front-loaded with purpose, no waste. Could be slightly more informative without sacrificing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and 5 parameters, description lacks details on return format, default behavior (e.g., across all accounts), and edge cases. Incomplete for an agent to fully understand.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all 5 parameters with descriptions; the tool's 'optional filters' adds minimal value. Baseline score of 3 is appropriate as schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'list' and resource 'mailboxes/folders', with 'optional filters' distinguishing it from sibling tools like mail_list_accounts or mail_list_attachments.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus siblings like mail_search_messages or mail_health_check. Lacks context about prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mail_permissions_checkC
Diagnose Full Disk Access and optional settings guidance.
| Name | Required | Description | Default |
|---|---|---|---|
| open_full_disk_access | No | Open System Settings to Full Disk Access pane. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavior. It only mentions 'diagnose' and 'optional settings guidance' without detailing side effects (e.g., opening system settings might require user interaction), permissions, or what happens when 'open_full_disk_access' is true. The parameter schema adds some transparency, but overall behavioral insight is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise at one sentence, with no superfluous words. However, the brevity comes at the cost of completeness. For a simple tool, this is adequate, but more structure (e.g., bullet points) could improve clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one optional boolean parameter and no output schema, the description is nearly complete but lacks details about what 'diagnose' entails, what output or feedback the agent can expect, and whether the tool is safe to call without side effects. The context is functional but could be more informative.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the parameter description in the schema is clear: 'Open System Settings to Full Disk Access pane.' The tool description adds 'optional settings guidance,' which loosely maps to the parameter but does not add meaningful semantics beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Diagnose Full Disk Access and optional settings guidance' provides a general sense of the tool's function but is vague. It does not clearly differentiate from siblings like mail_health_check, which could also involve checking permissions. The parameter hints at opening system settings, but the core purpose is not precisely stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives. The description does not mention prerequisites, when to call this tool, or what distinguishes it from other mail tools. An agent lacks context for appropriate invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mail_read_messageB
Read a selected downloaded message by local id or message id.
| Name | Required | Description | Default |
|---|---|---|---|
| local_id | No | Local message ROWID. | |
| message_id | No | Message ID (mailmsg_NNN). | |
| body_format | No | Body format: plain or html. | plain |
| include_body | No | Include message body. | |
| max_body_chars | No | Max body characters (default 12000, max 50000). | |
| include_headers | No | Include message headers. | |
| include_attachment_metadata | No | Include attachment metadata. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It mentions 'downloaded message' but does not explain if downloading is required, whether the tool modifies state, rate limits, or authentication needs. The description is too vague for a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words. It is front-loaded with the core action. However, it could benefit from slight structuring, but remains concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 7 parameters and no output schema. The description does not explain what the return value contains (e.g., which fields are returned, how attachments are included). For a relatively complex tool, the description is incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds no additional parameter semantics beyond what the schema already provides (e.g., body_format, include_body). It does not compensate for any lack of schema detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads a downloaded message using either a local id or message id. It distinguishes from siblings like mail_read_thread (thread-level) and mail_search_messages (search), providing specific verb+resource+scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives (e.g., mail_read_thread for threads, mail_search_messages for search). No prerequisites or context provided. The description only implies use when a specific message identity is known.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mail_read_threadC
Read a bounded local thread/conversation.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max messages in thread (1-100). | |
| local_id | No | Local message ROWID. | |
| message_id | No | Message ID to find thread for. | |
| body_format | No | Body format: plain or html. | plain |
| include_bodies | No | Include message bodies. | |
| max_body_chars | No | Max body chars per message. | |
| conversation_id | No | Direct conversation ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavioral traits. It only mentions 'bounded,' leaving out details like permissions, side effects, or return structure. For a tool with 7 parameters, this is insufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short (one sentence), which is concise but lacks necessary context for effective tool use. It sacrifices completeness for brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description fails to explain key concepts like 'bounded,' how different identifiers work together, or expected behavior. More context is needed for adequate selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with individual parameter descriptions. The tool description adds no additional meaning beyond the schema, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads a thread/conversation. The verb 'Read' and resource 'thread/conversation' are specific, but it does not distinguish from sibling tools like mail_read_message or mail_search_messages, which could cause confusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus siblings. The description provides no context about when a thread should be read instead of a single message or search results.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mail_search_messagesA
Search local metadata newest-first. Does not read message bodies.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results (1-100). | |
| query | No | General search query (max 200 chars). | |
| sender | No | Filter by sender. | |
| date_to | No | End date (YYYY-MM-DD or ISO). | |
| subject | No | Filter by subject. | |
| date_from | No | Start date (YYYY-MM-DD or ISO). | |
| recipient | No | Filter by recipient. | |
| mailbox_id | No | Filter by mailbox ID. | |
| page_token | No | Pagination token. | |
| mailbox_ids | No | Filter by multiple mailbox IDs. | |
| unread_only | No | Only unread messages. | |
| account_uuid | No | Filter by account UUID. | |
| flagged_only | No | Only flagged messages. | |
| include_junk | No | Include junk/spam. | |
| mailbox_role | No | Filter by mailbox role. | |
| include_trash | No | Include trash. | |
| include_drafts | No | Include drafts. | |
| has_attachments | No | Filter by attachment presence. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description discloses two important behaviors (metadata-only search, newest-first ordering) but lacks details like read-only nature, pagination behavior, or what happens with empty results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise: two sentences, front-loaded with key purpose and behavioral constraint. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite 18 parameters and no output schema, the description is too sparse. It does not explain the return structure, pagination, or prerequisites. A more complete description is needed for this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All 18 parameters are fully described in the schema (100% coverage), so the description adds no additional meaning. Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it searches local metadata ordered newest-first, and explicitly says it does not read message bodies, which distinguishes it from sibling tools like mail_read_message and mail_read_thread.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implied usage by stating it does not read bodies, but no explicit guidance about when to use this tool versus alternatives like mail_read_message or mail_list_attachments.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
mail_health_check - First observed
mail_list_accounts - First observed
mail_list_attachments - First observed
mail_list_mailboxes - First observed
mail_permissions_check - First observed
mail_read_message - First observed
mail_read_thread - First observed
mail_search_messages
TDQS
Scored across 8 tools
Each tool targets a distinct function: health check, account listing, attachment metadata, mailbox listing, permissions, message reading, thread reading, and search. No overlap in purpose.
All tools follow the 'mail_verb_noun' pattern with snake_case, e.g., mail_list_accounts, mail_read_message, providing strong predictability.
8 tools cover the core read-only operations on Apple Mail without being excessive or insufficient for the domain.
Covers health, permissions, account/mailbox listing, message/thread reading, search, and attachment metadata. Missing bulk message listing and attachment content export, but reasonable for read-only scope.
Maintenance
Related MCP Connectors
A MCP server for Gmail that lets you search, read, and draft emails and replies.
MCP server for MailTempo's public free temporary email inboxes.
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Related MCP Servers
- AlicenseAqualityDmaintenanceLocal MCP server for multi-account IMAP/SMTP email (iCloud + Gmail via app-specific passwords). Never marks mail read. Cross-folder search, idempotent sends, TLS verified.8MIT
- AlicenseNot gradedqualityDmaintenanceA read-only MCP server for Apple Mail on macOS that enables searching and reading emails directly from the local SQLite database, with fast SQL-level filtering and pagination.2MIT
- AlicenseNot gradedqualityCmaintenanceAn MCP server that drives macOS Mail: read, search, send, organise.MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for Apple Mail that reads from Mail's SQLite store for fast queries and writes through Mail.app via AppleScript, enabling mailbox management, search, drafts, and message updates without sending mail.2,003 npmMIT