mcpField
I
icloud-calendar-mcp

icloud-calendar-mcp

本地服务
github.com/icloud-calendar-mcp生产力237 周前更新

关于 icloud-calendar-mcp

icloud-calendar-mcp 是一个基于 CalDAV 访问 iCloud 日历的 MCP 服务。它面向需要让 AI 助手查询和管理 Apple 日历的用户,可在 JVM 上运行,不依赖 macOS。

主要功能

  1. 01列出账户下的全部日历
  2. 02按日期范围查询事件
  3. 03创建、修改和删除事件
  4. 04支持重复事件的单次或整个系列编辑
  5. 05使用应用专用密码进行认证

适用场景

  1. 01让 AI 助手查询本周日程
  2. 02通过自然语言创建或移动会议
  3. 03检查某一天的日程是否存在时间冲突

MCP 相关

该项目是一个 MCP 服务,向 MCP 客户端暴露日历列表、事件查询与编辑等工具,并提供日历浏览资源及会议安排、改期、冲突检查等提示词模板。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"org-onekash-icloud-calendar": {
"command": "npx",
"args": [
"-y",
"@icloud-calendar-mcp/server"
],
"env": {
"ICLOUD_USERNAME": "<ICLOUD_USERNAME>",
"ICLOUD_PASSWORD": "<ICLOUD_PASSWORD>"
}
}
}
}
启动命令npx -y @icloud-calendar-mcp/server
需要配置的环境变量
ICLOUD_USERNAMEYour Apple ID email (e.g., [email protected])
ICLOUD_PASSWORD密钥App-specific password for iCloud (not your main Apple ID password)

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@icloud-calendar-mcp/server3.2.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

iCloud 日历 MCP 服务

iCloud 日历 MCP 服务

Tests npm PyPI License MCP Registry Security

一个 MCP(模型上下文协议)服务,通过 CalDAV 为 AI 助手提供 iCloud 日历访问能力,并采用符合 OWASP MCP Top 10 的安全控制措施。

注意

切勿使用你的主要 Apple ID 密码。 此服务需要使用专用 App 密码,该密码可单独撤销,不会影响你的 Apple ID。

为什么选择此服务

  • 便携的 CalDAV。 只要能运行 JVM,就能运行此服务。它不依赖 macOS、AppleScript 或 Calendar.app。
  • 持久的事件句柄。 get_events 和 create_event 会返回一个不透明的 handle,用于在不同会话和进程重启后引用事件,因此编辑或删除事件时无需重新列出事件。
  • 正确处理重复事件。 系列事件会在指定范围内按每次发生展开为单个结果;你可以编辑或删除单次事件、本次及后续事件,或整个系列。
  • 有界响应。 日期范围和事件数量达到上限时,会返回清晰、结构化的错误,而不是静默截断响应。
  • 安全性符合 OWASP MCP Top 10,并由专门的测试套件提供保障。
  • 已发布到 MCP Registry、npm 和 PyPI。

功能

MCP 工具
工具描述只读具有破坏性
list_calendars列出 iCloud 账户中的所有日历是否
get_events获取日历指定日期范围内的事件是否
create_event创建新的日历事件否否
update_event更新事件(整个系列或单次事件)否否
delete_event删除事件(整个系列或单次事件)否是
MCP 资源
资源描述
calendar://calendars浏览可用日历
MCP 提示词

由用户发起的模板,可引导 Claude 完成多步骤任务:

提示词描述
schedule_meeting根据标题、参会者和时长拟定事件,然后创建该事件
reschedule查找现有事件,然后编辑以调整时间
find_conflicts列出某天的事件并报告时间重叠的时段
安全功能
  • 凭据保护 - 仅使用环境变量,不写入代码或配置文件
  • 输入验证 - 验证所有参数并提供 SSRF 防护
  • 速率限制 - 按照 MCP 规范,每分钟限制 60 次读取、20 次写入
  • 安全错误处理 - 错误消息不会泄露敏感数据
  • 符合 OWASP MCP Top 10 - 282 项安全测试,覆盖所有主要风险
  • ReDoS 防护 - 测试所有正则表达式模式,以防范灾难性回溯
  • Unicode 安全 - 防范同形异义字符和编码攻击

快速开始

前置条件
安装

选择你偏好的安装方式:

重要

所有选项运行的都是同一个 Java 构建。**必须在 PATH 中配置 Java 21 或更高版本,使用 npx 和 uvx 时也不例外。**这些包装器会下载并启动 JAR;它们不会替代 JVM。

