关于 Apple Reminders MCP Server
Apple Reminders MCP Server 通过 EventKit 将 MCP 客户端连接到 macOS 的提醒事项和日历应用,可管理提醒事项、列表、子任务及日历事件,并支持筛选和权限处理。
主要功能
- 01创建、读取、更新和删除提醒事项
- 02管理列表、子任务和日历事件
- 03按日期、优先级、标签和文本筛选
- 04以结构化结果保留 EventKit 数据
适用场景
- 01整理带标签和优先级的提醒及子任务
- 02按截止日期等条件查找提醒事项
- 03通过 MCP 客户端创建或更新日历事件
MCP 相关
将提醒事项、列表、子任务和日历事件操作作为 MCP 工具提供,并返回结构化 JSON 结果。读写操作使用 macOS EventKit 权限。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
5收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | enum | 是 | 要执行的操作。read | create | update | delete |
| id | string | 否 | 提醒的唯一标识符(更新、删除时必填;读取单个提醒时可选)。 |
| title | string | 否 | 提醒的标题(创建时必填,更新时可选)。 |
| dueDate | string | 否 | 到期日期。推荐格式:'YYYY-MM-DD HH:mm:ss'(不带时区的本地时间,例如 '2025-11-04 18:00:00')。也支持:'YYYY-MM-DD'、'YYYY-MM-DDTHH:mm:ss' 或带时区的 ISO 8601(例如 '2025-10-30T04:00:00Z')。未指定时区时,将时间视为本地时间。 |
| note | string | 否 | 提醒的附加备注。 |
| url | string | 否 | 要关联到提醒的 URL。 |
| completed | boolean | 否 | 将提醒标记为已完成/未完成(仅限更新)。 |
| priority | enum | 否 | 优先级:0=无,1=高,5=中,9=低(用于创建/更新)。0 | 1 | 5 | 9 |
| targetList | string | 否 | 创建或更新操作所用列表的名称。 |
| filterList | string | 否 | 按指定列表名称筛选提醒。 |
| showCompleted | boolean | 否 | 在结果中包含已完成的提醒。 |
| search | string | 否 | 用于按标题或备注筛选提醒的搜索词(获取后在 TS 中应用)。 |
| dueWithin | enum | 否 | 按到期日期范围筛选提醒(获取后在 TS 中应用)。today | tomorrow | this-week | overdue | no-date |
| startDate | string | 否 | 开始日期。当 action='update' 时:设置提醒的开始日期(CLI 无法在创建时设置)——格式为 'YYYY-MM-DD'、'YYYY-MM-DD HH:mm:ss' 或 ISO 8601。当 action='read' 时:到期日期范围的开始日期,作为 `--start` 传递给 CLI(包含开始日期)。对于 read,仅使用日期部分——任何时间/时区部分都会截断为日期前缀,因此范围按天解析。如果 read 只提供 startDate/endDate 中的一个,另一个将补全为 14 天的范围。 |
| endDate | string | 否 | 到期日期窗口的结束日期(仅限读取,action='read')。通过 `--end` 传递给 CLI;结束日不包含在内。仅使用日期部分——任何时间/时区部分都会截断为日期前缀(按天粒度)。如果只提供 startDate/endDate 中的一个,另一个将按 14 天窗口填充。 |
| filterPriority | enum | 否 | 按优先级筛选提醒。high | medium | low | none |
| filterRecurring | boolean | 否 | 为 true 时,仅显示重复提醒。 |
| filterLocationBased | boolean | 否 | 为 true 时,仅显示基于位置的提醒。 |
| filterTags | array | 否 | 按标签筛选提醒(必须包含所有指定标签)。示例:["work", "urgent"] |
| tags | array | 否 | 要在提醒上设置的标签(创建时)。替换所有现有标签。示例:["work", "urgent"] |
| addTags | array | 否 | 要添加到提醒的标签(更新时)。与现有标签合并。示例:["followup"] |
| removeTags | array | 否 | 要从提醒中移除的标签(更新时)。示例:["urgent"] |
| subtasks | array | 否 | 随提醒一起创建的初始子任务(create 操作)。请提供子任务标题数组。示例:["Buy milk", "Get eggs", "Pick up bread"] |
详细介绍
Apple Events MCP 服务

