Skip to main content

One post tagged with "Microsoft Graph"

View All Tags

A Cloudflare Worker for Microsoft To Do and Claude AI

· 11 min read

My latest project, mstodo-mcp-cloudflare, is now public. It‘s a Cloudflare Worker that connects Claude.ai to your Microsoft To Do account over MCP. You can ask Claude to find, create, update, complete, and search tasks across all your lists in plain language without leaving the conversation. Open source, MIT licensed, and runs on the Cloudflare free tier for single-user installs with a normal task count, with great performance for Paid Worker tier if you need it. Allows for sub-list item control, multi-attachment deduplicated uploads, and custom linked items by content (define a ticket number regex and the system adds a related ticket link for tasks mentioning a ticket number, configurable via MCP conversation).

This follows the Obsidian MCP and link resolver Workers I released two days ago, using the same core pattern: Cloudflare Worker, Durable Object for stateful storage, OAuth for access control, all serverless and scaling to zero.

Why I built it

I rely on Microsoft To Do for task management across all my devices. My Day resets every night, the sync is solid everywhere I work, and Outlook flagging integration sounded cool, but I abuse flags to the point of useless in a task app so I turned them off in To Do :-) (Don't worry, it still works here.)

I have more lists than most people would consider reasonable. Task lists, reference lists, and project-specific lists. That spread is both the strength and the weak point of the setup. Finding something across all of them required either opening To Do directly and searching, or remembering which list it was in.

The thing I wanted was conversational access to the whole picture. Not an AI embedded inside a task app behind whatever narrow interface the vendor provides, but an AI that could reach into the task app from a conversation, query across all the lists at once, and create tasks with context from whatever I was already discussing.

Before building this, I looked at what already existed. n8n is powerful, I use it a lot, it has Microsoft Graph integration (even with To Do directly!) and can wire up MCP-style operations for AI clients. The problem is coverage. The Microsoft To Do operations available through n8n's connector cover a subset of what the Graph API supports, and nothing is cached. A cross-list query through n8n means walking every list and fetching its tasks from the Graph API in sequence. This is fine for a single-list automation triggered manually, but slow enough to be painful for "show me everything due this week across all my lists" asked as a casual conversational query. With Microsoft Graph rate limits in play, bulk reads on a large account get uncomfortable fast. And n8n can build MCP servers easily but has some limitations on function structure that limit its capabilities here. I built it, used it periodically for 6 months, but always wanted something more complete.

Building the Obsidian MCP Worker made the right architecture clear. A local mirror in a Durable Object's SQLite database, kept current by delta sync, handles both problems: it exposes the full API surface and makes cross-list queries instant regardless of task count. Applying the same pattern to To Do was the natural next step.

What I am using it for

The most immediate change to my daily workflow is…honestly unknown, I just built it! Of course I can ask Claude to pull all incomplete tasks due this week across all my lists, grouped by list type, and get an actual picture rather than scrolling through 20-odd lists one at a time. That query used to require opening To Do and filtering repeatedly, which I mostly did not bother to do. I can ask it to take a list of follow-up items in Obsidian and convert them to Microsoft To Do tasks, or I can take a reference item in To Do and have Claude research it with the results saved in an Obsidian note.

The other thing that comes up constantly is task creation from context. When something comes up mid-conversation (a follow-up to schedule, something to note about a project, a call to make, an ongoing Obsidian note I'm creating or editing) asking Claude to add a task is faster than switching apps, finding the right list, and typing. Because the server holds the full list roster with aliases I have configured, Claude should usually route the task correctly from a description without needing an exact list name.

Cross-list search is less dramatic but I use it more than expected. I frequently remember writing something down without remembering where. Full-text search across all task titles and notes, answered from the local SQLite FTS5 index, comes back fast without hitting the Graph API at all.

The other thing To Do is bad at surfacing in the app is completed tasks. You can see them, but only per-list and with limited sorting capability. Because all completed tasks are synchronized here, reporting with any type of filters should be straightforward. And I’m contemplating (it’s not here yet) adding a REST API to make this reporting even easier from n8n or other systems (I’m doing this now in n8n for a periodic “recently completed tasks” email summary, but with limitations this database copy would remove).