选项 1:npm(推荐)
npx @icloud-calendar-mcp/server
选项 2:Python(uvx)
uvx icloud-calendar-mcp
选项 3:直接使用 JAR
# Download the latest release (version-agnostic name, always resolves)
curl -LO https://github.com/icloud-calendar-mcp/icloud-calendar-mcp/releases/latest/download/icloud-calendar-mcp-all.jar

# Run
java -jar icloud-calendar-mcp-all.jar
选项 4:从源代码构建
git clone https://github.com/icloud-calendar-mcp/icloud-calendar-mcp.git
cd icloud-calendar-mcp
./gradlew fatJar
java -jar build/libs/icloud-calendar-mcp-*-all.jar
配置

将你的 iCloud 凭据设为环境变量:

export ICLOUD_USERNAME="[email protected]"
export ICLOUD_PASSWORD="your-app-specific-password"

安全提示:请使用应用专用密码,不要使用你的 Apple ID 主密码。


Claude Desktop 集成

将以下内容添加到 Claude Desktop 配置中:

平台配置路径
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Linux~/.config/claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json
使用 npm(推荐)
{
  "mcpServers": {
    "icloud-calendar": {
      "command": "npx",
      "args": ["@icloud-calendar-mcp/server"],
      "env": {
        "ICLOUD_USERNAME": "[email protected]",
        "ICLOUD_PASSWORD": "your-app-specific-password"
      }
    }
  }
}
使用 uvx(Python)
{
  "mcpServers": {
    "icloud-calendar": {
      "command": "uvx",
      "args": ["icloud-calendar-mcp"],
      "env": {
        "ICLOUD_USERNAME": "[email protected]",
        "ICLOUD_PASSWORD": "your-app-specific-password"
      }
    }
  }
}
直接使用 JAR
{
  "mcpServers": {
    "icloud-calendar": {
      "command": "java",
      "args": ["-jar", "/path/to/icloud-calendar-mcp-all.jar"],
      "env": {
        "ICLOUD_USERNAME": "[email protected]",
        "ICLOUD_PASSWORD": "your-app-specific-password"
      }
    }
  }
}

使用示例

配置完成后,你可以向 Claude 提问:

  • “我这周的日历上有什么安排?”
  • “明天下午 2 点和 John 创建一个会议”
  • “显示我的所有日历”
  • “删除周五的牙医预约”
  • “把我下午 3 点的会议改到下午 4 点”
工具参数
list_calendars

无需参数。

get_events
参数类型必填说明
calendar_idstring是日历标识符(来自 list_calendars)
start_datestring是开始日期(YYYY-MM-DD)
end_datestring是结束日期(YYYY-MM-DD)

需要了解的行为:

  • UTC 日期边界。 start_date 和 end_date 会选取完整的 UTC 日历日:从 start_date 当天的 UTC 00:00 到 end_date 当天结束。定时事件会返回 UTC startTime/endTime 时刻;全天事件会返回纯 YYYY-MM-DD。若要确定用户在其他时区的某一天,请在两侧各额外查询一天,并保留开始时间转换到该时区后落在目标日期的事件;全天事件是浮动日期,无需转换。
  • 限制。 日期范围最多为 366 天,且 end_date 不得早于 start_date。响应最多包含 1000 个事件;如果单个重复系列展开后产生过多事件,则会被拒绝。若达到上限,请每次查询一周或一个月。
  • 重复系列。 范围内的每次出现都会作为独立结果返回,并带有自己的 handle,以及用于标识该实例的 recurrenceId。
  • 写入后读取。 iCloud 不保证数据立即可见,因此刚创建的事件可能会在短时间内未出现在下一次 get_events 查询中。这是 CDN 索引延迟,并非事件已删除,请勿重新创建。

每个结果都包含 uid、handle、summary、isAllDay,以及 startTime/endTime(定时事件)或 startDate/endDate(全天事件);此外还会包含已设置的 description、location、rrule、recurrenceId、status、url、categories、priority、organizer、attendeeCount 中的任意字段。

