mcpField
M
MustDo

MustDo

远程服务
ltng.jp生产力02 周前更新

关于 MustDo

MustDo 是用于通过 Claude 等 MCP 客户端管理 MustDo iOS 闹钟待办事项的 MCP 服务。它访问用户 iCloud 私有 CloudKit 数据库,提供托管 OAuth 中继或供开发者使用的本地 stdio 方式。

主要功能

  1. 01按日期和状态列出待办事项
  2. 02添加、更新、完成、延后和删除待办事项
  3. 03支持重复计划和截止时间
  4. 04将待办记录保存在用户的 iCloud CloudKit 数据库
  5. 05提供托管中继和本地 stdio 方式

适用场景

  1. 01查看日期范围内待处理或已完成的待办事项
  2. 02创建带截止时间的闹钟待办事项
  3. 03更新重复任务或标记某次任务完成
  4. 04通过 MCP 客户端延后或删除待办事项

MCP 相关

MustDo 将账户和待办事项操作作为 MCP 工具提供。托管中继通过 OAuth 使用远程 MCP;开发者可在本地通过 stdio 运行服务。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://ltng.jp/api/mustdo/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

mustdo-mcp

点击此处查看日语版(README.ja.md)

MustDo 的 MCP 服务——一款 iOS 待办闹钟,会持续响铃,直到你完成待办。

它让 Claude(Claude Code、Claude Desktop、claude.ai、Claude iPhone app)和任何其他 Model Context Protocol 客户端读取和写入你的 MustDo 待办事项。

  • 你的数据保存在自己的 iCloud 中。 MustDo 没有自己的待办事项数据库。它们存储在你 Apple ID 的 CloudKit private 数据库中(容器 iCloud.jp.lightning.mustdo,区域 MustDo)。 此服务与 Apple 的 CloudKit Web Services 通信,并读取和写入与 iPhone 应用相同的记录。
  • 开发者绝不会存储你的待办事项。 本仓库中的本地服务和托管中继(见下文)都不会在 Lightning LLC 的服务器上保留待办事项内容。
  • 写入后,CloudKit 会向你的 iPhone 推送静默通知,因此应用会立即更新。

两种使用方式

A. 托管中继(推荐)B. 在本地运行此仓库(开发者)
可使用的平台claude.ai、Claude iPhone app,以及支持远程 MCP + OAuth 的任何客户端Mac 上的 Claude Code / Claude Desktop(stdio)
设置添加自定义连接器,使用 Apple ID 登录Node 24、构建、配置并登录。需要 CloudKit API Token,目前不对外公开提供(见下文)
Lightning LLC 存储的内容仅你的 CloudKit 登录令牌,使用 AWS KMS 加密(见下文)无
A. 托管中继 — https://ltng.jp/api/mustdo/mcp
  1. claude.ai → 设置 → 连接器 → 添加自定义连接器 → URL https://ltng.jp/api/mustdo/mcp(命名为“MustDo”)。
  2. 点击连接。你会看到 ltng.jp 上的同意页面,说明存储的内容,随后会跳转到 Apple 登录页面。 使用你在 MustDo 应用中使用的同一个 Apple ID登录。
  3. 完成。此连接器也可在 Claude iPhone app 中使用。

中继会保留的内容,如实说明:

  • 登录时,Apple 会签发 CloudKit 登录令牌(ckWebAuthToken)。中继会使用 AWS KMS 加密此令牌(AWS 东京区域),以便在每次请求时代表你调用 CloudKit。
  • 它也会存储连接器本身的哈希 OAuth 访问令牌和刷新令牌。
  • 它不会存储或记录你的待办事项内容、Apple ID 邮箱、密码或原始 iCloud 用户 ID。
  • **断开连接:**在 claude.ai 中移除连接器,并且访问 https://ltng.jp/api/mustdo/disconnect。 使用 Apple ID 确认后,存储的令牌会立即删除。如果 Apple 使登录失效,令牌也会自动删除(此时工具会返回 RECONNECT_REQUIRED;只需重新连接)。

完整说明:https://ltng.jp/mustdo/mcp。

B. 在本地运行(stdio)

要求:

  • 安装了 Node.js 24 或更高版本的 macOS
  • 已安装 MustDo 应用,且至少同步到 iCloud 一次(应用会创建区域和 Account 记录)
  • MustDo 容器的 CloudKit API Token。目前不对公众提供——见下文“关于 CloudKit API Token”。没有此令牌时,请使用托管中继(A)
