mustdo-mcp
OfficialReads and writes the user's MustDo To-Dos stored in the private CloudKit database of their iCloud account (container iCloud.jp.lightning.mustdo), authenticating via Apple ID sign-in. Provides tools to list, add, update, complete, snooze, and soft-delete To-Dos (including repeating To-Dos with Calendar-style repeat rules), and changes are pushed back to the MustDo iOS app through iCloud.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mustdo-mcpadd a to-do alarm to pick up my dry cleaning tomorrow at 6pm"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mustdo-mcp
MCP server for MustDo — the iOS To-Do alarm that keeps ringing until you do it.
It lets Claude (Claude Code, Claude Desktop, claude.ai, the Claude iPhone app) and any other Model Context Protocol client read and write your MustDo To-Dos.
Your data stays in your iCloud. MustDo has no backend of its own. To-Dos live in the CloudKit private database of your Apple ID (container
iCloud.jp.lightning.mustdo, zoneMustDo). This server talks to Apple's CloudKit Web Services and reads/writes the same records as the iPhone app.The developer never stores your To-Dos. Neither the local server in this repository nor the hosted relay (see below) keeps To-Do content on Lightning LLC servers.
After a write, CloudKit pushes a silent notification to your iPhone, so the app updates right away.
Two ways to use it
A. Hosted relay (recommended) | B. Run this repository locally | |
Works from | claude.ai, Claude iPhone app, any client that supports remote MCP + OAuth | Claude Code / Claude Desktop on a Mac (stdio) |
Setup | Add a custom connector, sign in with your Apple ID | Node 24, build, configure, sign in |
What Lightning LLC stores | Your CloudKit sign-in token only, encrypted with AWS KMS (see below) | Nothing |
A. Hosted relay — https://ltng.jp/api/mustdo/mcp
claude.ai → Settings → Connectors → Add custom connector → URL
https://ltng.jp/api/mustdo/mcp(name it "MustDo").Click Connect. You will see a consent page on ltng.jp explaining what is stored, then Apple's sign-in page. Sign in with the same Apple ID you use in the MustDo app.
Done. The same connector is available in the Claude iPhone app.
What the relay keeps, honestly:
When you sign in, Apple issues a CloudKit sign-in token (
ckWebAuthToken). The relay stores this token encrypted with AWS KMS (AWS Tokyo region) so it can call CloudKit on your behalf on each request.It also stores hashed OAuth access/refresh tokens for the connector itself.
It does not store or log your To-Do content, your Apple ID email, your password, or your raw iCloud user ID.
Disconnect: remove the connector in claude.ai and visit https://ltng.jp/api/mustdo/disconnect. After confirming with your Apple ID, the stored token is deleted immediately. It is also deleted automatically when Apple invalidates the sign-in (the tools then return
RECONNECT_REQUIRED; just reconnect).
Full write-up: https://ltng.jp/mustdo/mcp.
B. Run locally (stdio)
Requirements:
macOS with Node.js 24 or newer
The MustDo app installed and synced to iCloud at least once (the app creates the zone and the
Accountrecord)A CloudKit API Token for the MustDo container — see the next section
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 mockedRegister with 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.jsOr put the settings in ~/.mustdo/config.json and register without -e:
{
"apiToken": "<MUSTDO_CK_API_TOKEN>",
"environment": "production"
}Then ask Claude to run the sign_in tool once. The server opens Apple's sign-in page in your browser,
listens on http://localhost:51234/callback, and saves the returned token to ~/.mustdo/auth.json (mode 0600).
About the CloudKit API Token
CloudKit Web Services needs two tokens on every request:
Token | What it is | Who has it |
| Identifies the container ( | Lightning LLC (the container belongs to the MustDo developer team). You cannot create one yourself — CloudKit Dashboard only lets a team create tokens for its own containers. |
| Your personal CloudKit session, issued by Apple when you sign in with your Apple ID. This is the credential that actually grants access to your private database. | Only you. Stored in |
Because the API Token is container-wide and cannot be created by end users, Lightning LLC provides the
value for local use. Use the value shown on https://ltng.jp/mustdo/mcp as MUSTDO_CK_API_TOKEN
(the token for the production environment has its Sign-in Callback set to
https://ltng.jp/api/mustdo/oauth/local-callback, which simply redirects back to http://localhost:51234/callback
without storing anything). If the page does not show a token, local use is not currently offered — use the hosted relay.
Configuration
Environment variables win over ~/.mustdo/config.json.
env | config.json key | default | meaning |
|
| (required) | CloudKit API Token for the MustDo container |
|
|
|
|
|
|
| leave as is |
|
|
| leave as is |
|
|
| port the sign-in callback listens on |
| — |
| where |
| — |
|
|
auth.json is per environment; switching MUSTDO_CK_ENV requires another sign_in.
Apple expires the session after a while (CloudKit returns HTTP 421); tools then return NOT_SIGNED_IN and you run sign_in again.
Related MCP server: iCloud CalDAV MCP Connector
Tools
All tools return JSON. Dates in output are ISO 8601 (UTC). Dates in input may be:
YYYY-MM-DD— that day at the account's default time (see below)YYYY-MM-DDTHH:mm— wall-clock time in the account's time zoneFull ISO 8601 with offset
Tool | Arguments | What it does |
|
| Local only. Opens Apple's sign-in page and stores |
| — | Account info: |
|
| Lists To-Dos. Deleted ones are excluded. Repeating To-Dos are returned as templates under |
|
| Creates a To-Do with |
|
| Changes only the fields you pass. |
|
| One-off: |
|
| Snoozes until |
|
| Soft delete ( |
Default time and omitted due
Each account has a default alarm time (Account.defaultTime, HH:mm, set in the app's settings; 09:00 if unset).
add_todowith nodue→ tomorrow (in the account's time zone) at the default time. Month/year boundaries and DST transitions follow the wall clock.due: "2026-10-10"→ that day at the default time.get_mereturnsdefaultTimeanddefaultDueNextso a client can tell the user when the alarm will ring.
Examples:
// "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" }Repeat rules
Same vocabulary as the iOS Calendar app. Used as input to add_todo / update_todo and returned by 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 }
}You want |
|
Every day |
|
Every Mon & Wed |
|
Every other week |
|
Every 3 days |
|
5th of every month |
|
First Monday of every month |
|
Last Friday of every month |
|
Every year |
|
10 times, then stop |
|
Until Dec 31 |
|
Omitted fields take defaults (interval 1, weekdays [], monthly.mode dayOfMonth, end.kind never).
Ranges: interval 1–99, ordinal 1–5 or -1, weekday 1–7, count 1–999. Anything else → INVALID_ARGUMENT.
The legacy shape { "kind", "weekdays", "until" } is still accepted.
Expansion happens in the app, not here. list_todos returns the template plus occurrences
(per-day done / skipped / snooze). Range filtering only drops templates that definitely cannot
fire in range (first occurrence after the range, until before the range, weekly with no matching weekday).
Errors
Failures come back with isError: true and a body of { "code": "...", "message": "...", "details"?: {...} }.
| Meaning |
| No valid |
| Same, on the hosted relay. Reconnect the connector in claude.ai. |
| API Token missing or rejected by CloudKit (HTTP 401/403). |
| The account's trial has ended and there is no active subscription. Only |
| No such To-Do, or it was deleted. |
| Bad date, out-of-range repeat rule, empty title, etc. |
| Another device changed the record twice in a row. Retry. |
| Any other CloudKit error (e.g. zone missing because the app has never synced). |
| The 10-minute sign-in listener expired. |
| Unexpected error. |
Security model
Access to your To-Dos is gated by your own Apple ID session (
ckWebAuthToken), issued by Apple's sign-in page. No one — including the developer — can read your private database without it.The API Token only identifies the container and fixes where Apple may redirect after sign-in. Apple positions it as a client-side token (it is normally embedded in CloudKit JS web pages). By itself it grants no access to any user's private data.
Locally, the session is stored in
~/.mustdo/auth.json(0600), logs go to stderr as JSON and never include tokens, and the sign-in listener binds to127.0.0.1/::1only.On the relay, the session is encrypted with AWS KMS per user (envelope encryption with encryption context), OAuth tokens are stored only as peppered SHA-256 hashes, PKCE S256 is mandatory, refresh tokens rotate with reuse detection, and To-Do content is never written to storage or logs.
Writes use CloudKit
recordChangeTag(optimistic locking) and retry once on conflict; deletes are soft.Anything you find: see SECURITY.md.
Development
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 handLayout:
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/ vitestdist/core.js (package exports) is the shared core consumed by the hosted relay: everything
except auth.ts, config.ts, index.ts and server.ts. Keep it free of anything that touches the
local file system or a browser.
License
MIT — Copyright (c) 2026 Lightning LLC. See LICENSE.
MustDo is a product of Lightning LLC. Apple, iCloud and CloudKit are trademarks of Apple Inc.
Available Tools
8 toolsadd_todoTODO を追加A
TODO を追加する(source=mcp)。ひとことで TODO を言われたら title だけ渡す。due を省略すると明日の既定時刻(Account の timeZone での今日の翌日、Account.defaultTime、既定 09:00)になる。「明日 9 時」「今日 15 時」など利用者が時刻を言ったときだけ due を渡す(YYYY-MM-DDTHH:mm は Account の timeZone の時計、ISO8601 も可)。日付だけ言われたら due に YYYY-MM-DD を渡すと「その日の既定時刻」になる。繰り返しは repeat で(iOS カレンダーと同じ語彙: 毎日 / 毎週 月水 / 隔週 / 毎月 5 日 / 毎月 第 1 月曜 / 最終金曜 / 毎年 / 3 日ごと / 10 回で終了 / 12/31 まで)。初回は due(毎月 5 日なら due を 5 日に、毎年なら due の月日)。試用(30 日)も購読も切れていると isError + code=PAYMENT_REQUIRED。
| Name | Required | Description | Default |
|---|---|---|---|
| due | No | 鳴らす時刻。YYYY-MM-DDTHH:mm(Account の timeZone の時計)か、オフセット付き ISO8601。YYYY-MM-DD だけなら「その日の既定時刻(Account.defaultTime、既定 09:00)」。 | |
| notes | No | ||
| sound | No | アラーム音。default, chime, marimba, beep, urgent, vibrateOnly, siren, klaxon, rapid, redalert, musicbox, harp, morning, bowl, droplet, breeze, horror, dread, ghost, lament, cello, rainy, fanfare, skip, sparkle | |
| title | Yes | ||
| repeat | No | 繰り返し(iOS カレンダーと同じ語彙)。省略した項目は既定値(interval 1・weekdays []・monthly.mode dayOfMonth・end.kind never)。範囲外は INVALID_ARGUMENT。例: 毎日 {kind:daily} / 毎週 月水 {kind:weekly, weekdays:[2,4]} / 隔週 {kind:weekly, interval:2} / 3 日ごと {kind:daily, interval:3} / 毎月 5 日 {kind:monthly}(due を 5 日に)/ 毎月 第 1 月曜 {kind:monthly, monthly:{mode:weekdayOrdinal, ordinal:1, weekday:2}} / 毎月 最終金曜 {kind:monthly, monthly:{mode:weekdayOrdinal, ordinal:-1, weekday:6}} / 毎年 {kind:yearly}(due の月日)/ 10 回で終了 {kind:daily, end:{kind:count, count:10}} / 12/31 まで {kind:weekly, weekdays:[2], end:{kind:until, until:"2026-12-31"}} |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses the default due behavior (next day at Account.defaultTime, default 09:00), timezone semantics, default repeat values, and a failure condition (trial/subscription expired → isError + code=PAYMENT_REQUIRED). It stops short of stating authentication requirements (implied by sign_in) or any rate limits, so it is not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded and no sentence is pure filler, but the definition is a single long run-on paragraph mixing due defaults, repeat vocabulary, and payment failure. Bullets or short sections would improve scanability for an agent parsing it, though the information density is justified by the nested repeat schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter tool with a nested repeat object and no output schema, the description covers the tricky invocation aspects (due defaults, recurrence encoding, payment-required error). It omits auth prerequisites and says nothing about the response, but with no output schema defined the latter is less critical. Adequate for correct invocation given the schema's own descriptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 60%, and the description compensates heavily for the complex parameters: it explains due formats and the date-only default-time behavior, and translates natural-language recurrence phrases into repeat object shapes (毎週 月水 → weekdays [2,4], 隔週 → interval 2, etc.). It says nothing about notes or sound, which remain schema-documented only, but adds real meaning beyond the schema for the high-complexity fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource (「TODO を追加する」) and adds the creation source (source=mcp). It is trivially distinguishable from siblings like update_todo, complete_todo, snooze_todo, and delete_todo, which all operate on existing TODOs. No ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Rich guidance on optional parameters: pass only title for a bare TODO; pass due only when the user states a time (「明日 9 時」「今日 15 時」); pass YYYY-MM-DD for date-only; how to express recurrence. It does not, however, route among sibling tools or state exclusions (e.g., when to use update_todo instead), so it falls short of explicit alternative-selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
complete_todoTODO を完了A
やった、にする。単発は status=done と completedAt。繰り返しは occurrenceDate(YYYY-MM-DD、省略で TODO の timeZone での今日)の回を Occurrence に done で記録する。
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| occurrenceDate | No | 繰り返しのどの回か。省略で今日 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and does well: it discloses the exact mutations for each case (status=done + completedAt for one-off; a done Occurrence record keyed by occurrenceDate for recurring). It omits idempotency, error states (e.g., already-completed), and auth requirements, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The action ('やった、にする') is front-loaded, and the remaining clauses each earn their place by covering the two execution branches. It is dense but free of filler; slightly telegraphic phrasing is the only minor cost.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter mutation tool with no annotations and no output schema, the definition covers the important complexity: the divergence between one-off and recurring completion, plus the optional date semantics. Error/edge behavior and return expectations are the only meaningful gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: occurrenceDate is documented, id is not. The description adds real value beyond the schema by specifying the timeZone-aware default ('today in the TODO's timeZone'), which the schema's terse '省略で今日' does not clarify. It adds nothing for the required id parameter, so a 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource ('mark as done') and goes further by splitting the behavior into one-off vs. recurring cases. It implicitly separates this from update_todo via completion semantics, but never names or contrasts a sibling explicitly, so it lands at 4 rather than 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the completion semantics and the single-vs-recurring branch, which tells an agent which code path applies. However, there is no guidance on when to prefer complete_todo over update_todo or snooze_todo, and no stated preconditions or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_todoTODO を削除B
deletedAt を書く soft delete。アプリ側で 14 日後に物理削除される。
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does add real value: it discloses the soft-delete mechanism and the 14-day retention before physical purge. It omits other relevant behavior such as idempotency, what happens when deleting an already-deleted TODO, or any permission requirements, leaving meaningful gaps for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, front-loaded sentences with zero filler; the core behavior (soft delete via deletedAt) leads and the follow-on cleanup detail follows immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (one required param, no output schema, no annotations), and the description does cover the key lifecycle behavior. Still, it says nothing about the id parameter, return value, or failure modes, and with no annotations those gaps are not covered elsewhere.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one parameter (id) with 0% schema description coverage, so the description should compensate but never mentions the identifier at all. It does not clarify what the id refers to or its expected format, leaving the schema's bare string entirely undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific operation (soft delete) and its mechanism (writing deletedAt) for the TODO resource. However, it never distinguishes itself from siblings like complete_todo, snooze_todo, or update_todo, which also mutate a TODO, so an agent must infer the difference from the tool name alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to choose this over complete_todo, snooze_todo, or update_todo, nor any prerequisite (e.g. ownership or existing state). The delete intent is only implied by the words 'soft delete'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_meアカウント情報と今日A
Account レコード(trialStartedAt / subscribedUntil / timeZone / defaultTime)と、その時間帯での今日の日付・曜日、due を省略したときに使われる「明日の既定時刻」(defaultDueNext、ISO8601)を返す。日付を扱う前に呼ぶ。
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose a genuinely non-obvious behavioral trait: defaultDueNext is a derived value tied to the account time zone and only matters as the fallback when due is omitted. It still does not state whether authentication (sibling sign_in) is required or what happens on failure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: the first front-loads exactly what is returned, the second front-loads the call precondition at the end where it is most actionable. Every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must explain return values and it does so field by field, including the derived ISO8601 value. For a zero-parameter read tool the definition gives the agent everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4 and there is no parameter syntax for the description to add. Nothing in the schema needs compensating for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the exact resource (Account レコード) and enumerates the fields returned (trialStartedAt, subscribedUntil, timeZone, defaultTime, defaultDueNext), so an agent knows precisely what it gets. It does not explicitly contrast itself with siblings like list_todos or sign_in, but the resource is distinctive enough that confusion is unlikely.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The closing line "日付を扱う前に呼ぶ" gives an explicit precondition for calling the tool, which is real usage guidance rather than implication. It stops short of naming a when-not case or an alternative tool, so it is not a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_todosTODO 一覧A
TODO を一覧する。date(1 日)か from/to(両端含む、YYYY-MM-DD、Account の timeZone)で絞る。省略で全期間。status の既定は pending。削除済み(deletedAt あり)は含めない。繰り返しは展開せず repeating にテンプレートとして返し、範囲内の Occurrence(回ごとの done / skipped / スヌーズ)を添える。展開はアプリ側で MCP はしない。規則(repeat): kind × interval(1=毎、2=隔)。daily は interval 日ごと、weekly は weekdays(1=日…7=土。空なら dueAt の曜日)の曜日、monthly は dueAt の日(dayOfMonth。無い月は月末)か第 n 曜日(weekdayOrdinal、ordinal -1 = 最終)、yearly は dueAt の月日。終了は end(never / until = その日を含む / count = 開始からの回数)。初回は dueAt、各回の時刻は dueAt の時分(timeZone の時計)。
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | この日まで(含む) | |
| date | No | この 1 日だけ | |
| from | No | この日から(含む) | |
| status | No | 既定 pending。done / skipped は単発だけに効く | |
| includeRepeating | No | 既定 true。false で繰り返しテンプレートを省く |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well: it discloses that deleted records (deletedAt present) are excluded, that recurring items are not expanded but returned as 'repeating' templates plus in-range occurrences, and that expansion is the app's job, not the MCP's. It stops short of stating the read-only nature or the response shape explicitly, but the read semantics are strongly implied by 一覧する.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and filtering rules are front-loaded, and the dense recurrence-rule block at the end is justified because there is no output schema describing the 'repeating' template. Every clause is information-bearing, though the spec-dump style for recurrence could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-required-param list tool with no output schema, the description covers filtering, defaults, exclusion rules, and the structure of recurring items and their occurrences. Given the complexity of the recurrence domain, it is largely complete, though the shape of a returned TODO item itself is left unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: from/to are inclusive on both ends, dates are interpreted in the Account's timeZone, and status defaults to pending. These are semantic details the schema fields do not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening 'TODO を一覧する' states a specific verb (list) and resource (TODO), immediately separable from the mutation siblings (add_todo, update_todo, complete_todo, delete_todo). It also defines the scope precisely with the date/from-to filtering semantics.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly says when to use date (single day) vs. from/to (inclusive range) and what the omission default is (全期間). It also states the status default (pending) and that deleted items are excluded. It does not explicitly name sibling alternatives, but the filtering guidance is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sign_iniCloud にサインインA
Apple のサインイン画面をブラウザで開き、戻ってきた ckWebAuthToken を ~/.mustdo/auth.json に保存する。他のツールが NOT_SIGNED_IN を返したときに使う。ユーザーがブラウザ操作できるときだけ呼ぶこと。
| Name | Required | Description | Default |
|---|---|---|---|
| waitSeconds | No | ブラウザが戻るまで待つ秒数(既定 90) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the side effect (a browser flow), the persisted artifact and its exact path (~/.mustdo/auth.json), and the human-in-the-loop prerequisite. It is silent on failure/timeout behavior and whether an existing token is overwritten, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: action, trigger, precondition. The routing constraint is front-loaded and every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter, no-output-schema tool, the description covers purpose, trigger, precondition, and side effect. Only minor gaps remain (failure/timeout handling, token-overwrite semantics), which are not essential for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and only one optional parameter exists, so the schema already fully documents waitSeconds (default 90, range 5-300). The description adds no parameter syntax or defaults beyond that, making the baseline 3 correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (opens Apple's sign-in page, persists ckWebAuthToken to ~/.mustdo/auth.json). This is unmistakably different from every sibling tool, all of which are todo operations, so an agent can route to it without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger (when another tool returns NOT_SIGNED_IN) and an explicit exclusion (call only when the user can operate the browser). Both the when and the when-not are stated, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
snooze_todoTODO をスヌーズC
until(YYYY-MM-DDTHH:mm は TODO の timeZone、または ISO8601)まで鳴らさない。繰り返しは occurrenceDate の回だけ。
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| until | Yes | YYYY-MM-DDTHH:mm(Account の timeZone の時計)か、オフセット付き ISO8601 | |
| occurrenceDate | No | 繰り返しのどの回か。省略で今日 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, yet it only discloses the suppression effect and that recurring items are scoped to one occurrence. It omits whether auth is required, how it interacts with existing reminders, idempotency, and what value is returned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact clauses with no filler, and the cardinal constraint (until) is front-loaded. It is dense to the point of being slightly cryptic but wastes no words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations and no output schema, the description covers the core timing parameters but omits the id parameter, sibling routing, side effects, and return behavior. It is minimally sufficient but leaves clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%; the description restates the until format and clarifies recurring-occurrence behavior, adding some meaning beyond the schema. However, it leaves id undocumented and its timeZone wording ("TODO の timeZone") conflicts with the schema's "Account の timeZone", which is a minor semantic inconsistency rather than added clarity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description conveys a specific action and effect—suppressing firing until a given time ("〜まで鳴らさない")—which, with the name snooze_todo, is distinguishable from update_todo or complete_todo. It does not explicitly name or contrast a sibling, keeping it short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no stated when-to-use or when-not-to-use versus the siblings (e.g. update_todo, complete_todo). The only usage hint is the recurrence note ("繰り返しは occurrenceDate の回だけ"), which is narrow and does not help an agent choose this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_todoTODO を更新A
TODO の題名・時刻・繰り返し・メモ・音・状態を変える。渡した項目だけ変わる。repeat は丸ごと置き換え(省略した項目は既定値)。repeat: null か {kind: none} で繰り返しを外す。notes: null でメモを消す。繰り返し TODO の status は変えられない(complete_todo / snooze_todo を使う)。
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| due | No | 鳴らす時刻。YYYY-MM-DDTHH:mm(Account の timeZone の時計)か、オフセット付き ISO8601。YYYY-MM-DD だけなら「その日の既定時刻(Account.defaultTime、既定 09:00)」。 | |
| notes | No | ||
| sound | No | アラーム音。default, chime, marimba, beep, urgent, vibrateOnly, siren, klaxon, rapid, redalert, musicbox, harp, morning, bowl, droplet, breeze, horror, dread, ghost, lament, cello, rainy, fanfare, skip, sparkle | |
| title | No | ||
| repeat | No | 繰り返し(iOS カレンダーと同じ語彙)。省略した項目は既定値(interval 1・weekdays []・monthly.mode dayOfMonth・end.kind never)。範囲外は INVALID_ARGUMENT。例: 毎日 {kind:daily} / 毎週 月水 {kind:weekly, weekdays:[2,4]} / 隔週 {kind:weekly, interval:2} / 3 日ごと {kind:daily, interval:3} / 毎月 5 日 {kind:monthly}(due を 5 日に)/ 毎月 第 1 月曜 {kind:monthly, monthly:{mode:weekdayOrdinal, ordinal:1, weekday:2}} / 毎月 最終金曜 {kind:monthly, monthly:{mode:weekdayOrdinal, ordinal:-1, weekday:6}} / 毎年 {kind:yearly}(due の月日)/ 10 回で終了 {kind:daily, end:{kind:count, count:10}} / 12/31 まで {kind:weekly, weekdays:[2], end:{kind:until, until:"2026-12-31"}} | |
| status | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden well: it discloses partial mutation, wholesale replacement of repeat, repeat removal via null or {kind:none}, notes deletion via null, and the status restriction on repeating TODOs. It stops short of auth, error, or return behavior, but covers the main mutation semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, moving from the general update operation to key semantic caveats without wasted sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter mutation tool with no annotations and no output schema, the description provides the crucial update semantics an agent needs. Minor gaps remain around id requirements and error/return behavior, but core invocation safety is covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 43%, so the description must compensate. It adds valuable semantics for repeat, notes, and status, but does not explain id, due-time formatting, or sound choices beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (変える) and resource (TODO), enumerates the mutable fields, and distinguishes the tool from complete_todo and snooze_todo for repeating TODO status operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly explains partial-update behavior (渡した項目だけ変わる) and routes the agent away from using this tool to change status on repeating TODOs, naming complete_todo and snooze_todo as alternatives. It does not cover every sibling relationship, but the relevant exclusion is explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
add_todo - First observed
complete_todo - First observed
delete_todo - First observed
get_me - First observed
list_todos - First observed
sign_in - First observed
snooze_todo - First observed
update_todo
TDQS
Scored across 8 tools
Each tool targets a distinct operation: auth (sign_in, get_me), CRUD (add/update/delete/list_todo), and special status actions (complete_todo, snooze_todo). The only mild overlap is that update_todo can also change status, but the description explicitly redirects recurring occurrences to complete_todo/snooze_todo, keeping boundaries clear.
Consistent snake_case verb_noun pattern throughout: sign_in, get_me, add_todo, update_todo, complete_todo, snooze_todo, delete_todo, list_todos. No mixed conventions or vague verbs.
8 tools is well-scoped for a personal TODO server. Auth, account info, CRUD, and recurring-occurrence actions each earn their place without redundancy.
Covers the full TODO lifecycle including soft delete, completion, snooze, recurrence, and listing with filters. Minor gaps: no restore-undelete, no single-todo get, and no explicit unsnooze, but agents can work around these.
Maintenance
Related MCP Connectors
Local-first task manager: create, edit, and complete tasks, projects, and checklists via MCP.
Give your AI agent a memory and body on your iPhone: set alarms, ring your phone, over MCP.
- mcpOAuthnet.todoist
Official Todoist MCP server for AI assistants to manage tasks, projects, and workflows.
Create, list, and complete todo items through MCP.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn OAuth-authenticated MCP server that bridges Claude AI with a task management system, allowing users to list, create, and update tasks through natural language commands.1-
- AlicenseNot gradedqualityCmaintenanceAn HTTP Model Context Protocol (MCP) server exposing iCloud Calendar (CalDAV) tools so MCP-aware clients can list calendars, read events, and create/update/delete events using an iCloud app-specific password.3MIT
- AlicenseAqualityDmaintenanceAn MCP server that connects Claude Desktop to Apple Reminders on macOS via AppleScript.511 npmMIT
- AlicenseNot gradedqualityBmaintenanceAn MCP server that bridges Claude Desktop to iCloud Mail, Calendar, Reminders, and Contacts, enabling cross-service actions like daily briefs, scheduling, email drafting, task deferring, and unified search via a single prompt.34 npmMIT