create_event
参数类型必填描述
calendar_idstring是目标日历
titlestring是事件标题
start_timestring条件必填定时事件的 ISO 8601 日期时间。无时区值(2026-01-15T09:00:00)会被视为 UTC,除非设置了 timezone;带 Z 或偏移量的值表示绝对时间点,会覆盖 timezone
end_timestring条件必填定时事件的 ISO 8601 日期时间(规则与 start_time 相同)
start_datestring条件必填全天事件的开始日期 YYYY-MM-DD
end_datestring条件必填全天事件的结束日期 YYYY-MM-DD,含当天
is_all_dayboolean否是否为全天事件
descriptionstring否事件描述
locationstring否事件地点
timezonestring否定时事件的 IANA 时区(例如,America/New_York)
end_timezonestring否结束时间的 IANA 时区;当其与开始时间不同时使用(例如航班)。默认使用 timezone
rrulestring否重复规则(例如,FREQ=WEEKLY;BYDAY=MO)
rdatesstring[]否额外的发生日期(RFC 5545 RDATE)
exdatesstring[]否排除的发生日期(RFC 5545 EXDATE)
alarmsobject[]否事件提醒(参见 提醒)
update_event

仅修改传入的字段。

参数类型必填描述
event_idstring是事件的引用。建议使用 get_events/create_event 返回的不透明 handle;对于本次会话中之前获取的事件,也可以使用单独的 UID(参见引用事件)
titlestring否新标题
start_timestring否新的开始时间(ISO 8601,规则与创建时相同)
end_timestring否新的结束时间(ISO 8601)
start_datestring否全天事件的新开始日期(YYYY-MM-DD)
end_datestring否全天事件的新结束日期(YYYY-MM-DD)
is_all_dayboolean否改为全天事件
descriptionstring否新描述
locationstring否新地点
timezonestring否IANA 时区(例如,America/New_York)
end_timezonestring否结束时间的 IANA 时区;当其与开始时间不同时使用
rrulestring否重复规则
rdatesstring[]否替换 RDATE(省略则保留,空数组则清除)
exdatesstring[]否替换 EXDATE(省略则保留,空数组则清除)
alarmsobject[]否替换提醒(省略则保留,空数组则清除,传入列表则替换;参见提醒)
scopestring条件必填指定重复事件编辑影响哪些发生项(参见编辑重复事件)。当 handle 指向系列中的某个发生项时必填
delete_event
参数类型必填描述
event_idstring是事件的引用。建议使用不透明的 handle;对于本次会话中之前获取的事件,也可以使用单独的 UID
scopestring条件必填指定重复事件删除会移除哪些发生项(参见编辑重复事件)。当 handle 指向系列中的某个发生项时必填
引用事件

get_events 和 create_event 会为每个事件返回两个标识符:uid 和不透明的 handle。将 handle 传给 update_event 和 delete_event。它是自包含的,可在全新进程中使用,因此常规流程是先调用 get_events(或 create_event)获取 handle,再用它调用 update_event/delete_event。跨会话无需额外查询。

也可以使用单独的 uid,但仅限于在同一会话中较早获取的事件,此时会通过短期内存缓存解析。服务端不支持无状态的 UID 查询:iCloud 会拒绝 CalDAV calendar-query UID prop-filter(HTTP 412),而不带筛选条件的查询会返回整个日历。建议使用 handle。

handle 包含事件的 ETag。如果自 handle 签发后,事件在其他地方发生了更改,编辑操作会报告冲突,而不是覆盖较新的版本;请重新运行 get_events 获取新的 handle,然后重试。成功时,update_event 会返回一个携带新 ETag 的更新后 handle,因此在一连串编辑中,下一次编辑应使用该 handle。

编辑重复事件

get_events 会为重复系列中的每次出现返回一条结果,每条结果都有自己的 handle。编辑或删除某个出现项的 handle 时,请设置 scope:

  • this_occurrence:仅更改或取消该实例。
  • this_and_future:更改该实例及之后的所有实例。
  • all_events:整个系列。

当 handle 指向系列中的某个出现项时,必须设置 scope。未设置时,操作会被拒绝,因此单个出现项的编辑不会意外更改整个系列。对于独立事件,请省略 scope。rrule、rdates 和 exdates 不能与 this_occurrence 或 this_and_future 组合使用。

提醒

create_event 和 update_event 接受一个 alarms 数组。每个条目都是一个对象:

字段必填描述
trigger是相对时长(-PT15M、-P1D)或绝对 UTC 时间点(20260115T093000Z)
action否DISPLAY(默认值)、AUDIO 或 EMAIL
description否提醒文本(DISPLAY 的默认值为 "Reminder")
summary否主题行,仅适用于 EMAIL
repeat_count否重复次数
repeat_duration否重复间隔(RFC 5545 时长)

调用 update_event 时,省略 alarms 可保留现有提醒;传入空数组可清除提醒;传入列表则会替换提醒。


故障排除

新事件不会立即显示。 iCloud 不保证事件会立即可见,因此刚创建的事件可能会在短时间内未出现在下一次 get_events 的结果中(CDN 索引延迟)。create_event 的成功响应是权威结果。请勿重新创建事件。

