mstodo-mcp-cloudflare
A Cloudflare Worker (with Durable Objects) MCP server for a single Microsoft To Do account. Keeps a synced SQLite copy of your lists and tasks for fast, large queries via delta sync. Configurable list-type classification and per-list sync exclusions (flaggedEmails skipped by default).
Install / Use
claude mcp add dszp -- npx -y github:dszp/mstodo-mcp-cloudflareIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
CommunicationSupported Platforms
Our assessment of mstodo-mcp-cloudflare
mstodo-mcp-cloudflare scores 75/100 on our quality scale, 412th of 435 Communication skills we index.
Its MCP Server is 23 KB long, well organised into 29 sections with 6 code examples: a thorough specification that gives an agent plenty to work with.
It has 3 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated about 3 months ago, so mstodo-mcp-cloudflare is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 92/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
mstodo-mcp-cloudflare compared with similar skills
All 4 of these similar skills score higher than mstodo-mcp-cloudflare; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| mstodo-mcp-cloudflare (this skill)by dszp | 75 | 3 | 3mo ago | MCP Server |
| claude-memby thedotmack | 100 | 98.1k | 1d ago | CLAUDE.md |
| Agent-Reachby Panniantong | 100 | 93.9k | today | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 74.7k | today | CLAUDE.md |
| CowAgentby zhayujie | 100 | 47.3k | today | CLAUDE.md |
Frequently asked questions
- How do I install mstodo-mcp-cloudflare?
- Run
claude mcp add dszp -- npx -y github:dszp/mstodo-mcp-cloudflare. The install tabs above show the steps for each supported agent. - Which AI agents does mstodo-mcp-cloudflare work with?
- It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
- Is mstodo-mcp-cloudflare safe to use?
- It is MIT-licensed and scores 92/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is mstodo-mcp-cloudflare still maintained?
- The repository was last updated about 3 months ago, so mstodo-mcp-cloudflare is actively maintained.
Skill content
View source on GitHubmstodo-mcp
Use your Microsoft To Do tasks from Claude (or any MCP client), in plain language. This is a personal, self-hosted server you run on your own Cloudflare Worker that connects Claude.ai to your Microsoft To Do account — so you can ask Claude to find, create, update, complete, search, and organize tasks across all your lists without leaving the chat. It keeps a fast local mirror of your lists and tasks, so searching and querying across every list is quick and doesn't hammer Microsoft on each request.
It's single-user by design: one deployment serves exactly one Microsoft account (everyone else is rejected by an owner-identity gate), so it's meant for running your own private instance — not a shared/multi-tenant service.
Contents
- Requirements
- Tools
- How it works
- Configuration
- Reset
- Identity-change auto-wipe
- Design decisions to revisit
- Author
- Deployment guide →
- Changelog →
Requirements
- A Microsoft 365 (M365) or personal Microsoft account that uses Microsoft To Do.
- A Cloudflare account — the free plan works for small accounts; Workers Paid is recommended once you have thousands of tasks (see the plan note in the deployment guide).
- A Microsoft Entra app registration — free, created once (walkthrough in the deployment guide).
- Node 18+ and Cloudflare's Wrangler CLI, to deploy.
- Claude.ai (or another MCP client) to connect to the deployed server.
➡️ Setup & deployment: see DEPLOYMENT.md for the full step-by-step guide (including the Microsoft Entra app registration), custom-domain setup, and troubleshooting. The Configuration reference is below.
Tools
The server exposes a Microsoft To Do tool surface over MCP. Highlights:
- Lists & tasks (CRUD) —
list_lists,get_list,create_list,update_list,delete_list;list_tasks,get_task,create_task,update_task,delete_task,move_task. - Sub-resources — checklist items and linked resources
(create/list/get/update/delete each); attachments (
list_attachments,get_attachment,remove_attachment). - Attachment upload —
create_upload_linkmints a short-lived, single-use web link the user opens in a browser to attach file(s) to a specific task. The bytes go browser → Worker → Microsoft (≤ 25 MB each, inline or chunked upload-session) and never pass through the model. See Web upload below. - Attachment download —
mint_download_linkmints a short-lived (≤ 5 min), single-use URL that serves one attachment's bytes for a server-to-server transfer (e.g. handing the URL to another MCP server's url-ingest tool). The bytes are fetched server-side and never pass through the model. ON by default; setENABLE_DOWNLOAD_LINKS="false"to disable. See Cross-server download below. - Cross-list query & search (answered from the local
TodoIndexmirror):query_tasks— filter by lists, status, date ranges, importance, has-checklist,has_open_checklist_item(tasks with an unchecked item — the "waiting on something" filter);types/exclude_types(include/exclude by list classification); acompletedconvenience (mutually exclusive withstatus); paginated.search_tasks— full-text search over task titles/bodies using FTS5 (SQLite's built-in full-text search engine); samelists/status/types/exclude_types/completedfilters.exclude_types:["excluded"]drops noise (e.g. flagged-email lists) from results without deleting anything. When the checklist cache is on it also matches checklist-item (subtask / step) text by default (include_checklist, tiered after title/body matches).find_task_list,get_pending_across_lists,get_recently_completed.
- Checklist follow-ups (opt-in) — gated behind
ENABLE_CHECKLIST_CACHE=true. Mirrors task checklist items into a queryable table so you can use checklist items as a lightweight follow-up system (add a "waiting on Acme reply" item, then find what's still open).search_checklist_itemsdoes FTS over checklist text, or — with no query — lists pending items oldest-first (what you've been waiting on longest), grouped by task. Pairs with thequery_taskshas_open_checklist_itemfilter. Off by default (it adds a one-time per-task backfill); the cache then stays fresh on the normal delta cycle. Covers open tasks only — completed tasks are intentionally excluded from cross-task checklist queries (get_taskstill shows any task's items live), and skipped lists (no_sync/Flagged Emails) aren't cached. - My Day & manual order (opt-in, Substrate) — gated behind
ENABLE_MY_DAY=true(these use the undocumented Substrate endpoint the To Do web app uses, because My Day and the manual drag-to-reorder position are invisible to Graph):list_my_day_tasks,add_to_my_day,remove_from_my_day;list_tasks_by_manual_order(one list in the app's manual order) andreorder_task(move a task to top/bottom, before/after another, or a 1-based slot). - Config —
get_list_config/set_list_config(classification patterns,no_sync,sync_flagged_emails),set_list_alias,get_link_rules/set_link_rules,get_attachment_config/set_attachment_config,extract_links. - Ops —
whoami,sync_status,resync.
How it works
Claude.ai connects to the Worker over remote-MCP; the Worker brokers requests to the
Microsoft Graph API (OAuth authorization-code flow with PKCE + a client secret). A
singleton TodoIndex Durable Object (Cloudflare's stateful, strongly-consistent
compute primitive) keeps a delta-synced mirror of your lists and tasks in its
embedded SQLite database, alongside an FTS5 full-text index (FTS5 is SQLite's
built-in full-text search engine). Cross-list query_tasks, search_tasks, and
aggregation tools read from this local mirror rather than re-walking Graph on every
call; a */15 cron keeps it synced and an owner-identity gate keeps it private.
By default the mirror also subscribes to Graph change notifications (one per list), so an edit
in any To Do client lands in the cache within ~2 minutes — near-instant, like the native apps —
instead of waiting for the next timer cycle. This is a trigger for delta sync, not a replacement:
the timer cycle stays as the backstop (Graph has no missed-notification guarantee for tasks). It
rides the existing Tasks.ReadWrite scope (no extra consent), needs a reachable SERVICE_BASE_URL
(Graph posts to ${SERVICE_BASE_URL}/webhook), and is toggleable with ENABLE_TASK_SUBSCRIPTIONS
("false" ⇒ timer-only, no public webhook). A notification also refreshes just the changed task's
My Day fields via one targeted Substrate read — the webhook path never writes back to Microsoft, so
it can't loop.
Small, slowly-changing state — your OAuth tokens, the owner-identity record, and the config blobs below — lives in Cloudflare KV (a key-value store). The large, frequently-queried task corpus lives in the Durable Object's SQLite, not KV.
Security model
The server is strictly single-user by design, and a few invariants are load-bearing — worth stating in one place:
- One owner, fail-closed. Every sign-in is gated at the OAuth callback: the Microsoft
/memail/userPrincipalNamemust equal theOWNER_EMAILsecret, and a non-matching identity is 403'd before any token is stored. A missing or mistypedOWNER_EMAILmakes the check fail for everyone — it locks the owner out, it never opens access. - Host-pinning before authorization. Every Graph and Substrate URL is pinned to its expected
host before the Bearer token is attached, so a malicious
@odata.nextLinkcan't redirect an authenticated request and exfiltrate the token. Tokens travel only in theAuthorizationheader — never in a URL or a log line. - One token refresher. The singleton
TodoIndexDurable Object is the sole caller of the Microsoft token endpoint; concurrent sessions funnel through a single refresh chain, so there are no refresh storms and no token-handling logic duplicated across sessions. - Config is owner-only, not an untrusted surface. The regex rules in
config:lists/config:link_rulesare writable only by the authenticated owner (via MCP tools behind the gate above), so user-supplied-regex concerns like ReDoS aren't in the threat model. The link engine additionally bounds work with an 8 KB body cap and a 50 ms budget per task. - Secret-less web surfaces.
/uploadand/downloadauthorize with single-use capability tokens — an unguessable random id stored in KV under a TTL, scoped to one task/attachment — so there is no signing key or shared secret to configure or leak. - Logs carry no secrets. Query strings (which can hold delta tokens) are redacted, Microsoft error bodies are logged as structured fields rather than raw text, and the only PII in logs is the owner's own address in the identity-change line.
Configuration
Three optional config blobs live in KV under the TODO_CACHE binding. Ready-to-edit
examples (with the exact wrangler kv key put commands) are in config-examples/.
config:lists — classification, aliases, sync control
patterns— ordered regex rules matched against list display names (emoji stripped, case-insensitive by default); first match wins →todo|reference|excluded. Unmatched lists areunclassified. Classification powerslist_listsfiltering and thetypes/exclude_typesparams onquery_tasks/search_tasks.excludedkeeps a list out of type-filtered tools but does not stop it syncing — useno_syncfor that.aliases— short handle → Graph list ID, usable anywhere a list is accepted. Cleared automatically on a Microsoft identity switch (IDs are per-account).no_sync— lists excluded from delta sync, matched bywellknownListNameor Graph list ID. They stay listed and on-demand-readable but aren't indexed. Settable conversationally viaset_list_config; the sync loop self-heal-purges a list's rows if you add it later.sync_flagged_emails— theflaggedEmailswell-known list is skipped by default (it's often huge and not a real task list); settrueto index it. This built-in skip is independent ofno_sync.
config:link_rules — auto-link tasks
Regex → linked-resource rules applied to task titles/bodies. See config-examples/link-rules.json.
config:attachments — inline upload cap
max_inline_bytes (hard ceiling 3072 KiB, the confirmed Graph limit). For web uploads this is
the cutover point: files at or below it are attached inline, larger ones (up to 25 MB) via a
chunked Graph upload-session. See config-examples/attachments.json.
Web upload (/upload)
File bytes can't practically travel through an MCP tool call (the model's per-call argument
budget is a few KB). Instead, create_upload_link mints a short-lived (default 15 min, max 30),
single-use link scoped to one specific task; the user opens it in a browser and the bytes go
straight from the browser to the Worker and on to Microsoft Graph — never through the model.
Provide a filename for a single-file link, or omit it for a batch link (up to max_files,
1–10, default 5). Identical files already attached to the task are detected by content hash and
skipped as duplicates.
The lin
Truncated for display — read the full file on GitHub.
Related Skills
claude-mem
98.1kPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode + More
Agent-Reach
93.9kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
74.7kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
CowAgent
47.3kOpen-source personal AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
