关于 icloud-mcp
icloud-mcp 是用于访问 iCloud 日历的 Go MCP 服务,也可选启用通讯录和邮件。它通过 CalDAV、CardDAV、IMAP 和 SMTP 连接,并可通过环境设置选择启用的域及写入操作。
主要功能
- 01日历读取和写入工具
- 02可选访问通讯录
- 03可选读取、修改和发送邮件
- 04只读模式可禁用修改操作
- 05通过 stdio 传输 JSON-RPC
适用场景
- 01搜索日程并查找空闲时间
- 02创建或更新日历项目
- 03启用后搜索联系人
- 04启用后读取或发送 iCloud 邮件
MCP 相关
icloud-mcp 通过 stdio 提供 JSON-RPC,并将已启用的 iCloud 域作为 MCP 工具公开。未启用的域及其工具不会注册。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
icloud-mcp
通过 Model Context Protocol 访问 iCloud 日历、联系人和邮件。一个 Go 二进制程序通过 stdio 提供 JSON-RPC,并使用 CalDAV、CardDAV、IMAP 和 SMTP 连接。
该服务使用 App 专用密码,可在无图形界面环境中运行。它使用远程协议,不依赖 macOS 框架、浏览器自动化或 Apple 私有 API。 发布压缩包支持 Linux amd64/arm64 和 macOS arm64。CI 也会构建 Windows amd64 版本。
任何 stdio MCP 宿主都可以通过进程环境启动该二进制程序。
该程序不会加载 .env 或特定宿主的配置文件。
| 领域 | 协议 | 默认状态 |
|---|---|---|
| 日历 | CalDAV HTTPS | 始终启用(读写,除非全局设为只读) |
| 联系人 | CardDAV HTTPS | 默认关闭,需设置 ICLOUD_MCP_ENABLE_CONTACTS |
| 邮件读取 | IMAP TLS | 默认关闭,需设置 ICLOUD_MCP_ENABLE_MAIL |
| 邮件修改 | IMAP | 默认关闭,需启用邮件并设置 ICLOUD_MCP_ENABLE_MAIL_WRITE |
| 邮件发送 | SMTP STARTTLS | 默认关闭,需启用邮件、设置 ICLOUD_MCP_ENABLE_MAIL_SEND 并配置收件人策略 |
提醒事项、备忘录、照片、云盘、查找、钥匙串、信息和家庭不在支持范围内。新版提醒事项不使用此服务的 CalDAV 连接器。
快速开始
预构建压缩包可从 GitHub Releases 下载。 每个压缩包都包含二进制程序、许可证和第三方声明。请将压缩包的 SHA-256 值与发布校验和文件进行比对。每个资源文件还附有 cosign 签名和证书。
安装 GitHub CLI 和 Cosign。运行这些命令前,请先对 GitHub CLI 进行身份验证。必要时将 platform 改为 linux-arm64 或 darwin-arm64。
version=$(gh release view --repo ThomasCrouzet/icloud-mcp --json tagName --jq .tagName)
platform=linux-amd64
asset="icloud-mcp-${version}-${platform}.tar.gz"
checksums="icloud-mcp-${version}-checksums.txt"
gh release download "$version" --repo ThomasCrouzet/icloud-mcp \
--pattern "$asset*" --pattern "$checksums"
grep " $asset$" "$checksums" | shasum -a 256 -c -
cosign verify-blob \
--certificate "$asset.pem" \
--signature "$asset.sig" \
--certificate-identity "https://github.com/ThomasCrouzet/icloud-mcp/.github/workflows/ci.yml@refs/tags/${version}" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"$asset"
tar -xzf "$asset"
./icloud-mcp -version
或者,使用 Go 1.26.0 或更高版本:
go install github.com/ThomasCrouzet/icloud-mcp/cmd/icloud-mcp@latest
- 创建一个应用专用密码。切勿使用 Apple Account 主密码。
- 将身份信息和密码分别存储在仓库外的普通文件中。
- 将每个文件的权限设置为
0600或更严格,并将文件大小限制在 4 KiB 以内。 - 设置环境变量,以启用日历只读访问:
export ICLOUD_EMAIL='file:///private/path/icloud-email'
export ICLOUD_PASSWORD='file:///private/path/icloud-password'
export ICLOUD_MCP_READ_ONLY=true
export ICLOUD_MCP_DEFAULT_TZ=Europe/Paris # owner IANA zone; default UTC
- 在 MCP 宿主中注册二进制程序的绝对路径和环境变量。
- 配置变更后,重启 MCP 进程。
stdio 用于传输 JSON-RPC。stderr 用于输出日志和修改操作审计事件。 该服务仅在启动时读取凭据文件。日历发现需要在 stdio 启动前访问网络。
此配置会开放 7 个工具:日历读取、本地辅助工具和 icloud_capabilities。该进程不会创建联系人或邮件客户端。
可选领域(仍采用与宿主无关的 export 格式):
# Contacts reads (writes also need ICLOUD_MCP_READ_ONLY=false)
export ICLOUD_MCP_ENABLE_CONTACTS=true
# Mail reads: IMAP identity may differ from ICLOUD_EMAIL (e.g. [email protected])
export ICLOUD_MCP_ENABLE_MAIL=true
export ICLOUD_MAIL_ADDRESS='file:///private/path/icloud-mail-address'
# Optional separate password; otherwise Mail uses ICLOUD_PASSWORD.
# export ICLOUD_MAIL_PASSWORD='file:///private/path/icloud-mail-password'
# Mail mutation (flags / move / trash); independent of send
export ICLOUD_MCP_ENABLE_MAIL_WRITE=true
export ICLOUD_MCP_READ_ONLY=false
# Mail send: requires exact recipient allowlist even under global read-only
export ICLOUD_MCP_ENABLE_MAIL_SEND=true
export ICLOUD_MCP_SMTP_ALLOWED_RECIPIENTS='[email protected],[email protected]'
完整的 12 个变量约定请参阅 .env.example。
MCP 工具
服务最多暴露 23 个工具。已禁用的工具不会出现在
tools/list 中。进程不会为已禁用的域创建客户端。
| 数量 | 条件 |
|---|---|
| 10 | 默认:日历读写 + icloud_capabilities |
| 7 | 全局只读,可选域关闭(建议首次运行时使用) |
| 23 | 通讯录 + 邮件读取 + 修改 + 发送,关闭只读模式 |
ICLOUD_MCP_READ_ONLY=true 会移除所有日历/通讯录写入、所有邮件修改以及邮件发送。它不会启用已禁用的读取域。
| 分组 | 工具 |
|---|---|
| 全局 | icloud_capabilities |
| 日历读取 | list_calendars、search_events、get_event、find_free_slots、validate_event、calendar_capabilities |
| 日历写入 | create_event、update_event、delete_event |
| 通讯录读取 | list_address_books、search_contacts、get_contact |
| 通讯录写入 | create_contact、update_contact、delete_contact |
| 邮件读取 | list_mailboxes、search_messages、get_message |
| 邮件修改 | set_message_flags、move_message、trash_message |
| 邮件发送 | send_message |
日历更新和删除操作支持事件实例,并使用强 If-Match。通讯录使用不透明的通讯录 ID,并以 vCard 3.0 格式写入。
邮件使用 (mailbox, UIDVALIDITY, UID) 标识、PEEK 读取,并对 SMTP 采用严格的收件人策略。move_message 会拒绝将邮件移至 SPECIAL-USE Trash 和 Junk 目的地。删除邮件请使用 trash_message。
如果服务器声明支持 CONDSTORE,set_message_flags 会通过
protocol_error 安全失败。这是因为 go-imap
beta.8 无法读取带标签的 MODIFIED。完整行为说明见:
docs/caldav-compatibility.md、
docs/carddav-compatibility.md、
docs/mail-compatibility.md。
创建 UID 与更新幂等性
create_event 和 create_contact 使用 client_uid 或其别名 idempotency_key
作为资源 UID。如果该 UID 已存在,创建操作会返回 conflict。
它绝不会静默覆盖对象。
只有 update_event 和 update_contact 会通过 idempotency_key 缓存结果。
进程本地缓存最多保存 1,024 条记录,每个负载最大为 256 KiB。
相同的键和参数会返回已保存的结果。不同的参数会返回
conflict。成功结果和确定性错误会保留 15 分钟。结果未知的请求会一直保留到进程退出。待处理的请求占用不会过期。
缓存已满时,会在写入前拒绝新的请求占用。请保留该键并等待缓存腾出空间。
收到有歧义的响应后,请先使用 get_event 或 get_contact,再进行新的更新。
使用新键或重启进程并不能证明先前的写入失败。
确有必要进行新更新时,请使用新的强 etag。
配置
产品环境变量恰好有 12 个:
| 变量 | 默认值 | 约定 |
|---|---|---|
ICLOUD_EMAIL | 无 | Calendar/Contacts 必需的身份信息。支持 file://(普通文件,<=4 KiB,权限为 0600+)。 |
ICLOUD_PASSWORD | 无 | 必需的专用应用密码。Mail 会将其用作备用密码。支持上述 file://。 |
ICLOUD_MCP_READ_ONLY | false | 全局变更熔断开关。 |
ICLOUD_MCP_LOG_LEVEL | info | Stderr 日志级别。可接受的形式见下文。 |
ICLOUD_MCP_DEFAULT_TZ | UTC | 用于无时区偏移的 Calendar 输入和循环写入回退的 IANA 时区。 |
ICLOUD_MCP_ENABLE_CONTACTS | false | Contacts 工具。写入要求关闭只读模式。 |
ICLOUD_MCP_ENABLE_MAIL | false | Mail 读取功能。需要 Mail 地址和密码。 |
ICLOUD_MAIL_ADDRESS | 无 | Mail 启用时使用的完整 IMAP/SMTP 地址。支持上述 file://。 |
ICLOUD_MAIL_PASSWORD | ICLOUD_PASSWORD | 可选的专用 Mail 应用密码。支持上述 file://。 |
ICLOUD_MCP_ENABLE_MAIL_WRITE | false | 三个 IMAP 变更工具。 |
ICLOUD_MCP_ENABLE_MAIL_SEND | false | send_message(独立于 Mail 写入)。 |
ICLOUD_MCP_SMTP_ALLOWED_RECIPIENTS | 无 | 启用发送时必需。使用精确地址或字面量 *。字面量 * 会触发启动警告。尽可能使用精确地址。 |
布尔值仅接受未设置、0、false、1 或 true。无效值会导致
启动失败。服务器会在访问网络之前验证配置。
主机必须将这些值作为字符串传递。在 YAML 中为布尔值加引号,例如
ICLOUD_MCP_READ_ONLY: "false"。未加引号的 YAML 布尔值会在服务器启动前
导致主机验证失败。
未启用 Mail 却启用 Mail 写入或发送会导致启动错误。启用 Mail 却未设置地址或密码也会导致启动错误。未设置收件人策略却启用发送会导致启动错误,即使处于只读模式也是如此。
全局只读可以与写入和发送标志同时启用,但会阻止注册这些功能。
服务器会去除日志级别两端的空白并忽略大小写。它接受 debug 或 -4、
info、warn、warning 或 2,以及 error 或 4。未设置或无法识别的
值会使用 info。
使用 -version 打印版本。可选的
-health 127.0.0.1:port 标志会在 loopback 上提供 /healthz 和 /status。这两个
端点都会返回包含域和速率限制的 JSON。可选的 -audit-format=json|text 标志用于选择 stderr 上的变更审计格式。
默认格式为 json。
日期
- Calendar 输入
start和end接受带偏移量的 RFC3339 格式。也 接受使用ICLOUD_MCP_DEFAULT_TZ的无偏移墙上时钟值。用户本地时间请使用无偏移值。循环创建以及指定时区的创建会写入 TZID 和 VTIMEZONE。非循环定时创建默认在线路上使用 UTCZ。全天创建使用VALUE=DATE。 - Calendar 输出中的定时事件使用 RFC3339 格式。始终包含
ICLOUD_MCP_DEFAULT_TZ中明确的数字偏移量,不会使用裸Z。全天日期使用YYYY-MM-DD。参见calendar_capabilities.outputFormat。 - Contacts 生日:仅写入
YYYY-MM-DD。 - Mail 搜索:
since包含该日期,before不包含该日期(YYYY-MM-DD)。
安全(摘要)
不可信的远程文本可能影响宿主上的大模型。标签并不能构成安全边界。遭到入侵的模型可以调用所有已注册的工具。此风险适用于所有宿主和供应商。
- **固定出站目标:**日历使用
caldav.icloud.com和匹配p[0-9]{1,3}-caldav.icloud.com:443的主机。联系人使用匹配的 Contacts 主机。IMAP 使用imap.mail.me.com:993。SMTP 使用smtp.mail.me.com:587,并强制使用 STARTTLS。目标不可配置。服务会忽略 DAV 代理环境变量,并验证 TLS 1.2 或更高版本。 - **隔离:**每个域都有独立的凭据、传输、拨号器、限流器、信号量和协议栈。没有经过身份验证的 HTTP 客户端会连接多个域。
- **密钥:**服务会移除密钥,包括 Basic 和 SASL PLAIN 形式。仅在启动时进行的
file://读取要求权限为 0600 或更严格。服务不使用os/exec,也不进行遥测。启动后不会写入磁盘。 - **审计:**变更日志包含
domain、resourceType和进程本地的 HMACresourceToken。日志绝不会包含原始路径、UID、邮箱或收件人。 - **剩余风险:**一个进程会持有所有已启用域的凭据。功能标志不会移除已编译的代码。如需更强的隔离,请使用只读模式并减少启用的域。也可以使用专用的 Mail 密码或多个独立进程。
完整策略:SECURITY.md、docs/security.md。 架构:docs/architecture.md。
限制(摘要)
| 工具期限 | 25s(DAV HTTP 为 30s) |
| Stdio / MCP 结果 | 1 MiB 帧。结果为 256 KiB。反射的协议错误有大小限制。 |
| 日历 | 搜索范围:366 天。结果:总计 400 个,每个日历 2,500 个,所有日历合计物化 10,000 个。重复事件:展开 2,000 次,每个系列 100k 步,每次搜索 250k 步。速率:每分钟读取 60 次、写入 20 次。并发:4 次读取、2 次写入。 |
| 联系人 | 100 个通讯录。100 个摘要。扫描 2000 张名片。速率:每分钟读取 60 次、写入 20 次。并发:4 次。 |
| 邮件 | 速率:每分钟读取 60 次、变更 20 次、发送 20 次。信号量:2 次读取、1 次变更、1 次发送。变更或发送均不会重试。 |
| 写入 | 不会自动重放 Calendar PUT/DELETE、联系人写入、IMAP 变更或 SMTP 操作。结果不明确时会使用 outcome_unknown。 |
服务会在启动时发现日历,并在首次使用时发现联系人。每次调用都会使用新的 IMAP 或 SMTP 会话。有关速率、解析器预算和重试规则,请参阅以下文档: docs/testing.md、docs/architecture.md。
多个账户
一个进程只持有一个 iCloud 身份。每个身份都应启动一个独立进程。 为每个进程提供独立的环境和可选的健康检查端口。 参阅宿主集成。
依赖项
使用 Go 1.26.0 或更高版本。项目只有一个模块,且恰好有 10 个直接依赖项。如果添加直接依赖项,请在此处说明其用途。
| 依赖项 | 精确版本 | 用途 |
|---|---|---|
github.com/emersion/go-webdav | v0.7.0 | CalDAV 基础功能。发现和条件操作仍由手动编写的代码实现。 |
github.com/emersion/go-ical | v0.0.0-20250609112844-439c63cef608 | iCalendar 解析/编码 |
github.com/mark3labs/mcp-go | v1.2.0 | MCP 标准输入/输出、架构、JSON-RPC |
github.com/teambition/rrule-go | v1.8.2 | 保留时区信息的有界重复规则 |
golang.org/x/time | v0.16.0 | 按域名设置的速率限制器 |
github.com/emersion/go-vcard | v0.1.0 | 读取 vCard 3.0/4.0,写入 3.0 |
github.com/emersion/go-imap/v2 | v2.0.0-beta.8 | 通过 internal/mail/imapadapter 使用 IMAP |
github.com/emersion/go-message | v0.18.2 | MIME/纯文本限制 |
github.com/emersion/go-smtp | v0.25.0 | SMTP + STARTTLS |
github.com/emersion/go-sasl | v0.0.0-20241020182733-b788ff22d5a6 | STARTTLS 后使用 SASL PLAIN |
构建和测试
make build # local host binary, VERSION defaults to dev
make test # go test ./... -race -cover
make lint # go vet + pinned golangci-lint
make release VERSION=v1.2.3 # packaged linux/arm64, digest-pinned Go 1.26.10 image
make release-all VERSION=v1.2.3 # packaged linux/amd64, linux/arm64, darwin/arm64 (host Go)
make install # host-compatible build to INSTALL_DIR (default ~/.local/bin)
发布目标要求工作树干净,且版本号格式如 v1.2.3。如果发布输出已存在,则不会覆盖。归档包含二进制文件、LICENSE 和 THIRD_PARTY_NOTICES.md。dist/ 目录还包含 SHA-256 校验和文件。GitHub 标签发布仅在该标签对应的 CI 和 gitleaks 检查成功后运行 make release-all。发布使用 Go 1.26.10,并禁用 check-latest。
本地运行 make release 时,linux/arm64 使用固定摘要的容器路径。发布文件包含 cosign 无密钥签名。-version 首先使用发布 ldflags 值。如果该值不存在,则使用 Go 模块构建信息。因此,go install ...@version 会报告模块版本。
CI 会检查格式、竞争测试、漏洞、机密信息、公开文本和多架构构建。CI 会强制执行覆盖率下限和 20 MiB 的二进制文件大小限制。发布标签 CI 会对所有解析器包运行模糊测试冒烟测试。手动工作流选项也可运行相同的测试。
实时测试需要 integration 构建标签,以及显式的域名/写入门控。CI 不会运行这些测试。请参阅测试。
如需仅使用夹具生成协议证据,请使用仓库外的绝对输出路径:
make protocol-evidence EVIDENCE_DIR=/external/path
运行器会从 cmd/icloud-mcp 测试构建可执行文件,并使用共享的 MCP 注册和标准输入/输出启动代码。它还会运行进程内幂等性和重复规则场景。运行器会在仓库外保存记录、运行元数据、源代码版本、工作区差异、夹具 SHA-256 值和结果。
CI 会在运行器上生成这些证据,并在作业结束后将其丢弃。
CI 不会在 GitHub 上上传或归档报告。这些检查使用合成夹具,无法证明与实时 iCloud 的兼容性。
文档
| 文档 | 用途 |
|---|---|
| 宿主集成 | 标准输入/输出设置、机密文件、运行状况检查、多个账户、调用方行为 |
| 错误代码 | 重试规则和变更恢复 |
| 架构 | 启动、域边界、并发、更新幂等性 |
| CalDAV 兼容性 | 日历发现、条件写入、重复规则、限制 |
| CardDAV 兼容性 | 联系人发现、vCard 支持、搜索、条件写入 |
| 邮件兼容性 | IMAP 会话、消息标识、变更、SMTP 提交 |
| 安全策略和实现 | 威胁模型、问题报告和技术控制措施 |
| 测试 | 本地检查、协议证据、CI 和实时集成门控 |
| 贡献指南 | 开发、文档编写、测试策略和支持 |
| 变更日志 | 发布历史 |
致谢
日历工具的结构和一些模式的灵感来自
github.com/roygabriel/mcp-icloud-calendar
(MIT,版权所有 2026 Gabe)。代码经过重写,并非复制。本服务还提供
严格的按域名出口限制、脱敏、有界解析器、条件式修改、
通讯录、邮件功能,并且不进行遥测。
贡献
请参阅 CONTRIBUTING.md。提交拉取请求前,请运行 gofmt、make test 和 make lint。
许可证
MIT。请参阅 LICENSE 和 THIRD_PARTY_NOTICES.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。