get_events 返回大小或数量错误。 查询范围过大。请一次查询一周或一个月;响应最多包含 1000 个事件。

身份验证失败。 请使用应用专用密码,而不是 Apple ID 密码,并将 ICLOUD_USERNAME 设置为完整的 iCloud 电子邮件地址。

不确定该使用哪个 calendar_id。 调用 list_calendars,并使用目标日历的 id。

重复事件编辑被拒绝或更改了每个实例。 请设置 scope(参见编辑重复事件):出现项的 handle 需要设置为 this_occurrence、this_and_future 或 all_events。

时间看起来因时区而偏移。 get_events 使用 UTC 日期边界(参见 get_events)。创建定时事件时请传入 timezone,并使用额外一天的方法来解析本地日期。


安全

此服务以安全为首要考虑进行设计,并遵循 OWASP MCP Top 10 指南。

隐私

该服务仅与您的机器(通过 STDIO)和 iCloud(caldav.icloud.com)通信。它不收集遥测数据,也不会将您的日历数据发送到其他任何地方。凭据来自环境变量,且绝不会记录到日志中。

安全控制
控制措施实现方式
凭据存储仅使用环境变量,绝不记录到日志中或对外暴露
输入验证验证所有输入(日历 ID、日期、时间、文本字段)
SSRF 防护阻止内部 IP、localhost 和危险的 URI 方案
速率限制滑动窗口:每分钟 60 次读取、20 次写入
错误处理从错误信息中清除密码、令牌、路径和电子邮件地址
注入防护正确转义 ICS 内容,并测试命令注入
ETag 规范化符合 RFC 7232,移除引号、W/ 前缀和 XML 实体
Content-Length 防护在缓冲前提前拒绝过大的响应
熔断器防止故障级联,并支持自动恢复
审计日志通过 MCP logging protocol(MCP08)记录 CUD 操作
ReDoS 防护测试所有正则表达式模式,防止灾难性回溯
Unicode 安全防护形近字符、规范化和编码绕过
OWASP MCP Top 10 覆盖情况
风险缓解措施测试数
MCP01:令牌管理不当在日志和错误信息中遮蔽凭据,并安全存储14
MCP02:权限提升固定工具集,不进行动态注册5
MCP03:工具参数注入输入验证、参数化操作8
MCP04:敏感数据暴露错误信息清理、凭据遮蔽10
MCP05:命令注入将输入视为数据,而非执行内容3
MCP06:提示词注入将恶意文本作为数据存储,而非进行解释3
MCP08:不安全日志记录速率限制、敏感数据清理31
MCP09:资源耗尽速率限制、输入大小限制、DoS 防护25
MCP10:上下文过度共享状态隔离,不会在请求间泄露数据3

完整的安全文档和漏洞披露流程请参阅 SECURITY.md。


测试

测试分布在两个位置:MCP 服务模块和 vendored icaldav-core iCalendar 库。两者均可通过以下命令运行:

./gradlew test
测试覆盖率(MCP 服务)
类别测试数描述
安全282对抗性输入、OWASP MCP Top 10、ReDoS、Unicode
CalDAV 协议181XML 解析、HTTP 客户端、模型、ETag 规范化
ICS 格式150RFC 5545 解析、构建、修补
错误处理56安全错误响应、凭据清理
集成45端到端工具、符合 MCP 规范、注释
输入验证44所有参数验证规则
服务层26日历操作、缓存
速率限制18并发访问、窗口重置
取消12操作取消、清理
日志记录9符合 MCP 日志规范
进度9进度报告
E2E11实时 CalDAV + 端到端集成
安全测试类别
类别测试数覆盖范围
对抗性输入53SQL/NoSQL 注入、XSS、路径遍历
ICS 补丁器安全43CRLF 注入、属性注入、编码攻击
Unicode 安全38同形异义字符、规范化、RTL 覆盖
日志记录器安全31日志注入、凭据清理
OWASP MCP 风险29MCP01-10 特定攻击向量
进度安全27令牌枚举、注入
ReDoS 防护25灾难性回溯、资源耗尽
取消操作安全22重放攻击、竞态条件
凭据安全14令牌屏蔽、安全存储
运行特定测试
# All tests
./gradlew test

# Security tests only
./gradlew test --tests "*SecurityTest*"
./gradlew test --tests "AdversarialTest"

# OWASP MCP specific tests
./gradlew test --tests "OwaspMcpSecurityTest"