git clone https://github.com/lightning-llc-jpn/mustdo-mcp mustdo-mcp
cd mustdo-mcp
npm install
npm run build        # -> dist/index.js
npm test             # vitest; CloudKit is mocked

在 Claude Code 中注册:

claude mcp add mustdo \
  -e MUSTDO_CK_API_TOKEN=<MUSTDO_CK_API_TOKEN> \
  -e MUSTDO_CK_ENV=production \
  -- node /path/to/mustdo-mcp/dist/index.js

或者将设置放入 ~/.mustdo/config.json,并在不使用 -e 的情况下注册:

{
  "apiToken": "<MUSTDO_CK_API_TOKEN>",
  "environment": "production"
}

然后让 Claude 运行一次 sign_in 工具。服务会在浏览器中打开 Apple 登录页面, 监听 http://localhost:51234/callback,并将返回的令牌保存到 ~/.mustdo/auth.json(模式 0600)。

关于 CloudKit API Token

CloudKit Web Services 的每个请求都需要两个 Token:

Token含义持有者
ckAPIToken用于标识容器(iCloud.jp.lightning.mustdo)。由容器所有者在 CloudKit Dashboard 中创建。Apple 设计它用于“从网站或嵌入式 Web 视图”访问,也就是说,它是一个客户端 Token,具有固定的 Sign-in Callback URL。Lightning LLC(该容器归 MustDo 开发者团队所有)。你无法自行创建——CloudKit Dashboard 只允许团队为自己的容器创建 Token。
ckWebAuthToken你的个人 CloudKit 会话,由 Apple 在你使用 Apple ID 登录时签发。这是实际授予你访问个人数据库权限的凭证。仅你持有。存储在 ~/.mustdo/auth.json 中。使用生产环境 Token 时,Apple 会在登录期间通过 ltng.jp 上的重定向返回该 Token(见下文;不会在那里存储或记录任何内容)。之后,该 Token 只会发送给 Apple。

API Token 适用于整个容器,最终用户无法创建。Lightning LLC 目前不公开分发该 Token,因此不向普通用户提供本地运行此服务的方式——请使用托管中继(A)。 发布代码是为了让你能准确查看 MCP 服务如何处理你的数据。

供参考,生产环境的 Token 将 Sign-in Callback 设置为 https://ltng.jp/api/mustdo/oauth/local-callback,它只会重定向回 http://localhost:51234/callback, 不会存储或记录任何内容。

配置

环境变量的优先级高于 ~/.mustdo/config.json。

环境变量config.json 键默认值含义
MUSTDO_CK_API_TOKENapiToken(必填)MustDo 容器的 CloudKit API Token
MUSTDO_CK_ENVenvironmentdevelopmentproduction 用于 App Store 数据。development 仅适用于 MustDo 开发者
MUSTDO_CK_CONTAINERcontaineriCloud.jp.lightning.mustdo保持不变
MUSTDO_CK_ZONEzoneNameMustDo保持不变
MUSTDO_CALLBACK_PORTcallbackPort51234登录回调监听的端口
MUSTDO_HOME—~/.mustdoconfig.json 和 auth.json 所在位置
MUSTDO_LOG_LEVEL—INFODEBUG / INFO / WARN / ERROR(在 stderr 上输出 JSON 行)

auth.json 按环境分别保存;切换 MUSTDO_CK_ENV 后需要再次运行 sign_in。 Apple 会在一段时间后使会话过期(CloudKit 会返回 HTTP 421);此时工具会返回 NOT_SIGNED_IN,你需要再次运行 sign_in。

工具

所有工具均返回 JSON。输出中的日期为 ISO 8601 格式(UTC)。输入中的日期可以是:

  • YYYY-MM-DD — 当天的默认时间(见下文)
  • YYYY-MM-DDTHH:mm — 账户时区的当地时间
  • 带偏移量的完整 ISO 8601 格式
