Skip to main content
Glama
PsychQuant

che-apple-mail-mcp

by PsychQuant

che-apple-mail-mcp

License: MIT macOS Swift MCP

功能最全面的 Apple Mail MCP 服务器 - 53 个工具,基于 SQLite 的毫秒级搜索,可处理 250K+ 封邮件。

English | 繁體中文


为什么选择 che-apple-mail-mcp?

特性

其他 MCP

che-apple-mail-mcp

工具总数

~35 (Tip)

53

语言

Python

Swift(原生)

搜索速度

秒级(AppleScript)

毫秒级(SQLite)

搜索字段

主题/发件人

主题/发件人/收件人/日期

批量操作

每次调用最多 50 封邮件

邮箱管理

基础

完整的增删改查(CRUD)

邮件颜色

7 种标记颜色 + 背景色

VIP 管理

规则管理

部分

完整的增删改查(CRUD)

签名

原始邮件头/原文


Related MCP server: apple-mail-mcp

快速开始

安装插件。它会把已签名的二进制文件、/archive-mail 命令族、安全规则和过期检测钩子作为一个整体提供:

claude plugin marketplace add PsychQuant/che-apple-mail-mcp
claude plugin install che-apple-mail-mcp@che-apple-mail-mcp

然后授予权限——安装窗口会显示实时状态,并直接链接到正确的"系统设置"面板:

~/bin/CheAppleMailMCP --setup

💡 完全磁盘访问权限(Full Disk Access,FDA) 是快速 SQLite 读取路径和 batch_export_emails_markdown 能够工作的前提。没有它,工具仍然可以运行,但实际能读取的内容极少甚至为空,这很容易被误认为是一个 bug,而不是权限问题。macOS 不允许应用以编程方式请求 FDA——必须由用户手动勾选——而这正是安装窗口在设计上想要简化的事情。

插件 vs 仅 MCP

