A Model Context Protocol (MCP) server that enables AI assistants to interact with Microsoft To Do via the Microsoft Graph API. Works with any MCP-compatible client — Claude Desktop, Cursor, Windsurf, and more.
- 17 MCP Tools: Complete task management including lists, tasks, checklist items, and organization
- In-Band Authentication: Authenticate directly through an MCP tool — use
start-auth(browser-based) orstart-device-auth(headless/terminal), selected via theAUTH_FLOWenvironment variable - Universal Client Support: Configure once with environment variables, works in every MCP client
- Automatic Token Refresh: Tokens are refreshed 5 minutes before expiration, transparently
- Microsoft Graph API Integration: Direct integration with Microsoft's official API v1.0
- Multi-tenant Support: Works with personal, work, and school Microsoft accounts
- TypeScript: Fully typed for reliability and developer experience
- ESM Modules: Modern JavaScript module system
- Node.js 18 or higher
- A Microsoft account (personal, work, or school)
- An Azure App Registration (see setup below)
Add the server to your MCP client configuration (see MCP Client Configuration below). The client will download and run the package automatically via npx.
npm install -g microsoft-todo-mcp-server
# or
pnpm install -g microsoft-todo-mcp-serverThe package provides two command aliases:
microsoft-todo-mcp-server— Full package namemstodo— Short alias
git clone https://github.com/jordanburke/microsoft-todo-mcp-server.git
cd microsoft-todo-mcp-server
pnpm install
pnpm run buildBefore using the server, you need to register an application in Azure:
- Go to the Azure Portal
- Navigate to App registrations → New registration
- Name your application (e.g., "To Do MCP")
- For Supported account types, choose based on your needs:
- Accounts in this organizational directory only — Single tenant
- Accounts in any organizational directory — Multi-tenant
- Accounts in any organizational directory and personal Microsoft accounts — Both work and personal accounts
- Set the Redirect URI to
http://localhost:4040/callback - After creation, go to Certificates & secrets → create a new client secret
- Go to API permissions → add the following Microsoft Graph > Delegated permissions:
Tasks.ReadTasks.ReadWriteUser.Read
- Click Grant admin consent for these permissions
Save your Application (client) ID and Client Secret — you'll need them for configuration.
Configure the server in your MCP client using environment variables for credentials. The required variables depend on the authentication flow you choose.
The server supports two authentication flows, selected via the AUTH_FLOW environment variable:
| Variable | Values | Default | Description |
|---|---|---|---|
AUTH_FLOW |
authorization_code, device_code |
authorization_code |
Selects the OAuth flow for authentication |
authorization_code(default) — Browser-based flow. RequiresCLIENT_ID,CLIENT_SECRET, andTENANT_ID. Best for desktop environments where a browser is available.device_code— Headless flow for terminal-only or remote environments. Requires onlyCLIENT_ID. No client secret needed. The server displays a user code and verification URL for sign-in on any device.
| Variable | Required | Description |
|---|---|---|
CLIENT_ID |
Yes | Azure App Registration application (client) ID |
CLIENT_SECRET |
Authorization code flow only | Client secret from Azure App Registration |
TENANT_ID |
Authorization code flow only | Tenant identifier (see table below) |
AUTH_FLOW |
No | authorization_code (default) or device_code |
REDIRECT_URI |
No | OAuth callback URL (defaults to http://localhost:4040/callback) |
| Value | Use Case |
|---|---|
organizations |
Multi-tenant organizational/work accounts (default if omitted) |
consumers |
Personal Microsoft accounts only |
common |
Both organizational and personal accounts |
your-tenant-id |
Single-tenant (use your Azure AD tenant GUID) |
Use this configuration for desktop environments with browser access:
Add to your Claude Desktop configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"microsoftTodo": {
"command": "npx",
"args": ["-y", "microsoft-todo-mcp-server"],
"env": {
"CLIENT_ID": "your_client_id",
"CLIENT_SECRET": "your_client_secret",
"TENANT_ID": "organizations"
}
}
}
}Add to your Cursor MCP configuration:
- Global:
~/.cursor/mcp.json - Project:
.cursor/mcp.jsonin your project root
{
"mcpServers": {
"microsoftTodo": {
"command": "npx",
"args": ["-y", "microsoft-todo-mcp-server"],
"env": {
"CLIENT_ID": "your_client_id",
"CLIENT_SECRET": "your_client_secret",
"TENANT_ID": "organizations"
}
}
}
}Add to your Windsurf MCP configuration (usually ~/.codeium/windsurf/mcp_config.json):
{
"mcpServers": {
"microsoftTodo": {
"command": "npx",
"args": ["-y", "microsoft-todo-mcp-server"],
"env": {
"CLIENT_ID": "your_client_id",
"CLIENT_SECRET": "your_client_secret",
"TENANT_ID": "organizations"
}
}
}
}Use this configuration for headless, terminal-only, or remote environments. Only CLIENT_ID is required — no client secret.
Prerequisite: In your Azure App Registration, go to Authentication → enable Allow public client flows.
{
"mcpServers": {
"microsoftTodo": {
"command": "npx",
"args": ["-y", "microsoft-todo-mcp-server"],
"env": {
"CLIENT_ID": "your_client_id",
"AUTH_FLOW": "device_code"
}
}
}
}{
"mcpServers": {
"microsoftTodo": {
"command": "npx",
"args": ["-y", "microsoft-todo-mcp-server"],
"env": {
"CLIENT_ID": "your_client_id",
"AUTH_FLOW": "device_code"
}
}
}
}{
"mcpServers": {
"microsoftTodo": {
"command": "npx",
"args": ["-y", "microsoft-todo-mcp-server"],
"env": {
"CLIENT_ID": "your_client_id",
"AUTH_FLOW": "device_code"
}
}
}
}If you cloned the repo and built locally, point the command at the built CLI:
{
"mcpServers": {
"microsoftTodo": {
"command": "node",
"args": ["/path/to/microsoft-todo-mcp-server/dist/cli.js"],
"env": {
"CLIENT_ID": "your_client_id",
"CLIENT_SECRET": "your_client_secret",
"TENANT_ID": "organizations"
}
}
}
}After adding the server to your MCP client, authenticate with Microsoft. The authentication method depends on your AUTH_FLOW setting:
- Ask your AI assistant to run the
start-authtool (e.g., "Run start-auth to authenticate with Microsoft") - The tool will return an authentication URL — open it in your browser
- Sign in with your Microsoft account and grant consent
- The server captures the OAuth callback automatically and saves your tokens
- You're ready to use all Microsoft To Do tools
- Ask your AI assistant to run the
start-device-authtool - The tool returns a user code and a verification URL
- Open the verification URL on any device (browser, phone, etc.)
- Enter the user code when prompted and sign in with your Microsoft account
- The server polls in the background and saves your tokens automatically once you complete sign-in
- Verify your status with the
auth-statustool
The server stores authentication tokens in a tokens.json file alongside your configuration. Tokens are refreshed automatically 5 minutes before expiration. You can customize the token file location with the MSTODO_TOKEN_FILE environment variable.
Re-authentication: If your tokens expire or become invalid, simply call start-auth (authorization code flow) or start-device-auth (device code flow) again. The server also attempts automatic refresh on each API call.
The server provides 17 tools for comprehensive Microsoft To Do management. The authentication tool depends on your AUTH_FLOW setting: start-auth for authorization code flow, start-device-auth for device code flow.
| Tool | Description |
|---|---|
auth-status |
Check authentication status — shows credential presence, token expiration time, account type (personal/work), and last refresh error if any |
start-auth |
Start the Microsoft OAuth browser flow — returns a URL to open in your browser; tokens are saved automatically after consent. Available when AUTH_FLOW=authorization_code (default). |
start-device-auth |
Start device code authentication — displays a user code and verification URL; visit the URL on any device to complete sign-in. Available when AUTH_FLOW=device_code. |
| Tool | Description |
|---|---|
get-task-lists |
Retrieve all task lists with metadata (default, shared, etc.) |
get-task-lists-organized |
Retrieve task lists organized by category (owned, shared, default, flagged) |
create-task-list |
Create a new task list |
update-task-list |
Rename an existing task list |
delete-task-list |
Delete a task list and all its contents |
| Tool | Description |
|---|---|
get-tasks |
Get tasks from a list with filtering, sorting, and pagination (supports OData query parameters: $filter, $select, $orderby, $top, $skip, $count) |
create-task |
Create a new task with full property support (title, description, due date, start date, importance, reminders, status, categories) |
update-task |
Update any task properties |
delete-task |
Delete a task and all its checklist items |
| Tool | Description |
|---|---|
get-checklist-items |
Get subtasks for a specific task |
create-checklist-item |
Add a new subtask to a task |
update-checklist-item |
Update subtask text or completion status |
delete-checklist-item |
Remove a specific subtask |
| Tool | Description |
|---|---|
archive-completed-tasks |
Move completed tasks to an archive list |
| Tool | Description |
|---|---|
test-graph-api-exploration |
Explore Microsoft Graph API endpoints for debugging |
For local development:
pnpm run build # Build TypeScript to JavaScript
pnpm run dev # Build and run CLI in one command
pnpm start # Run MCP server directly
pnpm run cli # Run MCP server via CLI wrapper
pnpm run test # Run tests
pnpm run typecheck # TypeScript type checking
pnpm run format # Format code with Prettier
pnpm run format:check # Check code formatting
pnpm run lint # Run linting checks- MCP Server (
src/todo-index.ts) — Core server implementing the MCP protocol with 17 tools - CLI Wrapper (
src/cli.ts) — Executable entry point; checks for credentials and starts the server - Auth Flow Config (
src/auth-flow-config.ts) — Reads theAUTH_FLOWenvironment variable and selects the appropriate authentication flow - OAuth Engine (
src/oauth-engine.ts) — MSAL-based OAuth logic for authorization code flow: authorization URL generation, token exchange, and refresh - Device Code Engine (
src/device-code-engine.ts) — MSAL-based device code flow usingPublicClientApplication; requires onlyCLIENT_ID(no client secret) - Auth Callback Server (
src/auth-callback-server.ts) — Lightweight HTTP server that listens for the OAuth callback duringstart-authand writes tokens viaTokenManager - Token Manager (
src/token-manager.ts) — Reads, writes, and refreshes tokens intokens.json - Graph Client (
src/graph-client.ts) — Microsoft Graph API helper for authenticated requests
- Microsoft Graph API: v1.0 endpoints
- Authentication: MSAL (Microsoft Authentication Library) with PKCE flow
- Token Management: Automatic refresh 5 minutes before expiration, with
lastRefreshErrorandlastRefreshAttemptpersisted for diagnostics - Build System: tsup for fast TypeScript compilation
- Module System: ESM (ECMAScript modules)
Personal Microsoft accounts (Outlook.com, Hotmail, Live) have limited access to the Microsoft To Do API through Microsoft Graph. This is a Microsoft service limitation — not a bug in this server. Work and school accounts have full API access.
This server detects and communicates the personal account limitation proactively:
- Detection at sign-in — When you complete the
start-authorstart-device-authflow, the server checks whether your account is a personal Microsoft account and stores that information in your token metadata. - Warning via
auth-status— Runningauth-statusshows your account type (personal or work/school) so you can verify at any time. - Actionable error messages — If you use a data tool (e.g.,
get-task-lists) with a personal account, the server returns a[MAILBOX_NOT_ENABLED]error with a clear explanation and a link to this section.
You have three options to get full Microsoft To Do API access:
Microsoft offers a free developer program that includes a Microsoft 365 tenant with full Graph API access. This is the best option for personal account users who want to use this server.
Step-by-step instructions:
- Visit the Microsoft 365 Developer Program page.
- Sign in with your existing Microsoft account (personal or otherwise).
- Click Join now to enroll in the developer program (free, no credit card required).
- After joining, click Set up E5 subscription to create a free developer tenant.
- Complete the setup form — you'll choose a tenant domain name (e.g.,
yourname.onmicrosoft.com). - Once the tenant is provisioned, you'll receive a work account (e.g.,
admin@yourname.onmicrosoft.com). - Register a new Azure App in this developer tenant, making sure to set the redirect URI to
http://localhost:4040/callbackand add the required Graph API permissions (Tasks.Read,Tasks.ReadWrite,User.Read). - Update your MCP client configuration with the new
CLIENT_ID,CLIENT_SECRET, and setTENANT_IDto your developer tenant GUID (found in the Azure Portal under Overview). - Run
start-auth(orstart-device-authif using device code flow) and sign in with your new developer tenant account.
If you have a Microsoft 365 account through your employer or school:
- Update your MCP client configuration and set
TENANT_IDtoorganizations. - Run
start-auth(orstart-device-auth) and sign in with your work or school account. - Your organization's account has full To Do API access.
If you don't need programmatic access and just want to manage your tasks:
- Web: https://to-do.microsoft.com
- iOS: Download Microsoft To Do from the App Store
- Android: Download Microsoft To Do from Google Play
- Windows: Available in the Microsoft Store
The web and mobile apps work with personal accounts and provide the full To Do experience.
- Rate limits apply according to Microsoft's policies
- Some features may be unavailable for personal accounts
- Shared lists have limited functionality
"Missing required credentials" at startup
- For authorization code flow: ensure
CLIENT_IDandCLIENT_SECRETare set in your MCP client'senvconfiguration. - For device code flow: ensure
CLIENT_IDis set.CLIENT_SECRETis not required.
Token acquisition failures
- Ensure your Azure App's redirect URI matches exactly:
http://localhost:4040/callback(authorization code flow only) - Check that the required Graph API permissions (
Tasks.Read,Tasks.ReadWrite,User.Read) are added and consented - For organizational accounts, admin consent may be required
Device code flow issues
- Ensure Allow public client flows is enabled in your Azure App Registration under Authentication
- The user code expires after 15 minutes — if it expires, call
start-device-authagain - If you see "flow already in progress", the server is still polling for the previous attempt. Wait for it to complete or restart the server.
Check authentication status
Ask your AI assistant: "Check my auth status" — this runs the auth-status tool, which shows credential presence, token expiration, and any refresh errors.
The server logs diagnostic information to stderr:
# View server logs (when running from a terminal)
mstodo 2> debug.logContributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Run
pnpm run typecheckandpnpm run format:checkbefore submitting - Submit a pull request
MIT License — See LICENSE file for details.
- Fork of @jhirono/todomcp
- Built on the Model Context Protocol SDK
- Uses Microsoft Graph API