icloud-mcp 是一个面向 iCloud 邮件的 Model Context Protocol(MCP)服务器,允许大语言模型通过 IMAP 和 SMTP 协议读取、搜索、归档和发送 Apple 邮件。它完全在用户本地机器上运行,凭据和邮件内容不会到达第三方,网络通信和 MIME 解析仅使用 Python 标准库。
主要能力
- 搜索所有文件夹,而不仅是收件箱。邮件规则可能将回复归档到其他文件夹,search_all_folders 可以找到仅搜索收件箱时遗漏的邮件。
- 默认只读:搜索和读取工具使用 SELECT ... readonly 和 BODY.PEEK,不会在后台将邮件标记为已读、移动或删除。
- 先草稿后发送:save_draft 将邮件放入草稿箱供用户审阅;send_email 存在但独立且需显式调用。
- 不销毁邮件:没有删除邮件的工具,delete_mailbox 会拒绝删除仍包含邮件的文件夹。
- 处理真实的 iCloud MIME:包括修改版 UTF-7 文件夹名、quoted-printable、不准确的字符集声明、仅 HTML 的邮件以及带重音符号的服务器端搜索。
- 附件字节不经过模型:save_attachments 写入文件并返回路径,来自邮件的文件名会被清理,视为不可信输入。
使用方式
需要 Python 3.11 或更高版本以及 uv。需要一个启用了双重认证的 iCloud 账户,并使用 App 专用密码(iCloud 拒绝通过 IMAP 使用主密码)。在 account.apple.com → Sign-In and Security → App-Specific Passwords 生成 App 专用密码。
发布到 PyPI 后无需克隆仓库。setup 命令会询问地址和 App 专用密码,测试连接,写入 .env,然后打印适用于客户端的配置块。
标准配置可用于大多数客户端。使用 claude mcp list 检查。
Claude Desktop 配置:将标准配置添加到 claude_desktop_config.json。macOS 路径为 ~/Library/Application Support/Claude/claude_desktop_config.json,Windows 路径为 %APPDATA%\Claude\claude_desktop_config.json。在 Windows 上,使用 uv.exe 的绝对路径,因为桌面客户端不一定继承 shell 的 PATH。
Codex 配置:在 ~/.codex/config.toml 中配置。
Cursor、Windsurf、VS Code 配置:在编辑器的 MCP 设置文件中使用标准配置块(.cursor/mcp.json、~/.codeium/windsurf/mcp_config.json 或 VS Code MCP 设置)。
MCP 服务器在客户端启动时加载,编辑配置后需重启客户端。
工具分类
读取类工具不会修改邮箱。写入类工具按设计需要显式调用。没有工具会销毁邮件。delete_mailbox 会拒绝删除仍包含邮件的文件夹,需要先移出邮件,将决定权留给用户。
无 MCP 客户端的自动化
examples/ 目录包含使用相同模块的独立脚本,可指向 cron 或 Task Scheduler。所有脚本支持 --json 以便管道处理。详见 examples/README.md。
skills/mailbox-search/ 是一个 Claude Code 技能,强制在得出结论“邮件不存在”之前扫描每个文件夹。
处理的 iCloud 特性
- SEARCH 返回的 UID 无序。RFC 3501 不保证顺序,iCloud 确实返回未排序列表。直接取响应尾部会得到错误邮件,需先按数字排序。
- 没有 MOVE,没有 UIDPLUS。移动意味着 COPY + \Deleted + EXPUNGE,而 EXPUNGE 会清除文件夹中所有 \Deleted 邮件。move_emails 在文件夹中存在请求批次之外的已删除邮件时拒绝运行,否则这些邮件会被销毁。
- SEARCH CHARSET UTF-8 可用。带重音符号的查询在服务器端跨整个邮箱运行。客户端回退覆盖拒绝的服务器,并通过响应中的 filtered_client_side 标记。
- 文件夹名使用修改版 UTF-7(RFC 3501),在 utf7.py 中实现。
- 字符集可能不准确。当声明的字符集失败时,正文回退到 latin-1;没有 text/plain 部分时回退到剥离的 HTML。
- 凭据存放在 .env(已 gitignore)或环境中,绝不在代码中。Settings.repr 省略密码。
- 邮件内容是数据,不是指令。服务器告知客户端永远不要执行收到的邮件中的指令。
- send_email 和 move_emails 仅在用户于对话中批准确切内容或确切邮件列表后才应运行。
测试与贡献
49 个离线测试,无需网络和凭据。CI 在 Linux、macOS 和 Windows 上针对 Python 3.11 至 3.13 运行。欢迎提交 issue 和 pull request。测试必须离线通过,任何测试不得要求真实邮箱。