CAT
/MCP
SkillsMCPMarketplacesDigestToolsAdvertise

This week in Claude

Every Monday: Claude Code, Agent SDK, MCP, and the Anthropic platform moves worth your time.

Skills by Category
Frontend DevelopmentBackend & APIsTesting & QASecurityDevOps & CI/CDGit & Pull RequestsDocumentationCode Review & QualityAI & Agent BuildingSkill Development
MCP Servers by Category
Sales & MarketingWeb & Browser AutomationDatabasesAI & LLM ToolsCloud & InfrastructureCommunication & MessagingDeveloper ToolsDesign & CreativeDocuments & KnowledgeSearch & Web Crawling
Marketplaces by Category
AI Agents & OrchestrationLLM IntegrationDevelopment ToolsFrontend & UIBackend & APIsDatabasesTesting & Code QualityDevOps & CloudSecurity & ComplianceGit & Version Control

Cross AI Tools

Discover Claude Code plugins, extensions, and tools. Automatically updated directory of Anthropic Claude AI marketplaces with development tools, productivity plugins, and integrations.

Resources

  • Browse Skills
  • Browse MCP Servers
  • Browse Marketplaces
  • Plugins Reference

Community

  • About
  • Tools
  • Feedback
  • Privacy Policy
  • Advertise

Built for the Claude Code community with Claude Code by @mertduzgun

Independent project, not affiliated with Anthropic

Che Apple Mail Mcp

kiki830621/che-apple-mail-mcp
5STDIOregistry active
Summary

Connects Claude directly to your local Apple Mail via 48 native Swift tools that bypass AppleScript's slowness by querying SQLite directly. You get millisecond searches across subject, sender, recipient, and date fields even with 250K+ emails, plus batch operations on up to 50 messages per call. Covers the full surface: composing with markdown/HTML/plain formats, CRUD for mailboxes and rules, attachment extraction from .emlx files, VIP management, flag colors, and raw header access. Built for macOS 13+ with hardened input validation and fallback paths when SQLite fails. If you're automating Mail.app workflows or need LLM-driven email triage without Python overhead, this is the native option.

CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Keep your Mac awake
Keep your Mac awake
Keep your Mac awake while Claude Code and 40+ AI agents run. Sleeps when they're idle.
One time payment $9 →
Context.devContext.dev
Context.dev
Integrate web data into your AI product. One API to scrape website & brand data.
Get API Key Now →
Make your agent a DeFi expert
Make your agent a DeFi expert
Agent, run crypto. Access onchain data & trade routes via 1inch.
Install now →
Make money from your Skills
Make money from your Skills
On Capafy, your Skill runs online 24/7 as an agent product, and you get paid every time someone uses it.
Start earning →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Keep your Mac awake
Keep your Mac awake
Keep your Mac awake while Claude Code and 40+ AI agents run. Sleeps when they're idle.
One time payment $9 →
Context.devContext.dev
Context.dev
Integrate web data into your AI product. One API to scrape website & brand data.
Get API Key Now →
Make your agent a DeFi expert
Make your agent a DeFi expert
Agent, run crypto. Access onchain data & trade routes via 1inch.
Install now →
Make money from your Skills
Make money from your Skills
On Capafy, your Skill runs online 24/7 as an agent product, and you get paid every time someone uses it.
Start earning →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →

che-apple-mail-mcp

License: MIT macOS Swift MCP

The most comprehensive Apple Mail MCP server - 48 tools with SQLite-powered millisecond search across 250K+ emails.

English | 繁體中文


Why che-apple-mail-mcp?

FeatureOther MCPsche-apple-mail-mcp
Total Tools~2047
LanguagePythonSwift (Native)
Search SpeedSeconds (AppleScript)Milliseconds (SQLite)
Search FieldsSubject/SenderSubject/Sender/Recipient/Date
Batch OperationsNoUp to 50 emails per call
Mailbox ManagementBasicFull CRUD
Email ColorsNo7 flag colors + background
VIP ManagementNoYes
Rule ManagementPartialFull CRUD
SignaturesNoYes
Raw Headers/SourceNoYes

Quick Start