工具参数功能
sign_inwaitSeconds?(5–300,默认 90)**仅限本地。**打开 Apple 登录页面并保存 ckWebAuthToken。中继上不提供此工具。
get_me—账户信息:timeZone、today、weekday、defaultTime、defaultDueNext、试用/订阅日期、canAddTodo。进行日期计算前请先调用此工具。
list_todosdate?、from?、to?(YYYY-MM-DD,含首尾日期)、status?(默认 pending / done / skipped / all)、includeRepeating?(默认 true)列出待办事项。已删除的待办事项不会列出。重复待办事项以模板的形式返回在 repeating 下(不会展开),并附带日期范围内每天的 occurrences。
add_todotitle(1–200)、due?、repeat?、notes?(≤2000)、sound?创建 source = "mcp" 的待办事项。如果省略 due,则设为明天的默认时间。
update_todoid、title?、due?、repeat?(对象或 null)、notes?(字符串或 null)、sound?、status?只更改传入的字段。repeat 会替换整个规则;null 或 { "kind": "none" } 会移除重复规则。
complete_todoid、occurrenceDate?一次性待办事项:status = done。重复待办事项:将当天的发生项标记为已完成(默认:今天)。
snooze_todoid、until、occurrenceDate?延后至 until。重复待办事项:仅延后当天的发生项。
delete_todoid软删除(deletedAt)。应用会在 14 天后彻底清除该待办事项。

**注意:**AI 客户端会根据你的指示添加、更改和删除待办事项。已删除的待办事项会在 14 天后从 iCloud 中移除,且无法恢复。请自行检查 AI 执行的操作结果。 delete_todo 标注为具有破坏性(destructiveHint),而 get_me / list_todos 标注为只读(readOnlyHint),因此支持这些标注的客户端会在删除前询问。

默认时间和省略 due 的情况

每个账户都有一个默认提醒时间(Account.defaultTime,格式为 HH:mm,在应用设置中设定;若未设置则为 09:00)。

  • add_todo 未提供 due → 设为明天(按账户时区)的默认时间。 月份/年份边界和夏令时转换均按当地时间计算。
  • due: "2026-10-10" → 设为当天的默认时间。
  • get_me 会返回 defaultTime 和 defaultDueNext,客户端可据此告知用户提醒何时响起。

示例:

// "Remind me to buy milk" → tomorrow at the default time
{ "title": "Buy milk" }

// "Call the dentist on the 10th" → that day at the default time
{ "title": "Call the dentist", "due": "2026-10-10" }

// "Today at 3pm"
{ "title": "Submit report", "due": "2026-10-06T15:00" }
重复规则

与 iOS Calendar app 使用相同的词汇。用作 add_todo / update_todo 的输入,并由 list_todos 返回。

{
  "kind": "none | daily | weekly | monthly | yearly",
  "interval": 1,                                   // 1 = every, 2 = every other … (1–99)
  "weekdays": [2, 4],                              // weekly only. 1 = Sun … 7 = Sat. Empty → weekday of `due`
  "monthly": { "mode": "dayOfMonth | weekdayOrdinal", "ordinal": 1, "weekday": 2 },
  "end": { "kind": "never | until | count", "until": "2026-12-31", "count": 10 }
}
需求repeat
每天{ "kind": "daily" }
每周一和周三{ "kind": "weekly", "weekdays": [2, 4] }
每隔一周{ "kind": "weekly", "interval": 2 }
每 3 天{ "kind": "daily", "interval": 3 }
每月 5 日{ "kind": "monthly" },并将 due 设为每月 5 日(29–31 日会调整为月末)
每月第一个星期一{ "kind": "monthly", "monthly": { "mode": "weekdayOrdinal", "ordinal": 1, "weekday": 2 } }
每月最后一个星期五{ "kind": "monthly", "monthly": { "mode": "weekdayOrdinal", "ordinal": -1, "weekday": 6 } }
每年{ "kind": "yearly" }(使用 due 的月/日;非闰年时,2 月 29 日 → 2 月 28 日)
执行 10 次后停止{ "kind": "daily", "end": { "kind": "count", "count": 10 } }
截止至 12 月 31 日{ "kind": "weekly", "weekdays": [2], "end": { "kind": "until", "until": "2026-12-31" } }

省略的字段使用默认值(interval 为 1,weekdays 为 [],monthly.mode 为 dayOfMonth,end.kind 为 never)。 取值范围:interval 为 1–99,ordinal 为 1–5 或 -1,weekday 为 1–7,count 为 1–999。其他值均会返回 INVALID_ARGUMENT。 仍接受旧版格式 { "kind", "weekdays", "until" }。

展开在 app 中进行,而非此处。 list_todos 会返回模板以及 occurrences (按天记录 done / skipped / snooze)。范围筛选仅会排除确定不可能在该范围内触发的模板(首次出现时间晚于范围、until 早于范围、每周规则没有匹配的星期几)。