# Unicode security tests
./gradlew test --tests "UnicodeSecurityTest"

# ReDoS protection tests
./gradlew test --tests "ReDoSSecurityTest"

# CalDAV tests
./gradlew test --tests "*CalDav*"

# ICS tests
./gradlew test --tests "*Ics*"

架构

+------------------------------------------------------------------+
|                    MCP Server (STDIO Transport)                    |
|                                                                    |
|  +----------------+  +----------------+  +----------------------+  |
|  | Rate Limiter   |  |   Input        |  |  Secure Error        |  |
|  | 60r/20w/min    |  |  Validator     |  |  Handler             |  |
|  +----------------+  +----------------+  +----------------------+  |
|                                                                    |
|  +----------------+  +----------------+  +----------------------+  |
|  | MCP Logger     |  | Cancellation   |  |  Progress            |  |
|  | (RFC 5424)     |  | Manager        |  |  Reporter            |  |
|  +----------------+  +----------------+  +----------------------+  |
|                                                                    |
|  Tools: list_calendars | get_events | create_event |               |
|         update_event | delete_event                                |
|                                                                    |
|  Resources: calendar://calendars                                   |
+------------------------------------------------------------------+
                              |
                              v
+------------------------------------------------------------------+
|                      CalendarService                               |
|  Orchestrates CalDAV operations, caches calendar metadata          |
+------------------------------------------------------------------+
                              |
                              v
+------------------------------------------------------------------+
|                      CalDAV Client Layer                           |
|                                                                    |
|  +-------------------+  +-------------------+  +----------------+  |
|  | OkHttpCalDav      |  |  IcsParser        |  |  IcsBuilder    |  |
|  | Client            |  |  (icaldav-core)   |  |  (icaldav-core)|  |
|  +-------------------+  +-------------------+  +----------------+  |
|                                                                    |
|  +-------------------+  +-------------------+  +----------------+  |
|  | ICloudXml         |  |  IcsPatcher       |  |  EtagUtils     |  |
|  | Parser            |  |  (event edits)    |  |  (RFC 7232)    |  |
|  +-------------------+  +-------------------+  +----------------+  |
|                                                                    |
|  +-------------------+                                             |
|  | Credential        |                                             |
|  | Manager           |                                             |
|  +-------------------+                                             |
+------------------------------------------------------------------+
                              |
                              v
+------------------------------------------------------------------+
|                    iCloud CalDAV API                               |
|                    caldav.icloud.com                               |
+------------------------------------------------------------------+

开发

构建
# Build
./gradlew build

# Build fat JAR
./gradlew fatJar

# Run tests
./gradlew test

# Clean build
./gradlew clean build
项目结构
src/main/kotlin/org/onekash/mcp/calendar/
├── Main.kt                 # MCP server entry point
├── caldav/                 # CalDAV protocol implementation
│   ├── CalDavClient.kt     # Client interface
│   ├── CalDavModels.kt     # Domain models
│   ├── OkHttpCalDavClient.kt
│   ├── ICloudXmlParser.kt
│   └── EtagUtils.kt        # RFC 7232 ETag normalization
├── ics/                    # ICS format handling (via icaldav-core)
│   ├── IcsParser.kt        # Parse iCalendar data
│   ├── IcsBuilder.kt       # Generate iCalendar data
│   └── IcsPatcher.kt       # Patch existing events (CRLF-safe)
├── service/                # Business logic
│   └── CalendarService.kt  # CalDAV orchestration + event cache
├── security/               # Security controls
│   └── CredentialManager.kt
├── validation/             # Input validation
│   └── InputValidator.kt
├── error/                  # Error handling
│   └── SecureErrorHandler.kt
├── ratelimit/              # Rate limiting
│   └── RateLimiter.kt
├── logging/                # MCP logging
│   └── McpLogger.kt
├── progress/               # Progress reporting
│   └── ProgressReporter.kt
└── cancellation/           # Operation cancellation
    └── CancellationManager.kt
使用 MCP Inspector 进行测试
ICLOUD_USERNAME="[email protected]" \
ICLOUD_PASSWORD="test-app-password" \
npx @mcp-use/inspector java -jar build/libs/icloud-calendar-mcp-*-all.jar

贡献

欢迎贡献!请参阅 CONTRIBUTING.md 了解指南。

安全问题

如需报告安全漏洞,请参阅 SECURITY.md 了解我们的负责任披露流程。请勿公开提交安全漏洞相关问题。


许可证

本项目采用 Apache License 2.0 许可,详情请参阅 LICENSE 文件。


致谢

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。