microsoft-todo-mcp
microsoft-todo-mcp
A remote Model Context Protocol server
for Microsoft To Do, deployable on Azure and usable as a custom connector
in both ChatGPT and Claude. Multi-account (personal + work
Microsoft accounts), multi-profile (/mcp/personal, /mcp/work, or any
custom alias), single-owner administration.
Architecture at a glance
flowchart TB
subgraph Clients
ChatGPT[ChatGPT custom connector]
Claude[Claude custom connector]
Browser[Owner's browser -> /accounts]
end
App["microsoft-todo-mcp\n(Azure Container Apps, scale-to-zero)"]
KV[(Key Vault)]
ST[(Storage: Table + Blob)]
Graph[[Microsoft Graph]]
ChatGPT -- Bearer JWT --> App
Claude -- Bearer JWT --> App
Browser --> App
App --> KV
App --> ST
App -- per-connection token --> GraphFull details: docs/architecture.md.
Why this exists
Microsoft To Do has no first-party remote MCP connector. This project lets you talk to your Microsoft To Do lists from ChatGPT or Claude, across however many personal/work Microsoft accounts you have, from a small self-hosted deployment you fully control (your own Azure subscription, your own OAuth authorization server, your own encrypted token storage).
Feature summary
MCP tools: full read/write coverage of task lists, tasks, and checklist items, plus account/profile discovery tools — see the tool list in
src/tools/.Multi-account routing that never guesses which Microsoft account a tool call should hit — see
docs/multi-account.md.Two independent OAuth systems, documented in
docs/oauth.md: this server as an OAuth 2.1 authorization server toward ChatGPT/Claude, and this server as an OAuth client toward Microsoft Entra ID/Graph.Encrypted token storage: AES-256-GCM MSAL token caches in Blob Storage, hashed OAuth codes/refresh tokens in Table Storage, secrets in Key Vault, all accessed via a least-privilege user-assigned managed identity — no client secrets or connection strings in the running production process.
Owner-only admin UI at
/accountsfor connecting accounts, binding profiles, reauthorizing, revoking, and deleting connections.Azure Container Apps, consumption plan, scale-to-zero — near-zero idle cost; see the cost estimate in
docs/azure-deployment.md.
Quick start (local development)
npm install
cp .env.example .env # fill in real values — see docs/azure-deployment.md
npm run devnpm run dev starts the server with tsx watch. You'll need a reachable
Storage account (Azurite works for local dev) and Key Vault (or adapt
src/config/secrets.ts for local secret sources) before OAuth flows will
actually work end-to-end — see docs/operations.md.
Deploying to Azure
./scripts/login.ps1
./scripts/validate-environment.ps1
$region = ./scripts/select-region.ps1
./scripts/provision.ps1 -ResourceGroupName rg-microsoft-todo-mcp -Location $region -ResourceSuffix prod01 `
-AzureClientId <graph-app-client-id> -AzureTenantId <tenant-id> `
-PublicBaseUrl https://todo.h-aa.dk -BudgetNotificationEmail you@example.com
./scripts/deploy.ps1 -ResourceGroupName rg-microsoft-todo-mcp -ContainerAppName todomcp-app-prod01 `
-Image ghcr.io/<you>/microsoft-todo-mcp:sha-abc123 -Build
./scripts/configure-domain.ps1 -ResourceGroupName rg-microsoft-todo-mcp `
-ContainerAppEnvironmentName todomcp-env-prod01 -ContainerAppName todomcp-app-prod01 `
-DomainName todo.h-aa.dk -Location $regionFull walkthrough: docs/azure-deployment.md.
DNS specifics: docs/dns.md.
Connecting ChatGPT / Claude
Connect at least one Microsoft account and bind a profile from
/accounts—docs/multi-account.md.Add a custom connector pointing at
/mcp/personal,/mcp/work, or/mcp(universal) —docs/chatgpt-setup.md/docs/claude-setup.md.
Security model
Summarized in docs/security.md; vulnerability
reporting in SECURITY.md.
Cost estimate
Roughly 10–25 DKK/month depending on whether Log Analytics is enabled
— see the itemized breakdown in
docs/azure-deployment.md.
Teardown
az group delete --name rg-microsoft-todo-mcp --yes --no-waitProject layout
src/ Server source (mcp, graph, oauth, storage, crypto, tools, admin, http)
infra/ Bicep: Container Apps (consumption, scale-to-zero), Key Vault, Storage, RBAC, budget
scripts/ PowerShell 7 provisioning/deploy/ops scripts
docs/ Architecture, deployment, DNS, OAuth, security, connector setup, operations
.github/ CI, CodeQL, secret scanning, OIDC-based deploy workflow
tests/ Vitest unit tests + Playwright OAuth flow testsLicense
MIT.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Haulund-ATP/microsoft-todo-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server