错误

失败时会返回 isError: true,以及格式为 { "code": "...", "message": "...", "details"?: {...} } 的正文。

code含义
NOT_SIGNED_IN没有有效的 ckWebAuthToken(本地)。运行 sign_in。
RECONNECT_REQUIRED托管中继上发生相同问题。请在 claude.ai 中重新连接该连接器。
NOT_CONFIGUREDAPI Token 缺失或被 CloudKit 拒绝(HTTP 401/403)。
PAYMENT_REQUIRED账户试用期已结束,且没有有效订阅。仅影响 add_todo。
NOT_FOUND找不到此 To-Do,或它已被删除。
INVALID_ARGUMENT日期无效、重复规则超出范围、标题为空等。
CONFLICT另一台设备连续两次更改了记录。请重试。
CLOUDKIT_ERROR其他任何 CloudKit 错误(例如,应用从未同步导致区域缺失)。
SIGN_IN_TIMEOUT10 分钟的登录侦听器已过期。
INTERNAL意外错误。

安全模型

  • 只有通过你自己的 Apple ID 会话(ckWebAuthToken)才能访问你的 To-Dos,该会话由 Apple 的登录页面签发。 没有它,任何人——包括开发者——都无法读取你的私人数据库。
  • API Token 仅用于标识容器,并确定 Apple 登录后可以重定向到的位置。 Apple 将其定位为客户端 Token(通常会嵌入 CloudKit JS 网页中)。它本身不会授予访问任何用户私人数据的权限。
  • 本地环境中,会话存储在 ~/.mustdo/auth.json(0600)中,日志以 JSON 格式写入 stderr,且绝不包含 Token; 登录侦听器仅绑定到 127.0.0.1 / ::1。
  • 在中继上,会话按用户使用 AWS KMS 加密(采用加密上下文的信封加密),OAuth Token 仅以加盐的 SHA-256 哈希形式存储,必须使用 PKCE S256,刷新 Token 会轮换并检测重用,且 To-Do 内容绝不会写入存储或日志。
  • 写入时使用 CloudKit recordChangeTag(乐观锁定),冲突时重试一次;删除采用软删除。
  • 发现问题?请参阅 SECURITY.md。

开发

npm install
npm run build       # tsc → dist/
npm test            # vitest (CloudKit mocked in test/fakeCloudKit.ts)
npm run typecheck   # tsc --noEmit
MUSTDO_LOG_LEVEL=DEBUG node dist/index.js   # run the stdio server by hand

目录结构:

src/
  index.ts      entry point (stdio)
  server.ts     wiring for stdio: sign_in + the 7 To-Do tools
  tools.ts      tool definitions (zod schemas) shared by stdio and the relay
  core.ts       public entry for the shared core (no auth/config/stdio)
  service.ts    tool logic: filtering, upserts, conflict retry
  cloudkit.ts   thin CloudKit Web Services client (query / lookup / modify, 421 handling)
  records.ts    CloudKit record <-> model conversion
  dates.ts      time-zone-aware date math using Intl only
  auth.ts       auth.json and the sign-in callback listener
  config.ts     env / ~/.mustdo/config.json
  model.ts      enums, allowlists, RepeatRule types (mirrors the Swift app)
  errors.ts     ToolError / NotSignedInError
  log.ts        JSON logs to stderr (setLogSink to redirect)
test/           vitest

dist/core.js(包 exports)是托管中继使用的共享核心:除 auth.ts、config.ts、index.ts 和 server.ts 外的所有内容。请确保其中不包含任何访问本地文件系统或浏览器的代码。

工作流:从 issue 开始

每项更改都从 GitHub issue 开始。在提交说明中引用该 issue,格式为 Issue #N (例如 Fix the due-date default for repeating To-Dos (Issue #12);合并提交也一样),并在更改进入 main 后关闭该 issue。单独使用 #12 不予接受。

bash tools/git-hooks/install.sh   # once per clone: installs the commit-msg hook that enforces this

推送的提交会由 .github/workflows/issue-number.yml 再次检查。

许可证

MIT — Copyright (c) 2026 Lightning LLC。请参阅 LICENSE。

MustDo 是 Lightning LLC 的产品。Apple、iCloud 和 CloudKit 是 Apple Inc. 的商标。

评论

支持 Markdown

第一次接触 MCP?

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

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