# Clone and build
git clone https://github.com/kiki830621/che-apple-mail-mcp.git
cd che-apple-mail-mcp
swift build -c release

# Copy to ~/bin and add to Claude Code
# --scope user    : available across all projects (stored in ~/.claude.json)
# --transport stdio: local binary execution via stdin/stdout
# --              : separator between claude options and the command
mkdir -p ~/bin
cp .build/release/CheAppleMailMCP ~/bin/
claude mcp add --scope user --transport stdio che-apple-mail-mcp -- ~/bin/CheAppleMailMCP

💡 Tip: Always install the binary to a local directory like ~/bin/. Avoid placing it in cloud-synced folders (Dropbox, iCloud, OneDrive) as file sync operations can cause MCP connection timeouts.

Then grant Automation permission in System Settings > Privacy & Security > Automation.


Recent Releases

For full details see CHANGELOG.md.

v2.7.2 (2026-05-10) — attachmentFragment cluster + fallback parity

  • Hardened attachmentFragment indent across all 3 callers + removed dead MailController.attachmentScript helper that bypassed v2.7.0's race-mitigation delays (#61, #62)
  • Attachment count cap (50) + env-configurable delays via CHE_MAIL_ATTACHMENT_DELAY_BETWEEN / _TRAILING (#63, #64)
  • get_email_metadata SQLite path now falls back to AppleScript on error — last read-tool gap closed; all 8 SQLite-first read tools now have parity fallback (#71)

v2.7.1 (2026-05-09) — base64 fix + .partial.emlx + observability

  • Critical: RFC822 header/body split was returning a relative array index instead of an absolute Data index, causing html_body to begin with "sion: 1.0\n\n<base64>" for some Android Gmail messages — raw base64 leaked into LLM context and triggered AUP false-positives downstream (#72)
  • save_attachment now reads from Attachments/<rowId>/<part_id>/<filename> cache when .partial.emlx body is empty — no more silent 0-byte writes for IMAP messages with stripped binaries (#66)
  • SQLite fast-path failures now log to stderr (SQLite ... fast path failed for rowId=...; falling through to AppleScript) (#69)

v2.7.0 (2026-05-04) — Mail.app race mitigation

  • Multi-attachment AppleScript paced with 0.3s between + 0.5s trailing delays to mitigate Mail.app silently dropping attachments under fast IPC (#60)

v2.6.0 (2026-05-03) — Security & validation hardening (8 PRs, 16 issues)

  • forward_email plain mode now embeds RFC 3676 > quoted original (parity with reply_email's #43 fix) (#44)
  • Hard-fail on tool param type mismatch — bool / [String] no longer silently coerced (#35)
  • Recipient email validation rejects header injection (control chars, missing/multiple @) (#41)
  • cc_additional deduplicates case-insensitively (#34)
  • Attachment path deny-list (~/.ssh, Keychains, TCC db, browser cookies) + symlink-resolved + new MAIL_MCP_ATTACHMENT_ROOTS env allow-list (#38)
  • All 17 id-taking tools hard-validate id as Int at handler boundary — defeats AppleScript predicate injection (#50)
  • Gated integration tests for reply_email runtime (#37, #45) + smoke matrix templates (#46, #47)

v2.5.0 (2026-04-17) — Composing format parameter

  • All 4 composing tools (compose_email / create_draft / reply_email / forward_email) gain format: "plain" | "markdown" | "html" param (closes #14, #15)
  • New message-composition capability spec

All 48 Tools

Accounts (2)
ToolDescription
list_accountsList all mail accounts
get_account_infoGet account details
Mailboxes (4)
ToolDescription
list_mailboxesList all mailboxes (folders)
create_mailboxCreate a new mailbox
delete_mailboxDelete a mailbox
get_special_mailboxesGet special mailbox names (inbox, drafts, sent, trash, junk, outbox)
Emails (7)
ToolDescription
list_emailsList emails in a mailbox
get_emailGet full email content
search_emailsSearch by subject/content
get_unread_countGet unread count
get_email_headersGet all email headers
get_email_sourceGet raw email source
get_email_metadataGet metadata (forwarded, replied, size)
Actions (8)
ToolDescription
mark_readMark as read/unread
flag_emailFlag/unflag email
set_flag_colorSet flag color (7 colors)
set_background_colorSet email background color
mark_as_junkMark as junk/not junk
move_emailMove to another mailbox
copy_emailCopy to another mailbox
delete_emailDelete email (to trash)
Compose (5)
ToolDescription
compose_emailSend new email (supports cc/bcc/attachments; format: plain/markdown/html; optional from_address for multi-account sender selection — see #131). Plain-text bodies send via the wrapper-free native path when Accessibility is granted — see #175 / check_accessibility
reply_emailReply to email. Optional: cc_additional, attachments, save_as_draft, format (since v2.4.0). Plain mode embeds RFC 3676 > quoted original (since v2.5.0 / #43)
forward_emailForward email. Optional body + format. Plain mode embeds RFC 3676 > quoted original (since v2.5.0+ / #44)
redirect_emailRedirect email (keeps original sender)
open_mailtoOpen mailto URL

Reply-as-draft example (v2.4.0+)

Reply to a thread, add extra CC, attach files, and save as a draft for human review before sending:

reply_email(
    id="<message id from search_emails>",
    mailbox="INBOX",
    account_name="iCloud",
    body="Reply text",
    cc_additional=["x@y.com"],
    attachments=["/path/to/file.pdf"],
    save_as_draft=true
)
Drafts (2)
ToolDescription
list_draftsList draft emails
create_draftCreate a draft (supports attachments; optional from_address for multi-account sender selection — see #131). Plain-text bodies use the wrapper-free native path when Accessibility is granted — see #175 / check_accessibility
Attachments (2)
ToolDescription
list_attachmentsList email attachments
save_attachmentSave attachment to disk
VIP (1)
ToolDescription
list_vip_sendersList VIP senders
Rules (5)
ToolDescription
list_rulesList mail rules
get_rule_detailsGet rule details
create_ruleCreate a new rule
delete_ruleDelete a rule
enable_ruleEnable/disable a rule
Signatures (2)
ToolDescription
list_signaturesList email signatures
get_signatureGet signature content
SMTP (1)
ToolDescription
list_smtp_serversList SMTP servers
Sync (2)
ToolDescription
check_for_new_mailCheck for new mail
synchronize_accountSync IMAP account
Utilities (4)
ToolDescription
extract_name_from_addressExtract name from email address
extract_addressExtract email from full address
get_mail_app_infoGet Mail.app info
import_mailboxImport mailbox from file

Response shape: search_emails / list_emails

Both tools return an envelope object { results, returned, limit, truncated } — not a bare array (changed in v2.14.0, #204). Read the matches from .results:

FieldMeaning
resultsArray of result objects (per-object fields unchanged from the pre-envelope shape). search_emails objects carry id, subject, sender, date_received, account_name, mailbox, to, plus account_id when the account UUID is resolvable. list_emails objects carry id, subject, sender.
returnedNumber of objects in results
limitEffective limit applied to the query
truncatedtrue when more results are available than were returned — raise limit or narrow the query to retrieve the rest (definitive on the SQLite fast path; a best-effort heuristic on the AppleScript fallback — see below)

truncated is definitive on the SQLite fast path (it fetches limit + 1 internally); on the AppleScript fallback it is a best-effort returned == limit heuristic. Any "enumerate → batch process" consumer should check truncated before assuming it has the full set.


Installation

Requirements

  • macOS 13.0+
  • Xcode Command Line Tools
  • Apple Mail with at least one account configured

Step 1: Build

git clone https://github.com/kiki830621/che-apple-mail-mcp.git
cd che-apple-mail-mcp
swift build -c release

Step 2: Configure

For Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "che-apple-mail-mcp": {
      "command": "/full/path/to/che-apple-mail-mcp/.build/release/CheAppleMailMCP"
    }
  }
}

For Claude Code (CLI)

# Copy to ~/bin and register (user scope = available in all projects)
mkdir -p ~/bin
cp .build/release/CheAppleMailMCP ~/bin/
claude mcp add --scope user --transport stdio che-apple-mail-mcp -- ~/bin/CheAppleMailMCP

Step 3: Grant Permissions

Automation (control Mail.app):

open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"
  1. Find CheAppleMailMCP and enable permission for Mail.app
  2. If using Claude Code, also add Terminal or iTerm

Full Disk Access (the SQLite fast path + export_emails_markdown read ~/Library/Mail):

open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"

macOS grants Full Disk Access to the responsible process — the app that launched this server — not to the binary itself. For an MCP server run by Claude Code inside a terminal, that responsible process is the terminal (Ghostty / Terminal / iTerm), so add your terminal app here and enable it. One grant on the terminal covers every MCP server it launches. (If you instead run the binary directly, or use the Claude Desktop bundle, add that binary — ~/bin/CheAppleMailMCP — since it is then its own responsible process.) The FDA-denied error message names these candidates for you — it does not auto-resolve the one exact app, because macOS exposes no reliable in-process API for that (#214). Without Full Disk Access, read tools silently fall back to the slower AppleScript path and SQLite-only features (projection, export_emails_markdown) fail. For the direct-launch path, a Developer ID-signed build makes the grant survive version bumps — see Signing & Notarization.

Guided setup (#213) — instead of the manual steps above, the binary ships setup helpers:

  • CheAppleMailMCP --setup opens a small window with live Full Disk Access status (re-checked on a timer, flips to "Ready ✅" the moment you grant) plus an on-demand Automation check, and "Open Full Disk Access settings" / "Copy binary path" buttons.
  • CheAppleMailMCP --check-fda prints the status headlessly (and opens the pane when access is denied) — handy from a terminal or script.
  • The check_fda MCP tool reports the same status to Claude on demand (call it when a SQLite-only feature errors).

None of these can remove the single manual toggle (Apple puts FDA in the manual-only bucket alongside Accessibility / Screen Recording), but they make "what do I do?" obvious and give live feedback the instant you flip it on.

Accessibility (clean compose, #175) — a separate, optional grant from Full Disk Access. Mail.app wraps any AppleScript-injected outgoing-message body in <blockquote type="cite">, which some mobile clients render as a quotation of your own text. To avoid this, compose_email / create_draft route plain-text mail through Mail's native compose pipeline (a mailto: hand-off), then drive save/send and attachments with keyboard shortcuts — which needs Accessibility (System Settings → Privacy & Security → Accessibility), granted to the same responsible process as FDA (your terminal / Claude Desktop). The check_accessibility MCP tool and the --setup window's Accessibility row report the status. Without it, compose still works but falls back to the wrapped legacy path (with a stderr warning). markdown/html bodies and a custom from_address always use the legacy path. To force the legacy path even when Accessibility is granted, set CHE_MAIL_DISABLE_MAILTO_COMPOSE=1.

Step 4: Restart Claude

# For Claude Desktop
osascript -e 'quit app "Claude"' && sleep 2 && open -a "Claude"

# For Claude Code - start a new session
claude

Usage Examples

Natural Language (Claude Desktop)

"List all my mail accounts"
"Show unread emails in Gmail inbox"
"Search for emails about 'quarterly report'"
"Send an email to john@example.com about the meeting"
"Flag important emails in red"
"Create a rule to move newsletters to a folder"

Direct Tool Calls (Claude Code)

"Use list_accounts to show my accounts"
"Use search_emails to find emails containing 'invoice'"
"Use set_flag_color to mark email ID 12345 as blue"
"Use check_for_new_mail to refresh"

Flag & Background Colors

Flag Colors (set_flag_color)

IndexColor
0Red
1Orange
2Yellow
3Green
4Blue
5Purple
6Gray
-1Clear

Background Colors (set_background_color)

blue, gray, green, none, orange, purple, red, yellow


Performance & Storage

SQLite + .emlx fast path

Most read tools prefer Apple Mail's local Envelope Index (SQLite) and on-disk .emlx message files over AppleScript IPC, with transparent AppleScript fallback when the SQLite path can't satisfy a request:

ToolSQLite/.emlx pathAppleScript fallback
get_email✓✓ on any error
get_emails_batch✓ (per item)✓ (per item)
get_email_headers✓✓ on any error
get_email_source✓✓ on any error
search_emails✓✓ when reader unavailable
list_attachments✓✓ on any error
save_attachment✓✓ on any error
get_email_metadata✓✓ on any error (since #71)

For save_attachment's read path the fast path is 10–100× faster than AppleScript (per #12 measurements). Other tools' speedup ratios depend on request shape; in general, large bulk reads see the biggest gain.

The fast path requires:

  • Full Disk Access granted to the host process (System Settings → Privacy & Security → Full Disk Access)
  • Apple Mail's local store at ~/Library/Mail/V10/...
  • Message has been synced to local .emlx storage

EWS / Exchange accounts intentionally bypass the fast path

Exchange (EWS) accounts in Apple Mail do not materialize .emlx files — message bodies live on the server and are fetched on demand. For these accounts, all 8 read tools (including get_email_metadata since #71) transparently degrade to AppleScript IPC (which is correct but slower). Symptoms:

  • A bulk fetch of 500 EWS messages will be noticeably slower than 500 IMAP/Gmail messages
  • This is not a bug — it's an Apple Mail storage architecture constraint (see #9)

Diagnosing fast-path bypass

When the fast path fails for a non-EWS account, the failure is logged to stderr (since #69). Run the binary in a terminal and watch stderr to distinguish:

  • EnvelopeIndexReader init failed: ... — DB unreachable (commonly: Full Disk Access missing)
  • SQLite get_email fast path failed for rowId=N: ... — per-message failure (e.g., .partial.emlx only, malformed MIME, file not yet synced)

Both cases transparently fall through to AppleScript with ... falling through to AppleScript in the log line, so behavior is preserved while observability is restored.


Troubleshooting

ProblemSolution
Server disconnectedRebuild with swift build -c release
Not allowed to send Apple eventsAdd permissions in System Settings > Automation
Mail.app not respondingEnsure Mail.app is running with configured accounts
Commands timing outLarge mailboxes take longer; try specific searches
Bulk fetch slower than expectedWatch stderr for ... falling through to AppleScript lines. EWS/Exchange accounts always fall back (see Performance & Storage); other accounts logging fallback indicate a fixable .emlx issue
save_attachment fails with -1728 "Can't get account" or -1719 "Invalid mailbox index"Since #173 both errors come back with an actionable hint naming the failing reference (account / mailbox / message). Common causes: two Mail.app accounts share the same display_name, or an email-form account_name maps to several accounts — see Account Disambiguation below.

Account Disambiguation

Mail.app's AppleScript account "<display_name>" selector is not unique when two accounts share the same display_name — a common pattern when an iCloud catch-all alias forwards a Gmail address back to itself, or when Google Workspace + personal Gmail overlap. Any AppleScript-routed tool (save_attachment fallback, get_email, mark_read, etc.) will then non-deterministically pick the wrong account → -1728 / -1719 errors.

The fix: pass account_id (Mail.app's globally-unique UUID) alongside account_name. When provided, save_attachment uses Mail.app's account id "<UUID>" selector instead, bypassing the ambiguity:

// Tool call: save_attachment with account_id
{
    "id": "273214",
    "mailbox": "[Gmail]/全部郵件",
    "account_name": "alice@example.com",
    "account_id": "C38E0583-47F8-4468-BE70-43155C15549D",  // ← disambiguates
    "attachment_name": "report.pdf",
    "save_path": "/tmp/report.pdf"
}

Discovering account_id:

  • From search_emails results — each object in the results array (a SearchResult) carries an account_id field alongside account_name (populated by decoding the account UUID from the SQLite mailboxes.url authority via MailboxURL.decode — Mail.app's storage convention encodes the account UUID in the mailbox URL authority; there is no direct SELECT mailboxes.account_id). Recommended: pass it through directly.
  • Manually — read ~/Library/Mail/V10/MailData/Signatures/AccountsMap.plist. The top-level keys are the UUIDs; the AccountURL value contains the matching email address percent-encoded in the authority.
  • In AppleScript — tell application "Mail" to get id of every account returns the UUID list.

Backward compatibility: account_id is optional. When omitted (or empty), tools fall back to the legacy account "<display_name>" path — behavior identical to pre-#101 — with one save_attachment exception (#173): when account_name contains @ (email-shaped, the form SQLite-path tools like search_emails emit), save_attachment first reverse-looks-it-up in AccountsMap and silently upgrades to the account id "<UUID>" selector (the upgrade is logged to stderr). Exactly one match → that UUID; several accounts behind one address (iCloud catch-all + Gmail) → an actionable error listing every candidate instead of a raw -1728; no match → the legacy display-name path, unchanged. Edge: a Mail account whose description legitimately contains @ and happens to equal another account's email now resolves in the email namespace first — pass account_id explicitly to pin the selector. Other tools keep the strict pre-#101 fallback (the cross-tool sweep is #176).

Scope: account_id is accepted across the AppleScript-routed tools that reference mail by account. It began with save_attachment (#101); the #104 sweep then added the 13 single-message / movement / relay / mailbox tools below:

  • save_attachment (#101) — the precursor
  • PR-A — 5 single-message mutation tools: mark_read, flag_email, set_flag_color, set_background_color, mark_as_junk
  • PR-B — 3 movement/destruction tools: move_email, copy_email, delete_email
  • PR-C — 3 message-relay tools: reply_email, forward_email, redirect_email
  • PR-D — 2 mailbox CRUD tools: create_mailbox, delete_mailbox

The surface has since expanded beyond the #104 set:

  • #176 — generalized the email→UUID resolveAccountIdForTool chokepoint across all 14 AppleScript-routed write handlers (so an email-form account_name resolves to the UUID selector, not just an accepted account_id).
  • #180 — threaded account_id through the read-tool AppleScript fallbacks (list_emails / search_emails / get_email / headers / source / metadata / attachments / get_unread_count) via resolveMailboxRef / resolveMsgRef (the PR-E that was previously deferred is now done).
  • #179 — get_special_mailboxes accepts account_id / account_name for per-account special-mailbox real names.
  • #191 — the account-level action tools check_for_new_mail and synchronize_account gained the account_id escape hatch (synchronize_account accepts account_id alone).

Still not covered by account_id (tracked): get_account_info / list_mailboxes (#202).

compose_email / create_draft do not exhibit the display_name-collision defect — they make new outgoing message rather than referencing existing mail by account, so they never emit an account "<display_name>" selector. Multi-account sender selection is now available via the optional from_address parameter (#131) — pass any one of your configured Mail.app email addresses ("alice@example.com" or RFC 5322 form "Alice <alice@example.com>") to set the sender of the outgoing message; omit to use Mail.app's default account. Use list_accounts to discover the addresses configured on the running Mac.

Cross-account move/copy is not supported via account_id (#129 — from #127 verify). move_email and copy_email accept a single account_id, which is threaded through both the source msgRef and the destination mailboxRef. The architectural choice is correct (movement stays within one account, because Mail.app's AppleScript verb move msg to <mailboxRef> requires the destination mailbox to be expressed relative to a single account context). Mail.app's UI permits cross-account move via drag-and-drop, but the AppleScript-routed move_email / copy_email tools cannot replicate that — calling move_email with account_id of one account while expecting the destination to_mailbox to be resolved against a different account silently picks the wrong account's mailbox of that name (if both accounts happen to have one) or raises -1719 "Invalid mailbox index". If you need a copy of the message's contents under a different account, you can manually rebuild it via save_attachment + compose_email — note this is not a true move/copy: original metadata (Message-ID, received-date, flags, labels) and message identity are not preserved.


Technical Details

  • Framework: MCP Swift SDK v0.10.0
  • Read path: SQLite (Envelope Index) + .emlx file parser, with AppleScript fallback for EWS / unparseable .emlx
  • Write/state path: AppleScript via NSAppleScript
  • Transport: stdio
  • Platform: macOS 13.0+ (Ventura and later)

Signing & Notarization

The distributed binary is Developer ID-signed and notarized, and that is not cosmetic. The fast read path needs Full Disk Access (FDA), and macOS TCC keys an FDA grant to the binary's designated requirement. For an ad-hoc binary that requirement is the cdhash, so every version bump invalidated the grant and you had to re-add the binary to the Full Disk Access list after each release. A stable Developer ID signature keys the grant to the signing identity instead, so it survives version bumps (#211) — that signature, not notarization, is what delivers the persistence.

Notarization matters for quarantined-launch paths: a browser download or the .mcpb (Claude Desktop) install, where Gatekeeper assesses the binary on first launch. The plugin wrapper's curl + exec path sets no quarantine attribute, so Gatekeeper never fires there. We notarize anyway so the published release asset is safe to run by any means.

The first grant is still manual. FDA (kTCCServiceSystemPolicyAllFiles) has no programmatic request API — an app can only deep-link you to the settings pane. Signing makes that first grant permanent, not automatic.

One-time setup (maintainers)

# 1. Developer ID Application cert in your login keychain (needs an Apple Developer account)
security find-identity -p codesigning -v        # find your identity

# 2. notarytool keychain profile (prompts for an app-specific password — never pass it on the CLI)
xcrun notarytool store-credentials <profile-name> \
  --apple-id <your-apple-id> --team-id <your-team-id>

# 3. Export both for the signed targets
export DEVELOPER_ID='Developer ID Application: Your Name (TEAMID)'
export NOTARY_PROFILE='<profile-name>'

Dev install on your own machine (fast — no notarization)

make install-signed     # build + Developer ID sign + copy to ~/bin

Use this to get a stable FDA grant on your own Mac without waiting for Apple notarization: your own cert launches fine locally, and the grant survives future rebuilds. Grant Full Disk Access once to ~/bin/CheAppleMailMCP and you are done.

Distribution release (signed + notarized + published)

make release-signed VERSION=vX.Y.Z      # wraps scripts/release.sh with REQUIRE_CODESIGN=1

This builds a universal (arm64 + x86_64) binary, signs it, notarizes it (1–15 min Apple round-trip), and uploads it to the GitHub release. Forks without certs can still cut an unsigned dev release with SKIP_CODESIGN=1 ./scripts/release.sh vX.Y.Z.


Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


License

MIT License - see LICENSE for details.


Author

Created by Che Cheng (@kiki830621)

If you find this useful, please consider giving it a star!

Featured
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Keep your Mac awake
Keep your Mac awake
Keep your Mac awake while Claude Code and 40+ AI agents run. Sleeps when they're idle.
One time payment $9 →
Context.devContext.dev
Context.dev
Integrate web data into your AI product. One API to scrape website & brand data.
Get API Key Now →
Make your agent a DeFi expert
Make your agent a DeFi expert
Agent, run crypto. Access onchain data & trade routes via 1inch.
Install now →
Make money from your Skills
Make money from your Skills
On Capafy, your Skill runs online 24/7 as an agent product, and you get paid every time someone uses it.
Start earning →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Categories
DatabasesSearch & Web Crawling
Registryactive
Packagehttps://github.com/kiki830621/che-apple-mail-mcp/releases/download/v2.0.1/CheAppleMailMCP
TransportSTDIO
UpdatedApr 2, 2026
View on GitHub

Related Databases MCP Servers

View all →
Postgres

ai.waystation/postgres

Connect to your PostgreSQL database to query data and schemas.
54
Read Only Local Postgres Mcp Server

hovecapital/read-only-local-postgres-mcp-server

MCP server for read-only PostgreSQL database queries in Claude Desktop
2
Database Mcp

cocaxcode/database-mcp

MCP server for database connectivity. Multi-DB (PostgreSQL, MySQL, SQLite), 19 tools.
1
Mcp Mysql

io.github.infoinlet-marketplace/mcp-mysql

Read-only MySQL/MariaDB for AI agents — query, list/describe tables, health. SQL-guarded.
Database Admin

io.github.cybeleri/database-admin

Database admin MCP: schema inspection, query optimization for PostgreSQL and MySQL
Postgres Secured (Aegis Zero-Trust)

io.github.yash-0620/postgres-mcp-secured

Enterprise PostgreSQL MCP secured by Aegis Zero-Trust to block unauthorized SQL injections.