仅注册 MCP 服务器本身是一种受支持的进阶方案,但它是一个严格更小的安装。请在你完全知悉的前提下去选择它——运行时不会有任何东西提示你缺少这些内容(#353):

随插件提供

仅 MCP 所具备

全部 53 个 MCP 工具

✅ 是

/archive-mail + -migrate / -rebuild-threads / -repair-synthetic-ids / -view

❌ 归档标准操作流程(SOP)不存在

rules/compose-wrapper-free.md — 引用块(cite-block)曾经的方式,以及被拒绝的 compose 调用意味着什么

⚠️ 背景:自 #304 以后,包装器(wrapper)在结构上已经不可能存在,因此该规则现在解释 6 种拒绝原因及其处理方案,而不再是防止静默回退

rules/confirmation-triggers.mdrules/false-positive-detection.md

❌ 缺乏针对破坏性操作的确认纪律

hooks/session-start.sh — 过期检测并终止会话

❌ 升级后,会话可能继续运行旧二进制文件

Developer ID 签名 + 公证(notarized) 的二进制

❌ 自构建的二进制使用的是临时签名(ad-hoc);在 macOS 26 上 TCC 无法可靠地为它授予 FDA/自动化权限,因此权限看起来已经授予,之后却会失效(#211

版本 sidecar → --self-update 以及 #303 种的过期检查

❌ 通过手工程序构建的二进制旁边没有 sidecar,所以该检查永远处于静默状态

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

# --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

将二进制文件安装到本地目录,例如 ~/bin/。避免使用云同步文件夹(Dropbox、iCloud、OneDrive)——同步活动会导致 MCP 连接超时。

对于自构建的二进制文件,如果希望在重新构建后仍能保持 TCC 权限,请使用 Developer ID 签名;参见 签名与公证一节。否则,你需要在每次构建后重新重新授予权限。


近期发布

详细内容请见 CHANGELOG.md

v2.7.2(2026-05-10)— attachmentFragment 修复集 + 回退对齐

  • 加固了 attachmentFragment 在所有 3 个调用方中的缩进,并移除了绕过 v2.7.0 的竞态缓解延迟的废弃 attachmentFragment 辅助方法(issues #61#62

  • 设置附件数量上限(50),并可通过 CHE_WRITE_ATTACHment_DELAY_BETWEEN / _TRAILING 环境变量配置延迟([#63](https://github.com/PsychQuant/che-App redirect? 实际内容)

  • get_email_metadata 的 SQLite 路径现在在出错时会回退到 AppleScript——最后一个读取工具的空档已补齐;现在全部 8 个 SQLite 优先的读取工具都具备对等回退(#71

v2.7.1(2026-05-09)— base64 修复 + .partial.emlx + 可观测性

  • 严重:RFC822 头部/正文拆分曾返回相对数组索引,而不是绝对 Data 索引,导致部分 Android Gmail 消息的 html_body 开头变成 "sion: 1.0\n\n<base64>",并根据 base64 直接泄漏到 LLM 上下文并进一步引发 AUP 误报(#72

  • save_attachment.partial.emlx 内容为空时,现在会从 Attachments/<rowId>/<part_id>/<filename> 缓存读取,不会出现被剥离的二进制 IMAP 消息被接到 0 字节文件的问题(#66

  • SQLite 快速路径失败现在会记录到 stderr(日志格式:SQLite ... fast path failed for rowId=...; falling through to AppleScript),见 #69

v2.7.0(2026-05-04)— Mail.app 竞态问题缓解

  • 多附件 AppleScript 请求加入 0.3 秒的间隔和 0.5 秒的尾部延迟,以缓解在高速 IPC 期间 Mail.app 静默删除附件的问题(#60

v2.6.0(2026-05-03)— 安全性与校验加固(8 个 PR,16 个 issue)

  • forward_email 的纯文本模式现在会嵌入 RFC 3676 的 > 引用原文(与 reply_email 的 #43 修复保持一致性,详见 #44

  • 工具参数类型不匹配时现在直接硬失败——bool[String] 不会再被静默强制转换(#35

  • 收件人邮箱校验将拒绝包含控制字符、缺少 @ 或包含多个 @ 的邮件头注入(#41

  • cc_additional 现在会进行不区分大小写的去重(#34

  • 附件路径黑名单(~/.ssh、Keychain、TCC 数据库、浏览器 Cookie),解析软链接,并新增 MAIL_MCP_ATTACHMENT_ROOTS 环境变量的可配置白名单(#38

  • 所有 17 个接受 id 的工具都会在处理器边界强制将 id 作为整数校验,从而阻止 AppleScript 谓词注入(#50

  • reply_email 添加了有门的集成测试(#37#45)以及冒烟矩阵模板(#46#47

v2.5.0(2026-04-17)— 编写邮件时的 format 参数

  • 全部 4 个编写邮件的工具(compose_email / create_draft / reply_email / forward_email)都增加了 format: "plain" | "markdown" | "html" 参数(对应关闭 #14#15

  • 新增 message-composition 能力规范


所有 53 个工具

工具

描述

list_accounts

列出所有邮件账户

get_account_info

获取账户详情

工具

描述

list_mailboxes

列出所有邮箱(文件夹)

create_mailbox

创建新邮箱

delete_mailbox

删除邮箱

get_special_mailboxes

获取特殊邮箱名称(收件箱、发件箱、已发送、已发送、草稿、垃圾邮件)

</详细>

工具

描述

list_emails

列出某个邮箱中的邮件

get_email

获取完整的邮件内容

<span style="font-family: monospace;">search_emails</span>

按主题/内容搜索

get_unread_count

获取未读邮件数

get_email_headers

获取全部邮件头

get_email_source

获取原始邮件内容

get_email_metadata

获取邮件元数据(是否已转发、已回复、大小等)

Инструмент

Описание

mark_read

Пометить как прочитанное/непрочитанное

flag_email

Установить/снять флаг на письме

set_flag_color

Задать цвет флага (7 цветов)

set_background_color

Задать цвет фона письма

mark_as_junk

Пометить как спам/не спам

move_email

Переместить в другой почтовый ящик

copy_email

Скопировать в другой почтовый ящик

delete_email

Удалить письмо (в корзину)

Инструмент

Описание

compose_email

Отправить новое письмо (поддерживаются cc/bcc/вложения; format: поддерживается только plain, начиная с #304; необязательный from_address для выбора отправителя в мультиаккаунтном режиме — см. #131, чистое выполнение поддерживается через проверенное всплывающее окно From, #219). Тело письма всегда берётся из собственного редактора Mail — см. #175 / check_accessibility; вызов, который не может быть выполнен чисто, завершается ОШИБКОЙ с указанной причиной и не создаёт ничего (#304)

reply_email

Ответить на письмо. Необязательно: cc_additional, attachments, save_as_draft, format (начиная с v2.4.0). В режиме plain встраивается процитированный оригинал с префиксом > в формате RFC 3676 (начиная с v2.5.0 / #43). Новое тело вставляется в собственное окно ответа Mail (#218); не-plain значение format или отсутствие прав Accessibility приводит к ошибке вместо отката (#304)

forward_email

Переслать письмо. Необязательно: body + format. В режиме plain встраивается процитированный оригинал с префиксом > в формате RFC 3676 (начиная с v2.5.0+ / #44). Пересылка без body не требует вставки содержимого и не требует прав Accessibility; при указании body действуют те же правила, что и для reply_email (#218 / #304)

redirect_email

Перенаправить письмо (сохраняется исходный отправитель)

open_mailto

Открыть mailto-URL

Пример ответа в виде черновика (v2.4.0+)

Ответьте в ветку обсуждения, добавьте дополнительных получателей в копию, прикрепите файлы и сохраните как черновик для проверки человеком перед отправкой:

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
)

Инструмент

Описание

list_drafts

Список черновиков писем — каждая запись содержит subject и числовой id (#276, дополняющая функция; используется для update_draft.draft_id / delete_email.id)

create_draft

Создать черновик (поддерживаются вложения; необязательный from_address для выбора отправителя в мультиаккаунтном режиме — см. #131, чистое выполнение через надёжное всплывающее окно From, #219). Тело письма всегда берётся из собственного редактора Mail — см. #175 / check_accessibility; вызов, который не по выполоться чисто, завершается ошибкой и не создаёт ничего (#304)

update_draft

Заменить существующий черновик (вставка или обновление, #276): найти по draft_id или точному subject_match → создать замену (наследует условия применимости и ограничения create_draft) → удалить старый. Преднамеренно «сначала создать, затем удалить» с подтверждением после создания (при неисправности всегда предпочтение отдаётся сохранению черновиков — в худшем случае могут существовать оба, но никогда не ни один). 0 или более 1 совпадений всегда приводят к отказу (кандидаты перечисляются). Замена получает НОВЫЙ id

Инструмент

Описание

list_attachments

Список вложений письма

save_attachment

Сохранить вложение на диск

Инструмент

Описание

list_vip_senders

Список VIP-отправителей

Инструмент

Описание

list_rules

Список почтовых правил

get_rule_details

Получить подробности правила

create_rule

Создать новое правило

delete_rule

Удалить правило

enable_rule

Включить/отключить правило

Инструмент

Описание

list_signatures

Список подписей писем

get_signature

Получить содержимое подписи

Инструмент

Описание

list_smtp_servers

Список SMTP-серверов

Инструмент

Описание

check_for_new_mail

Проверить наличие новых писем

synchronize_account

Синхронизировать IMAP-аккаунт

Инструмент

Описание

Инструмент

Описание

get_emails_batch

Получить до 50 писем за один вызов (ошибки по отдельным элементам)

list_attachments_batch

Перечислить вложения для до 50 писем

batch_export_emails_markdown

Массовый экспорт на стороне сервера в markdown без изменений + вложения (замороженный манифест во frontmatter; конкурентные вызовы сериализуются по output_dir#193 / #236)

export_emails_markdown

УСТАРЕЛО — переименован в batch_export_emails_markdown (#233); алиас будет удалён не ранее v3.0

Инструмент

Описание

extract_name_from_address

Извлечь имя из адреса электронной почты

extract_address

Извлечь email из полного адреса

get_mail_app_info

Получить информацию о Mail.app

import_mailbox

Импортировать почтовый ящик из файла

Инструмент

Описание

check_fda

Проверка статуса Full Disk Access (доступность быстрого пути через SQLite)

check_accessibility

Проверка разрешения Accessibility (GUI-пути для compose/reply; без него такие инструменты отказываются)

check_automation

Проверка разрешения Automation (Apple Events для Mail) — неактивный вид проб, не приглашающий запросов, четыре состояния с рекомендациями по исправлению (#293); у бинарника есть его собственное разрешение — работающий osascript ≠ авторизованный бинарника (#288)

Форма ответа: search_emails / list_emails

Оба инструмента возвращают объект-обёртку { results, returned, limit, truncated }а не простой массив (изменено в v2.14.0, #204). Читайте найденные записи из .results:

Поле

Описание

results

Массив объектов-результатов (поля каждого объекта не изменились по сравнению с прежней формой без обёртки). Обьекты search_emails содержат id, subject, sender, date_received, account_name, mailbox, to, а также account_id, когда UUID учётной записи удаётся резолвить. Объе 93ы list_emails содержат id, subject, sender.

returned

Количество объектов в results

limit

Фактический limit, применённый к запросу

truncated

true, когда доступно больше результатов, чем возвращено, — увеличьте limit или сузьте запрос, чтобы получить остальные (точность гарантирована на быстром пути SQLite; на резервном пути AppleScript это эвристика best-effort — см. ниже)

truncated определённо точен на быстром пути SQLite (внутри получается limit + 1); на резервном пути AppleScript это эвристика returned == limit с максимальной добросовестностью. Любой потребитель в схеме «перечисление → пакетная обработка» должен проверить truncated, прежде чем считать, что получил полный набор.


Установка

Начните с Быстрый старт — установка плагина является поддерживаемым путём и даёт вам команды, правила безопасности, хук устаревания (staleness hook) и подписанный бинарник. Всё ниже — продвинутый / для разработчиков маршрут: он регистрирует только MCP-сервер, и это строго меньший объём установки (см. Плагин против MCP-only, чего будет не хватать, потому что в среде выполнения ничто об этом вам не сообщит).

Требования

  • macOS 13.0+

  • Xcode Command Line Tools (для маршрута «сборка своими руками» ниже)

  • Apple Mail как минимум с одной настроенной учётной территорией

Шаг 1: Сборка

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

Шаг 2: Настройка

Для Claude Desktop

Отредактируйте ~/Library/Application Support/Claude/claude_desktop_config.json:

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

Для 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

Шаг 3: Выдача разрешений

Самый быстрый способ — окно настройки: оно показывает актуальный статус Full Disk Access / Automation / Accessibility, повторно проверяет его по мере выдачи разрешений и открывает нужную панель System Settings:

~/bin/CheAppleMailMCP --setup

Чтобы сделать это вручную:

Automation (для управления Mail.app):

open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"
  1. Найдите CheAppleMailMCP и включите разрешение для Mail.app.

  2. Если вы используете Claude Code, также добавьте Terminal или iTerm.

Full Disk Access (быстрый путь SQLite, чтение ~/Library/Mail через export_emails_markdown):

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

macOS выдаёт Full Disk Access ответственному процессу — приложению, которое запустило этот сервер, — а не самому бинарнику. Для MCP-сервера, запущенного Claude Code внутри терминала, таким ответственным процессом будет терминал (Ghostty / Terminal / iTerm), поэтому добавьте свой терминал и включите разрешение. Одно разрешение для терминала покрывает все MCP-серверы, которые он запускает. (Если вы вместо этого запускаете бинарник напрямую или используете копиюс Claude Desktop, добавьте сам бинарник — ~/bin/CheAppleMailMCP — потому что тогда он — собственный ответственный процесс.) Сообщение об ошибке «FDA denied» перечисляет этих кандидатов — оно не автоматически выбирает конкретное приложение, так как macOS имеет надёжного процесса для этого no API (#214). Без Full Disk Access инструменты чтения молча переходят на более медленный путь AppleScript, а функции, работающие только с SQLite (projection, export_emails_markdown), завершаются ошибкой. Для прямого запуска подпись Developer ID позволяет разрешению пережить обновления версий — см. Подпись и нотаризация.

Направляемая настройка (#213) — вместо ручных шагов выше бинарник включает помощников по настройке:

  • CheAppleMailMCP --setup открывает небольшое окно с «живым» статусом Full Disk Access (проверяется по таймеру и переключается на «Готово ✅» в момент вашего разрешения) плюс проверкой Automation по запросу, а также кнопки «Open Full Disk Access settings» / «Copy binary path».

  • CheAppleMailMCP --check-fda выводит статус в без-UI режиме (и открывает панель, когда доступ запрещён) — удобно из терминала или скрипта.

  • MCP-инструмент check_fda сообщает Claude тот же статус по запросу (вызывайте его, когда какой-либо функционал только SQLite прет).

Ни один из этих способов не избавит от единого ручного переключателя (because macOS помещает FDA в категорию «только вручную» вместе с Accessibility / Screen Recording), но они показывают, что именно делать, и дают мгновенную обратную связь, как только вы его включите.| Инструмент | Описание | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | get_emails_batch | Получить до 50 писем за один вызов (ошибки по отдельным элементам) | | list_attachments_batch | Перечислить вложения для до 50 писем | | batch_export_emails_markdown | Массовый экспорт на стороне сервера в markdown как есть + вложения (замороженный манифест во frontmatter; конкурентные вызовы сериализуются по output\_dir#193 / #236) | | export_emails_markdown | УСТАРЕЛО — переименован в batch_export_emails_markdown (#233); алиаs удалён не ранее v3.0 |

Инструмент

Описание

extract_name_from_address

Извлечь имя из адреса электронной почты

extract_address

Извлечь email из полного адреса

get_mail_app_info

Получить информацию о Mail.app

import_mailbox

Импортировать почтовый ящик из файла

Инструмент

Описание

check_fda

Проверка статуса Full Disk Access (доступность быстрого пути SQLite)

check_accessibility

Проверка разрешения Accessibility (GUI-пути для compose/reply; без него эти инструменты отказываются)

check_automation

Проверка разрешения Automation (Apple Events для Mail) — неактивное зондирование без запросов, четыре состояния с исправлениями (#293); у бинарника собственное разрешение, osascript работает ≠ бинарник авторизован (#288)

Форма ответа: search_emails / list_emails

Оба инструмента возвращают объект-обёртку { results, returned, limit, truncated }а не простой массив (изменено в v2.14.0, #204). Читайте найденные записи из .results:

Поле

Описание

results

Массив объектов-результатов (поля каждого объекта прежние, как без обёртки). В объектах search_emails есть id, subject, sender, date_received, account_name, mailbox, to, плюс account_id, когда UUID учётной записи удаётся резолвить. В list_emails есть id, subject, sender.

returned

Количество объектов в results

limit

Фактический limit, применённый к запросу

truncated

true, когда доступно больше результатов, чем возвращено — поднимите limit или сузьте запрос, чтобы получить остальные (достоверность на быстром пути SQLite; на резервном пути AppleScript — эвристика best-effort — см. ниже)

Значение truncated достоверно на быстром пути SQLite (внутри выбирается limit + 1); на резервном пути AppleScript это эвристика returned == limit (best-effort). Любому «перечисление → пакетная обработка»-потребителю стоит проверить truncated, прежде чем считать набор данных полным.


Установка

Начните с Quick Start — установка плагина, поддерживаемый путь, даёт команды, правила безопасности, фильтр устаревания (staleness hook) и подписанный бинарник. Всё ниже — продвинутый / для разработки способ: он регистрирует только MCP-сервер, что является строго меньшей установкой (см. Plugin против MCP-only о том, чего не хватает: ничто в среде выполнения вам об этом не сообщит).

Требования

  • macOS 13.0+

  • Xcode Command Line Tools (для маршрута «вручную собрать» ниже)

  • Apple Mail с как минимум одной настроенной учётной записью

Шаг 1: Сборка

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

Шаг 2: Настройка

Для Claude Desktop

Отредактируйте ~/Library/Application Support/Claude/claude_desktop_config.json:

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

Для 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

Шаг 3: Предоставление разрешений

Самый быстрый путь — окно настройки, в котором виден актуальный статус Full Disk Access / Automation / Accessibility, оно перепроверяет по мере выдачи разрешений и открывает нужную панель System Settings:

~/bin/CheAppleMailMCP --setup

Можно и вручную:

Automation (управление Mail.app):

open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"
  1. Найдите CheAppleMailMCP и включите разрешение для Mail.app

  2. При использовании Claude Code добавьте также Terminal или iTerm

Full Disk Access (быстрый путь SQLite и чтение ~/Library/Mail с помощью export_emails_markdown):

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

macOS выдаёт Full Disk Access ответственному процессу — то есть приложению, которое запустило этот сервер, — не самому бинарнику. Для MCP-сервера, запускаемого Claude Code внутри терминала, таким ответственным процессом является терминал (Ghostty / Terminal / iTerm), поэтому здесь нужно добавить и включить своё терминальное приложение. Одного разрешения терминала хватает для всех MCP-серверов, которые он запускает. (Если вместо этого запускать бинарник напрямую или использовать инсталлятор Claude Desktop, добавьте сам бинарник — ~/bin/CheAppleMailMCP, — поскольку тогда он сам становится ответственным процессом.) Сообщение об отказе FDA перечисляет возможные кандидатуры — он не самостоятельно выбирает то единственно правильное приложение, потому что macOS не предоставляет надёжного внутрипроцессного API что бы определить. Без Full Disk Access инструменты чтения молча переходят на более медленный AppleScript-путь, а функции, существующие только на SQLite (projection, export_emails_mchannels)->Fail. Для прямого запуска сборка Developer ID; справка — см. Signing & Notarization.

Направляемая настройка (#213) — бинарник содержит встроенные помощники вместо ручных действий:

  • CheAppleMailMCP --setup открывает небольшое окно с сердцем: статус Full Disk Access — в реальном времени (перечитывается по таймеру, становится «Ready ✅» в момент выдачи), плюс проверка Automation по запросу и кнопки "Open Full Disk Access settings" / "copy binary path".

  • CheAppleMailMCP --check-assembly печатает статус без интерфейса (и открывает область настроек при отказе FDA) — удобно в терминале или скрипте.

  • Инструмент MCP check_fda сообщает этот же статус Claude в любой момент (вызвать его, когда функция, зависящая от SQLite, получит сообщение об ошибок).

Ни один них не может отменить одно ручное переключение (Apple держит FDA в категории только ручных что вместе с Accessibility / Screen Recording), но они делают очевидным порядок действий и дают оперативную обратную связь сразу после переключения.

Accessibility (compose, #175/#304) — это отдельное, необязательное разрешение в дополнение к Full Disk Access. Mail.app оборачивает тело исходящего сообщения, внедрённого через AppleScript, в <blockquote type="cite">, которое некоторые мобильные клиенты отображают как цитату вашего собственного текста — и которое отправитель локально не видит, потому что у встроенного стиля обёртки нет рамки. Начиная с #304 кода, который это создавал, больше не существует: каждый инструмент создания письма берёт тело из собственного редактора Mail — через передачу mailto: для compose_email / create_draft, штатный глагол reply/forward плюс вставку для reply_email / forward_email — и управляет сохранением, отправкой и прикреплением файлов с помощью клавиатурных сокращений, для чего требуется Accessibility (System Settings → Privacy & Security → Accessibility), выданный тому же отвественному процессу, что и FDA (ваш терминал или Claude Desktop). Инструмент MCP check_accessibility и строка Accessibility в окне --setup показывают статус. Без него эти инструменты теперь завершаются ошибкой, а не переходят на запасной путь — запасного пути нет, поэтому вызов, который не может выполниться чисто, возвращает поименованную ошибку и не создаёт ничего. Ошибка указывает на open_mailto, которому вообще не нужно разрешение TCC (он не может нести вложения; вы сохраняете или отправляете окно сами). Ровно шесть условий отказывают в вызове: не-plain формат format; пустая тема; отсутствие разрешения Accessibility; from_address, который не является bare addr-spec; путь к вложению, содержащий не-ASCII символы (#220); и получатель с отображаемым именем, которое этот путь не может заполнить (cc/bcc — всегда; to при отправке — отображаемое имя to для черновика заполняется через графический интерфейс, #277). Для чистого тела письма из неосновного аккаунта передайте from_address: графический интерфейс выбирает его в открывающемся списке From в Mail и считывает выбор обратно, прерывая операцию, а не рискуя отправить с неправильного адреса (#219). Вместе с устаревшим путём удалены: format: "markdown" / "html" — ни один путь из существующих сегодня не передаёт форматированный текст без того присваиванияbody, которое было удалено. Это то, что существует, а не доказательство невозможности (#310): путь вставки (#218) — второй маршрут без обёртки, и NSPasteboard может переносить расширенные типы данных, но созданный им MIME не проверен — #306 это решает; #308 / [#309](https://github.com/PsychQuant/che-apple-mail-mcp/issues/309 являются альтернативами, параметры require_wrapper_free и sanitize_links, а также escape-люки CHE_MAIL_DISABLE_MAILTO_COMPOSE / CHE_MAIL_DISABLE_PASTE_REPLY. Отказ от них подразумевает две очевидные возможности: создание письма без видимого окна (исходная цель этих люков) больше невозможно, и compose_email больше не отправляет данные на Name <addr> — используйте create_draft и отправьте черновик самостоятельно.

TCC Automation (-1743) и аварийный выход без TCC

Если инструменты на базе AppleScript завершаются с ошибкой AppleScript error (-1743): Not authorized to send Apple events to Mail, значит, разрешение Automation отсутствует для этого бинарного: подписанный бинарный файл MCP использует НАСТОЯЩЕЕ разрешение Automation — его TCC-идентичностьзация привязана к идентичности подписи бинарника (урок #211, ось Automation) и отдельна от вашего терминала. Эмпирически подтверждено: управление Mail через osascript из вашего браузера shell не означает, что бинарник авторизован. Предоставьте его через System Settings → Privacy & Security → Automation — найдите запись для бинарника / его хоста (расширение Claude Desktop: под Claude.app) и включите для Mail. Если записи нет, ранее принятоэкцией припоминается и macOS не запромит снова: выполните tccutil reset AppleEvents, затем попробуйте инструмент Mail ещё раз, чтобы вызвать запрос. Разрешения выдаются на конкретную установку, и обновление бинарника может признать запись недействительной (#221).

Пока разрешение на месте, open_mailto по-прежнему работает: он проходит через Launch Services (нулевой TCC, #287) и открывает окно создания без блоков-цитат в системном почтовом клиенте по умолчанию. МТ и mailto не могут нести вложения (RFC 6068) — файлы перетаскиваются вручную.

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

Примеры использования

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"

Прямые вызовы инструментов (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"

Цвета флажков и фоны

Цвета флажков (set_flag_color)

Индекс

Цвет

0

Красный

1

Оранжевый

2

Жёлтый

3

Зелёный

4

Синий

5

Фиолетовый

6

Серый

-1

Прозрачный

Цвета фона (set_background_color)

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


Производительность и хранение

Быстрый путь SQLite + .emlx

Большинство инструментов чтения предпочитает локальный Envelope Index (SQLite) приложения Apple Mail и файлы сообщений .emlx на диске, а не примут AppleScript IPC, и прозрачно переходят на AppleScript как резерв, когда этот путь через SQLite не справляется с запросом.

Tool

Путь SQLite/.emlx

Резервный путь AppleScript

get_email

✓ (с у error)

get_emails_batch

✓ (для каждого элемента)

✓ (для каждого элемента)

get_email_headers

✓ (при любой ошибке)

get_email_source

✓ (при любой ошибке)

search_emails

✓ (когда ридер недоступен)

list_attachments

✓ (при любой ошибке)

save_attachment

✓ (при любой ошибке)

get_email_metadata

✓ (при любой ошибке) (начиная с #71)

Для пути чтения save_attachment быстрый путь в 10–100× быстрее, чем AppleScript (о чем свидетельствуют #12). Степень ускорения остальных инструментов зависит от структуры запроса; в целом массовые чтения выигрывают максимально.

Чтобы использовать быстрый путь, нужна:

  • Разрешение Full Disk Access для основного процесса (System Settings → Privacy & Security → Full Disk Access)

  • локальб ~5/Library/Mail/ /V10/...

  • Сообщение в локальном хранилище .emlx

Аккаунты EWS / Exchange сознательно обходят быстрый путь

Учётные записи Exchange (EWS) в Apple Mail не создают файлов .emlx — содержимое тара хранится на сервере и подгружается по запросу. Для таких учётных записей все 8 рабочих инструментов (включая get_email_metadata с #71)) прозрачно откат на AppleScript IPC (это корректно, но медленнее). Симптомы:

  • Массовая выборка 5005 писем EWS будет заметно медленнее, чем 500 IMAP/Gmail.

  • Это не дефект — это ограничение архитектуры хранения Apple Mail (см. #9).

Диагностика обхода быстрого пути

Когда быстрый путь не сразаёт для учётной записи не-EWS, ошибка записывается в stderr (поскольку #69). Запустите бинарник в терминале и наблюдайте за stderr, например:

  • Три строки EnvelopeIndexReader init failed: ... — недоступна база данных (например, отсутствует Full Disk Access)

  • SQLite get_email fast path failed for rowId=N:... — ошибка для конкретного сообщения (например, только .partial.emlx, некорректный MIME, ещё не синхронизировано)

В обоих случаях прозрачный переход к AppleScript оформляется в строке журнала с подписью ... falling through to AppleScript, поэтому поведение сохраняется, а observability за восстанавливается.


Troubleshooting

Неисправность

Решение

Сервер отключился

Пересоберите с помощью swift build -c release

Нет разрешения отправлять события Apple

Добавьте разрешения в «Системных настройках» (System Settings) > «Автоматизация» (Automation)

Mail.app не отвечает

Убедитесь, что Mail.app запущена и в ней настроены учётные записи

Команды выходят по тайм-ауту

Для больших почтовых ящиков требуется больше времени; попробуйте более конкретные поисковые запросы

Массовое получение данных медленнее ожидаемого

Следите в stderr за строками ... falling through to AppleScript. Учётные записи EWS/Exchange всегда переходят на резервный (fallback) путь (см. Производительность и хранилище); у других учётных записей появление такого fallback в логах указывает на устранимую проблему с .emlx

save_attachment завершается с ошибкой -1728 "Can't get account" или -1719 "Invalid mailbox index"

Начиная с #173 обе ошибки возвращаются с практической подсказкой, указывающей на проблемный элемент (учётная запись / почтовый ящик / сообщение). Частые причины: две учётные записи Mail.app имеют одинаковый display_name, либо account_name в виде адреса электронной почты соответствует нескольким учётным записям — см. Устранение неоднозначности учётных записей ниже.


Устранение неоднозначности учётных записей

Селектор AppleScript account "<display_name>" в Mail.app не уникален, когда две учётные записи имеют одинаковый display_name — обычная ситуация, когда catch-all-алиас iCloud пересылает адрес Gmail обратно самому себе или когда Google Workspace и личный Gmail пересекаются. Тогда любой инструмент, работающий через маршрут AppleScript (резервный путь save_attachment, get_email, mark_read и т. д.), недетерминированно выбирает не ту учётную запись → ошибки -1728 / -1719.

Решение: передавайте account_id (глобально уникальный UUID в Mail.app) вместе с account_name. Когда он указан, save_attachment использует селектор account id "<UUID>" Mail.app, обходя неоднозначность:

// 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"
}

Как узнать account_id:

  • Из результатов search_emails — каждый объект в массиве results (это SearchResult) содержит поле account_id наряду с account_name (заполняется декодированием UUID учётной записи из authority поля mailboxes.url SQLite через MailboxURL.decode — принятое в Mail.app правило хранения кодирует UUID учётной записи в authority URL почтового ящика; прямого SELECT mailboxes.account_id не существует). Рекомендуется передавать его без изменений.

  • Вручную — откройте файл ~/Library/Mail/V10/MailData/Signatures/AccountsMap.plist. Ключи верхнего уровня — это UUID; значение AccountURL содержит соответствующий адрес электронной почты, закодированный в authority через percent-encoding.

  • В AppleScripttell application "Mail" to get id of every account возвращает список UUID.

Обратная совместимость: account_id необязателен. Когда он опущен (или пуст), инструменты используют прежний путь account "<display_name>" — поведение идентичное pre-#101 — с одним исключением для save_attachment (#173): если account_name содержит @ (имеет форму адреса электронной почты, как у инструментов на SQLite-пути, например search_emails), save_attachment сначала выполняет обратный поиск в AccountsMap и незаметно переключается на селектор account id "<UUID>" (переключение логируется в stderr). Ровно одно совпадение — используется этот UUID; несколько учётных записей за одним адресом (iCloud catch-all + Gmail) — конкретное сообщение об ошибке со списком всех кандидатов вместо сырого -1728; нет совпадения — прежний путь по отображаемому имени, без изменений. Особый случай: учётная запись Mail, у которой description законно содержит @ и случайно совпадает с адресом другой учётной записи, теперь резолвится в пространстве адресов в первую очередь — передайте account_id явно, чтобы зафиксировать селектор. Остальные инструменты сохраняют строгий fallback, как до #101 (распространение по всем инструментам отслеживается в #176).

Область применения: account_id принимается в инструментах на маршруте AppleScript, которые обращаются к письмам по учётной записи. Началось всё с save_attachment (#101); затем в ходе прохода (#104) добавили 13 инструментов для работы с одиночными сообщениями / перемещением / пересылкой / почтовыми ящиками:

  • save_attachment (#101) — предшественник

  • PR-A — 5 инструментов изменения отдельных сообщений: mark_read, flag_email, set_flag_color, set_background_color, mark_as_junk

  • PR-B — 3 инструмента перемещения/удаления: move_email, copy_email, delete_email

  • PR-C — 3 инструмента пересылки сообщений: reply_email, forward_email, redirect_email

  • PR-D — 2 инструмента управления почтовыми ящиками: create_mailbox, delete_mailbox

С тех пор набор расширился за пределы праймера из #104:

  • #176 — обобщил общую точку resolveAccountIdForTool для преобразования email→UUID во всех 14 обработчиках записи на маршруте AppleScript (чтобы account_name в форме адреса резолвился в UUID-селектор, а не только явный account_id).

  • #180 — проброшен account_id через AppleScript-fallback инструментов чтения (list_emails / search_emails / get_email / заголовки / исходный текст / метаданные / вложения / get_unread_count) через resolveMailboxRef / resolveMsgRef (ранее отложенный PR-E теперь выполнен).

  • #179get_special_mailboxes принимает account_id / account_name для получения реальных имён специальных почтовых ящиков учётной записи.

  • #191 — инструменты уровня учётной записи check_for_new_mail и synchronize_account получили запасной вариант через account_id (synchronize_account принимает только account_id).

Пока account_id не покрывает (отслеживается): get_account_info / list_mailboxes (#202).

compose_email / create_draft не подвержены дефекту пересечения токенов display_name — они создают новое исходящее сообщение через make new outgoing message, а не ссылаются на существующее почту по учётной записи, поэтому никогда не генерируют селектор account "<display_name>". Выбор отправителя при нескольких учётных записях теперь доступен через необязательный параметр from_address (#131) — передайте любой из настроенных в Mail.app адресов ("alice@example.com" или в форме RFC 5322 "Alice <alice@example.com>"), чтобы задать sender исходящего письма; если параметр опущен, используется учётная запись Mail.app по умолчанию. Используйте list_accounts, чтобы узнать адреса, настроенные на этом Mac.

Перемещение/копирование между учётными записями через account_id не поддерживается (#129 — из подтверждения #127). move_email и copy_email принимают один account_id, который пробрасывается и в исходный msgRef, и в целевой mailboxRef. Такое архитектурное решение корректно: перемещение остаётся внутри одной учётной записи, потому что глагол AppleScript move msg to <mailboxRef> требует, чтобы целевой почтовый ящик был указан относительно контекста одной учётной записи. В UI Mail.app допускается перемещение между учётными записями перетаскиванием, но инструменты move_email / copy_email на маршруте AppleScript этого повторить не могут — вызов move_email с account_id одной учётной записи, ожидая, что целевой to_mailbox будет безотносительно резолвиться в другой, молча выберет почтовый ящик с таким именем другой учётной записи (если он есть в обеих) или приведёт к ошибке -1719 "Invalid mailbox index". Если нужна копия содержимого письма в другой учётной записи, её можно собрать вручную через save_attachment + compose_email — заметьте, это не настоящее перемещение/копирование: исходные метаданные (Message-ID, дата получения, флаги, метки) и идентичность сообщения не сохраняются.


Технические details

  • Фреймворк: MCP Swift SDK v0.10.0

  • Путь чтения: SQLite (Envelope Index) + парсер .emlx, с fallback на AppleScript для EWS / неразбираемых .emlx

  • Путь записи/состояния: AppleScript через NSAppleScript

  • Транспорт: stdio

  • Платформа: macOS 13.0+ (Ventura и новее)


Подпись и нотаризация

Распространяемый бинарник подписан Developer ID и нотаризован, и это не косметика. Быстрый путь чтения требует Полного доступа к диску (Full Disk Access, FDA), а TCC macOS привязывает выданное разрешение FDA к designated requirement бинарника. Для ad-hoc бинарника это требование — cdhash, поэтому при каждом изменении версии разрешение становилось недействительным, и после каждого релиза приходилось заново добавлять бинарник в список Full Disk Access. Стабильная подпись Developer ID привязывает разрешение к подписывающей идентичности, поэтому оно сохраняется при смене версий (#211) — именно эта подпись, а не нотаризация, обеспечивает постоянство.

Нотаризация важна для путей запуска с карантинной меткой: загрузка из браузера или установка через .mcpb (Claude Desktop), когда Gatekeeper оценивает бинарник при первом запуске. Путь обёртки плагина с curl + exec не устанавливает атрибут карантина, поэтому Gatekeeper там не срабатывает. Мы всё равно нотаризуем, чтобы опубликованный в релизе файл можно было безопасно запускать любым способом.

Первое разрешение всё равно выдаётся вручную. Для FDA (kTCCServiceSystemPolicyAllFiles) не существует программного API запроса — приложение может только перенаправить вас к панели настроек. Подпись делает это первое разрешение постоянным, а не автоматическим.

Разовая настройка (для мейнтейнеров)

# 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>'

Установка на своей машине для разработки (быстро, без нотаризации)

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

Используйте это, чтобы получить стабильное разрешение полного доступа к диску на вашем Mac без ожидания нотаризации Apple: ваш собственный сертификат успешно запускается локально, и разрешение сохраняется при дальнейших пересборках. Предоставьте полный доступ к диску один раз для ~/bin/CheAppleMailMCP — и всё готово.

Релиз для распространения (подписанный + нотаризованный + опубликованный)

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

Этот шаг собирает универсальный (arm64 + x86_64) бинарный файл, подписывает его, нотаризует (1–15 минут на обращение к Apple) и загружает его в релиз GitHub. Форки без сертификатов по-прежнему могут выпустить неподписанный dev-релиз с помощью SKIP_CODESIGN=1 ./scripts/release.sh vX.Y.Z.


Участие

Вклад приветствуется! Не стесняйтесь отправлять Pull Request.


Лицензия

Лицензия MIT

Подробности см. в LICENSE.


Автор

Создано Che Cheng (@kiki830621)

Если этот проект оказался вам полезен, пожалуйста, поставьте ему звезду!

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
1dResponse time
4dRelease cycle
44Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Enables AI assistants to interact with Apple Mail through natural language, providing comprehensive email management including reading, searching, composing, organizing, and analyzing emails across all configured accounts. Includes an expert skill system that teaches intelligent email workflows and productivity strategies.
    26
    193
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables unified email management across Gmail, Outlook, iCloud, and IMAP providers with tools for search, send, organize, and batch operations via natural language.
    58
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables using Apple Mail accounts to search, read, manage, draft, and send messages from Codex or Claude Code locally.
    MIT

View all related MCP servers

Related MCP Connectors

  • Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…

  • Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.

  • Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.

View all MCP Connectors

Latest Blog Posts

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/PsychQuant/che-apple-mail-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server