English | 简体中文
一款 Model Context Protocol(MCP)服务,通过 EventKit 框架在 macOS 上原生集成 Apple Reminders 和 Calendar。它通过标准化接口提供提醒事项、列表、子任务和日历事件,并支持完整的 CRUD 操作。
EventKit 后端是独立的 event Swift CLI,以 git 子模块形式引入,并在 pnpm install 期间构建到 bin/event——无需单独执行 brew install。有关 v1.5.0 后端切换,以及 event 尚未提供的写入字段列表,请参阅 docs/migration-to-event-cli.md。
目录
功能
- 支持对提醒事项、子任务、提醒事项列表和日历事件进行完整的 CRUD 操作
- 支持优先级(高/中/低/无)、标签和带进度跟踪的清单子任务
- 多条件筛选:完成状态、到期日期范围、优先级、标签、全文搜索、重复事项、基于位置的筛选
- 支持灵活的日期格式(
YYYY-MM-DD、YYYY-MM-DD HH:mm:ss、ISO 8601),并考虑时区 - 通过 EventKit 原生集成 macOS——在 Reminders.app/Calendar.app 中配置的值会在读取响应中原样返回
- 自动发现并请求 macOS 权限
- 完整支持 Unicode,并提供全面的输入验证
前置条件
- Node.js 20 或更高版本
- macOS(EventKit 必需)
- Xcode Command Line Tools(仅从源代码构建时需要)
- pnpm(推荐)
已发布的 npm 包包含预构建的通用代码签名 bin/event 二进制文件,因此使用 npx 的用户无需安装 Xcode 或 Swift 工具链。从 git 克隆构建则需要满足上述条件。
快速开始
npx mcp-server-apple-events
配置
将此服务添加到你的 MCP 客户端。以下客户端均可使用 npx 配置;如需使用本地构建,请将 command/args 替换为指向 dist/index.js 的 node 命令。
Cursor
设置 → MCP → 添加新的全局 MCP 服务:
{
"mcpServers": {
"apple-reminders": {
"command": "npx",
"args": ["-y", "mcp-server-apple-events"]
}
}
}
ChatWise
设置 → 工具 → “+”,然后填写:
- 类型:
stdio - ID:
apple-reminders - 命令:
mcp-server-apple-events - 参数:(留空)
Claude Desktop
编辑 claude_desktop_config.json(可通过设置 → 开发者选项 → 编辑配置打开,或在 macOS 上直接打开 ~/Library/Application Support/Claude/claude_desktop_config.json/在 Windows 上打开 %APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"apple-reminders": {
"command": "npx",
"args": ["-y", "mcp-server-apple-events"]
}
}
}
本地构建的配置:
{
"mcpServers": {
"apple-reminders": {
"command": "node",
"args": ["/absolute/path/to/mcp-server-apple-events/dist/index.js"]
}
}
}
连接本地服务的方法请参阅 MCP 官方文档。请完全重启 Claude Desktop(退出应用,而不只是关闭窗口),以使更改生效。
macOS 权限
服务会直接启动随附的 event CLI。macOS 会保留对启动服务的应用程序的正常归因,因此请在 System Settings > Privacy & Security > Reminders / Calendars 中授权该宿主。每个宿主都需要单独批准;在终端中授予的权限不会授权独立的桌面 MCP 客户端。
宿主必须支持 EventKit 权限请求,并声明所需的用途描述。如果不支持,macOS 可能会拒绝访问,且不显示提示。请使用支持这些权限的宿主。服务不会通过让公共辅助程序自行承担责任来绕过此限制:这样会允许无关的本地进程重复使用该辅助程序获得的 Calendar 和 Reminders 权限。
当 event 检测到 notDetermined 状态时,会调用 requestFullAccessToReminders / requestFullAccessToEvents。请在相同的宿主上下文中运行 ./check-permissions.sh 来诊断访问权限;在终端中运行时,只会检查该终端的权限。受保护的资源需要用途描述;请参阅Apple 的应用分发指南。
Calendar 读取错误或未显示提示
如果出现 Failed to read calendar events,请在 System Settings > Privacy & Security > Calendars 下为调用应用启用 Full Calendar Access。如果未显示提示,请检查宿主是否支持 EventKit 权限并声明了用途描述,然后重启宿主并重试。AppleScript Automation 的批准与 EventKit Calendar 和 Reminders 的批准相互独立。
从责任免责声明辅助程序升级
重新安装软件包以移除旧的 bin/event-disclaim 产物。如果是源码检出,请在重新构建前移除该生成文件。在 System Settings > Privacy & Security > Reminders / Calendars 中撤销旧的 event 授权,然后为你打算使用的每个宿主授权。更新服务无法撤销现有的 macOS 授权,也无法移除安装在其他位置的旧副本。
无 GUI 的 / launchd 运行挂起而非失败
当服务在没有 GUI 会话的上下文中运行(SSH、launchd 代理/守护进程)时,首次调用 EventKit 可能会无限期阻塞,等待一个永远无法显示的权限提示——MCP 请求始终无法完成,并且每次调用都会泄漏一个子进程。现在,服务会终止任何运行超过 30 s 的 event 调用(SIGKILL),并返回易于理解的错误。可通过 EVENTKIT_CLI_TIMEOUT_MS 环境变量调整该时限(单位为毫秒;无效值或零值将回退到默认值——无法禁用超时,但接受最高 2^31-1 ms 的超大值)。随附的 event CLI(通过 FradSer/event#15 固定版本)还会在没有 GUI 会话时快速失败,并在等待无法响应的提示 15 s 后放弃(EVENT_PERMISSION_TIMEOUT_MS),并报告 Permission denied: Timed out waiting for ...,以便宿主在服务终止进程前显示特定于权限的消息(15 s < 30 s)。请参阅问题 #113。
macOS 26(Tahoe)could not build module 'Foundation'
如果 pnpm build 失败并显示 could not build module 'Foundation'(或 SDK is not supported by the compiler),说明你的 Swift 工具链版本低于 macOS 26 SDK 的要求——需要 Swift 6.3 或更高版本,但 macOS 26 早期小版本随附的 Command Line Tools 包含 Swift 6.2.x。pnpm build:event 会检测此情况并输出相同的解决方法;请参阅问题 #85。可通过从 App Store 安装 Xcode 26.x,或将 Command Line Tools 更新至 Swift 6.3+ 版本来解决:
softwareupdate --list
sudo softwareupdate -i "Command Line Tools for Xcode-<latest>"
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer # if full Xcode is installed
xcrun swiftc --version # should report Apple Swift version 6.3 or newer
使用示例
配置完成后,让 Claude 与 Apple Reminders 和 Calendar 交互。提示词示例:
Create a reminder to "Buy groceries" for tomorrow at 5 PM with tags shopping and errands.
Add a high-priority reminder to "Finish quarterly report" due Friday in my "Work" list.
Create "Grocery shopping" with subtasks: milk, eggs, bread, butter.
Show me all high-priority reminders due today tagged "urgent".
Show subtasks for my "Grocery shopping" reminder and mark "milk" as complete.
Update "Buy groceries" — change the title to "Buy organic groceries" and set priority to high.
Show reminders from my "Work" list, and list all my reminder lists.
Create a calendar event "Team standup" tomorrow from 9:00 to 9:30 in "Work".
Show my calendar events for the next week.
Invite [email protected] to my "Team standup" event.
Cancel just the September 21 occurrence of my weekly "Team standup".
服务会处理自然语言请求,与 Apple 原生的 Reminders 和 Calendar 应用交互,并返回结构化结果。
此服务只能读取闹钟、重复规则和位置触发条件,无法修改;请在 Reminders.app / Calendar.app 中配置。如果底层应用提供这些值,读取工具会在结构化记录中保留它们。
写入确认和不可信数据
默认情况下,服务端写入确认处于关闭状态。 不支持 MCP 表单征询的客户端也可以写入。创建、更新、删除、子任务切换/重新排序、邀请参会者以及更改关联事件,都会在没有服务端确认表单的情况下执行。删除操作可能会移除项目,邀请或日历变更可能会通知其他人。此设置改变了 v1.6.0 的默认行为,并移除了该版本针对提示注入设置的逐次写入确认屏障。
如需每次写入都要求用户重新确认,请在 MCP 服务参数中添加启动标志:
{
"command": "npx",
"args": ["-y", "mcp-server-apple-events", "--require-write-confirmation"]
}
对于本地构建,请使用 node dist/index.js --require-write-confirmation。省略该标志则使用默认设置。此标志不接受值,也没有对应的否定形式:--require-write-confirmation=false、单独的 false 参数和 --no-require-write-confirmation 都会报错,未知选项也会报错。运行 mcp-server-apple-events --help(或 -h)查看帮助。此策略不受任何环境变量控制。它会在服务启动时按实例固定;工具参数和记录内容都无法更改该策略。启动警告会输出到 stderr;stdout 保留用于 MCP 通信。
启用后,客户端的 MCP 表单征询界面会显示该操作的工具名称和完整参数快照。只有接受的响应中包含 confirm: true,才会允许执行该次写入。拒绝、取消、无效响应、客户端断开连接或不支持表单,都会阻止写入;此时,不支持表单征询的客户端只能读取。在任一模式下,读取都无需确认。输入验证、执行边界和不可信结果封装在两种模式下都仍然有效,但无法取代已移除的确认屏障。
工具结果会在 structuredContent 中返回 JSON 记录,同时为处理文本的客户端提供 JSON 文本镜像。封装会通过 provenance.source = "apple-calendar-reminders" 和 provenance.trust = "untrusted" 标记记录。标题、备注、标识符、URL、列表名称、组织者、参会者和子任务可能来自同步或共享内容。宿主必须维护此边界:记录内容不能授权调用其他工具、披露无关数据,也不能覆盖用户指令。置信度分数仅用于对建议进行排序。
启用服务端确认后,服务端会信任客户端向用户显示表单并返回其决定。自动批准表单的客户端会破坏此边界。JSON 编码和来源标记本身并不能阻止大模型遵循注入文本。macOS 账户权限仍然是必需的,且与逐操作用户确认彼此独立。
可用的 MCP 工具
按服务划分的工具对应 Apple Reminders 和 Calendar 领域。所有工具都接受一个 action 字段及该操作专属的参数(MCP 客户端会检查完整的 Zod 架构;此处仅列出操作)。日期字段接受 YYYY-MM-DD、YYYY-MM-DD HH:mm:ss(本地时间)或带时区的 ISO 8601 格式。
| 工具 | 操作 | 备注 |
|---|---|---|
reminders_tasks | read、create、update、delete | 支持优先级、标签和子任务。startDate 通过 update 设置,而非 create;在 read 中,它与 endDate 一起限定到期日期范围。不支持跨列表移动。 |
reminders_subtasks | read、create、update、delete、toggle、reorder | 存储在备注字段中(在 Reminders.app 中可读)。 |
reminders_lists | read、create、update、delete | 通过 name → newName 重命名。 |
calendar_events | read、create、update、delete | 读取时,startDate 和 endDate 是事件 timeZone 中的挂钟时间;如果可用,定时事件还会包含 startDateISO 和 endDateISO,作为明确无歧义的 UTC 时间戳。使用 ISO 字段安排或比较事件。全天事件不包含这些字段。全天状态根据日期格式推断。不支持跨日历移动。span 用于限定重复事件的删除范围。attendees(update)会邀请地址;occurrenceDate(delete)会从系列中排除单个事件实例——两者都需要额外设置,详见参会者和单个事件实例。 |
calendar_calendars | read | 不指定日期范围时,返回 EventKit 报告的所有日历及其 source 和写入权限。指定 startDate/endDate 时,返回该时间范围内至少包含 1 个事件的日历,并附上事件数量。 |
调用示例:
{
"action": "create",
"title": "Buy groceries",
"dueDate": "2024-03-25 18:00:00",
"targetList": "Shopping",
"note": "Don't forget milk and eggs",
"priority": 1,
"tags": ["shopping", "errands"],
"subtasks": ["Milk", "Eggs", "Bread"]
}
{ "action": "read", "filterList": "Work", "dueWithin": "today", "filterPriority": "high", "filterTags": ["urgent"] }
{ "action": "read", "startDate": "2026-08-01", "endDate": "2026-08-31" }
{ "action": "update", "id": "reminder-123", "completed": false, "addTags": ["followup"] }
{ "action": "toggle", "reminderId": "reminder-123", "subtaskId": "a1b2c3d4" }
{ "action": "create", "name": "Project Alpha" }
{ "action": "create", "title": "Team standup", "startDate": "2026-05-04 09:00:00", "endDate": "2026-05-04 09:30:00", "targetCalendar": "Work" }
{ "action": "update", "id": "event-123", "attendees": ["[email protected]", "[email protected]"] }
{ "action": "delete", "id": "event-123", "occurrenceDate": "2026-09-21T09:00:00" }
参与者和单次操作
这两个 calendar_events 参数是唯一不通过 event CLI 执行的写入,因为 EventKit 无法表达其中任何一项。每项都需要进行服务器其他部分不需要的设置。
attendees(更新) — 向现有事件邀请电子邮件地址。macOS SDK 中的 EKCalendarItem.attendees 是只读的,而且 EventKit 没有邀请 API,因此写入会通过 Calendar.app 的脚本接口完成;在本地添加参与者后,iCloud 才会发送邀请。
- 需要 Automation 授权:首次调用时会提示,且相应条目会显示在
System Settings > Privacy & Security > Automation下。需要 GUI 会话,因此无法在无头环境中使用。 - 必须单独更新参与者。参与者通过 Calendar.app 处理,而其他所有字段都通过 EventKit 处理,二者没有共享的并发令牌——组合更新无法安全确定顺序,因此会被拒绝。请分两次调用。
- 如果有两个事件的标题和开始日期相同,操作会直接拒绝,而不会猜测目标。Calendar.app 只能按标题和日期查询,若写入错误事件,就会向该事件发送真实邀请。
occurrenceDate(删除) — 仅排除循环系列中的某次事件。每次事件都共享一个 EventKit 标识符,因此 span: "this-event" 只能排除系列的首次事件;如果目标是之后的某次事件,则不会写入任何内容,但仍会报告成功。提供 occurrenceDate 后,删除操作会通过 CalDAV 执行,从而直接定位该实例。
-
需要 iCloud 凭据。设置
ICLOUD_APPLE_ID和ICLOUD_APP_PASSWORD,或者设置ICLOUD_APPLE_ID并将密码存储在 Keychain 中:security add-generic-password -a "[email protected]" -s "icloud-caldav-mcp" -w请使用应用专用密码,切勿使用账户密码。凭据会先从环境变量读取,然后从 Keychain 读取;绝不会从 MCP 客户端配置中读取,也绝不会写入日志。
-
只有同步到 iCloud 的事件才符合条件——没有外部标识符的事件没有可供定位的 CalDAV 资源。
-
CalDAV 请求在重定向和读取响应期间的总时限为 30 秒,响应大小上限为 2 MiB。日历编辑还限制资源最多包含 20000 行物理行/内容行、每条展开后的 UTF-8 行不超过 64 KiB、最多 16 层嵌套组件、2000 个事件和 1000 个重复 ID。资源过大或过于复杂时,会在写入日历之前返回可采取操作的错误;序列化后的输出也必须符合相同的大小和行数限制。
读取响应结构
读取工具会返回一个 structuredContent 封套,其 records 数组包含该工具返回的领域对象。原生值会予以保留,包括数字形式的提醒优先级(0、1、5 或 9),而不是展示标签。例如:
{
"provenance": {
"source": "apple-calendar-reminders",
"trust": "untrusted"
},
"records": [
{
"id": "reminder-123",
"title": "Buy groceries",
"isCompleted": false,
"list": "Shopping",
"notes": "Don't forget milk and eggs",
"url": "https://example.com",
"dueDate": "2024-03-25T18:00:00Z",
"priority": 1,
"tags": ["shopping", "errands"],
"subtasks": [
{ "id": "a1b2c3d4", "title": "Milk", "isCompleted": true },
{ "id": "e5f6a7b8", "title": "Eggs", "isCompleted": false },
{ "id": "c9d0e1f2", "title": "Bread", "isCompleted": false }
],
"subtaskProgress": { "completed": 1, "total": 3, "percentage": 33 }
}
]
}
随附的 content 数组会先包含静态文本摘要(例如 Read reminders.),随后是包含同一 structuredContent 对象序列化 JSON 镜像的文本项。使用文本的客户端可以解析第二项;支持结构化结果的客户端应使用 structuredContent。
提醒 URL 会存储在原生 url 属性以及结构化的 URLs: 备注块中。日历事件 URL 会存储在 EventKit 的原生 URL 属性中。两者都会拒绝不安全的 URI 方案和被屏蔽的 HTTP(S) 地址。
只读字段:提醒闹钟、提醒重复规则和位置触发条件、日历重复规则和结构化位置、全天事件开关,以及跨日历移动,均无法通过此服务器写入。可以通过创建/更新来设置日历事件闹钟、URL 和日程可用性。设置日历可用性时,日历必须支持所选值。其余差异请参阅 docs/migration-to-event-cli.md。
结构化提示词库
此服务提供一个提示词注册表,通过 MCP 的 ListPrompts / GetPrompt 端点公开。每个模板都包含任务目标、上下文输入、编号步骤、约束、输出格式和质量标准,为下游助手提供可预测的框架。
- daily-task-organizer — 可选的
today_focus;生成当天的执行蓝图,平衡优先事项与恢复时间,并自动为今天到期的提醒创建日历时间块。 - smart-reminder-creator — 可选的
task_idea;生成经过优化排期的提醒结构。 - reminder-review-assistant — 可选的
review_focus(例如overdue或列表名称);审核并优化现有提醒。 - weekly-planning-workflow — 可选的
user_ideas;引导用户从周一到周日重新规划,并创建与现有列表关联的时间块。
提示词仅使用 Apple Reminders 的原生功能,并会在执行不可逆操作前询问缺失的上下文。修改提示词文案后,运行 pnpm test -- src/server/prompts.test.ts。
开发
pnpm install # postinstall builds bin/event from vendor/event on macOS
pnpm build # TypeScript + vendored event CLI
pnpm test # Jest suite: repositories, schemas, build script, prompt templates
pnpm exec biome check # lint + format
CLI 入口最多向上遍历十个目录以查找 package.json,因此服务可以从嵌套路径(例如 dist/ 或编辑器任务运行器)启动,而不会丢失 bin/event。如果自定义文件夹布局,请确保清单在此深度范围内可访问。
脚本
pnpm build— TypeScript + 随附的eventCLI(从源代码运行前必须执行)pnpm build:ts— 仅 TypeScriptpnpm build:event— 仅随附的eventCLI(swift build -c release→bin/event)pnpm build:release— 构建并进行公证(发布打包)pnpm test/pnpm test:ci— Jest 测试套件 / 并生成覆盖率pnpm lint— Biome 格式化/修复 + TypeScript 类型检查pnpm check— lint + 带覆盖率的测试
许可证
MIT
贡献
欢迎贡献!请先阅读贡献指南。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。