loading…
Search for a command to run...
loading…
A self-hosted Model Context Protocol server for Microsoft To Do. The key problem this solves: the Microsoft Graph API silently omits user-created lists on perso
A self-hosted Model Context Protocol server for Microsoft To Do. The key problem this solves: the Microsoft Graph API silently omits user-created lists on personal accounts (GET /me/todo/lists only returns well-known lists like "Flagged Emails"). This server works around it with a local SQLite registry that tracks every list you create, so your lists always show up.
A self-hosted Model Context Protocol server for Microsoft To Do. The key problem this solves: the Microsoft Graph API silently omits user-created lists on personal accounts (GET /me/todo/lists only returns well-known lists like "Flagged Emails"). This server works around it with a local SQLite registry that tracks every list you create, so your lists always show up.
Run it on your own VPS, expose it over HTTPS, and connect any MCP-compatible AI client (Claude Code, Cursor, Claude Desktop) from any machine.
Credits: Based on jordanburke/microsoft-todo-mcp-server, which is a fork of @jhirono/todomcp.
Microsoft's Graph API has a limitation for personal Microsoft accounts (outlook.com, hotmail.com, live.com, Gmail linked accounts, etc.):
POST /me/todo/lists — works, creates the list, returns an ID ✅GET /me/todo/lists — only returns built-in lists like "Flagged Emails", silently drops everything you created ❌This means any MCP server that relies purely on the API for listing will never show your custom lists. This repo fixes it by maintaining a local SQLite database (lists.db) that persists every list created through the server, then merges it with the API response so nothing is ever missing.
Your laptop / any machine
│
│ claude mcp add --transport http ...
▼
https://todo-mcp.yourdomain.com
│
├── / → Dashboard (connection status + quick-add commands)
├── /auth → Start Microsoft OAuth
├── /callback → OAuth callback (saves tokens)
├── /health → Health check
└── /mcp → MCP endpoint (API key protected)
You authenticate once via the dashboard. Tokens are stored on your server and auto-refreshed. Your API key protects the MCP endpoint so only your machines can use it.
/mcp endpointtodo-mcp)consumers) or any account (common)https://todo-mcp.yourdomain.com/callback (Web)Tasks.Read, Tasks.ReadWrite, Tasks.Read.Shared, Tasks.ReadWrite.Shared, User.Readgit clone https://github.com/akkilesh-a/microsoft-todo-mcp-server.git
cd microsoft-todo-mcp-server
npm install
npm run build
cp .env.example .env
Edit .env:
CLIENT_ID=your_azure_app_client_id
CLIENT_SECRET=your_azure_app_client_secret
TENANT_ID=consumers
PORT=3001
PUBLIC_URL=https://todo-mcp.yourdomain.com
REDIRECT_URI=https://todo-mcp.yourdomain.com/callback
MCP_API_KEY=your_secret_api_key # openssl rand -hex 32
DASHBOARD_USERNAME=admin # username for dashboard login
DASHBOARD_PASSWORD=your_dashboard_pass # set this — protects /auth
node dist/todo-index.js
Open https://todo-mcp.yourdomain.com in your browser, enter your dashboard password, and click Connect Microsoft Account. After OAuth completes, tokens are saved on the server.
The dashboard shows ready-to-copy commands. Or manually:
Claude Code:
claude mcp add --transport http mstodo https://todo-mcp.yourdomain.com/mcp \
--header "Authorization: Bearer your_api_key"
Cursor — add to ~/.cursor/mcp.json:
{
"mcpServers": {
"mstodo": {
"url": "https://todo-mcp.yourdomain.com/mcp",
"headers": { "Authorization": "Bearer your_api_key" }
}
}
}
Claude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"mstodo": {
"url": "https://todo-mcp.yourdomain.com/mcp",
"headers": { "Authorization": "Bearer your_api_key" }
}
}
}
| Layer | Protection |
|---|---|
/mcp |
MCP_API_KEY — required on every MCP request |
Dashboard /, /auth, /callback |
DASHBOARD_USERNAME + DASHBOARD_PASSWORD — HTTP basic auth |
Always set DASHBOARD_PASSWORD. Without it, anyone who knows your URL can visit the dashboard and trigger an OAuth flow that overwrites your tokens. DASHBOARD_USERNAME defaults to admin.
| Tool | Description |
|---|---|
get-task-lists |
List all task lists (API + local SQLite registry) |
create-task-list |
Create a new list |
update-task-list |
Rename a list |
delete-task-list |
Delete a list and all its tasks |
| Tool | Description |
|---|---|
get-tasks |
Get tasks with filtering, sorting, pagination |
create-task |
Create a task (title, body, due date, importance) |
update-task |
Update any task properties |
delete-task |
Delete a task |
| Tool | Description |
|---|---|
get-checklist-items |
Get subtasks for a task |
create-checklist-item |
Add a subtask |
update-checklist-item |
Update subtask text or completion |
delete-checklist-item |
Remove a subtask |
| Tool | Description |
|---|---|
auth-status |
Check token status and expiry |
archive-completed-tasks |
Archive all completed tasks in a list |
get-task-lists-organized |
Grouped/categorized view of lists |
MIT — see LICENSE
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"microsoft-todo-mcp-server-self-hosted": {
"command": "npx",
"args": []
}
}
}