Spencer McGuire b3918c3ee6 Fix Windows sign-in: don't launch the browser through cmd.exe (v1.0.1)
cmd's `start` splits unquoted commands at "&", truncating the OAuth authorize
URL after the first query parameter — Windows users hit AADSTS900144 (missing
'scope'). Launch via rundll32 url.dll,FileProtocolHandler instead, which takes
the URL as a plain argument with no shell parsing.

Same fix as claude-msplanner b07a241, applied to the canonical skill copy and
synced into the extension bundle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 08:01:12 -06:00

Claude-MSTodo

Connect Claude to Microsoft To Do via the Microsoft Graph API, with full read/write (CRUD) over task lists, tasks, and checklist items (subtasks).

This is a sibling to Claude-SharepointLists, built the same way — a dependency-free core Graph client (graph.mjs) wrapped by a small CLI and packaged as a Claude Code skill. The one fundamental difference is authentication:

SharePoint Lists Microsoft To Do
Auth model App-only (client credentials) Delegated (browser, auth-code + PKCE)
Why SharePoint supports application permissions To Do has no app-only access — /me/todo needs a user token
Secrets tenant + client id + client secret client id only (public client, no secret)
First run works immediately login once (opens browser); refresh token cached

A browser flow is used rather than device-code because device-code is commonly blocked by Conditional Access (AADSTS53003).

Two ways to use it, sharing one core Graph client (graph.mjs):

Form Best for Entry point
Skill Claude Code on your own machine .claude/skills/ms-todo/
Desktop extension (.mcpb) Claude Desktop, distributed org-wide mcp-extension/

Repo layout

.
├── .claude/skills/ms-todo/              # the skill (Claude Code)
│   ├── SKILL.md                         # how the skill works + usage
│   ├── .env.example                     # config template (.env is git-ignored)
│   ├── scripts/
│   │   ├── todo.mjs                     # CLI: login|logout|test|lists|tasks|get|create|update|done|delete|checklist…
│   │   └── lib/graph.mjs                # shared, dependency-free Graph client (MSTodoClient) — single source of truth
│   └── references/
│       ├── setup.md                     # Entra app registration walkthrough (public client + loopback redirect)
│       └── graph-api.md                 # todoTask field formats + OData query reference
└── mcp-extension/                       # Claude Desktop extension (imports the same graph.mjs)
    ├── manifest.json                    # .mcpb manifest (baked client/tenant id, user_config)
    ├── server/index.mjs                 # MCP server (stdio) exposing todo_* tools
    ├── scripts/sync-core.mjs            # copies the canonical graph.mjs into the bundle
    └── README.md                        # build + install + admin setup

For Claude Desktop, build and distribute the extension — see mcp-extension/README.md. (Claude Desktop can't run Claude Code skills; it loads MCP servers, so the .mcpb is the right vehicle.)

Prerequisites (one-time)

An Entra (Azure AD) public client app registration with the delegated Tasks.ReadWrite permission and a loopback redirect URI (http://localhost + http://127.0.0.1) under the Mobile-and-desktop platform. The full walkthrough is in references/setup.md. You end up needing just one value: TODO_CLIENT_ID (and optionally TODO_TENANT_ID).

There is no client secret — To Do is a personal/delegated resource, so you sign in as yourself once and the refresh token is cached in a git-ignored file.

Quick start

cp .claude/skills/ms-todo/.env.example .claude/skills/ms-todo/.env
# set TODO_CLIENT_ID (and TODO_TENANT_ID if not "common")

cd .claude/skills/ms-todo/scripts
node todo.mjs login          # open the printed URL, enter the code, approve
node todo.mjs test           # -> { ok: true, signedInAs, listCount, lists: [...] }

node todo.mjs lists
node todo.mjs tasks  --list "Work" --filter "status ne 'completed'" --orderby "dueDateTime/dateTime asc"
node todo.mjs create --list "Work" --title "Renew SSL cert" --due 2026-07-01 --importance high
node todo.mjs done   --list "Work" --id "<TASK_ID>"

See SKILL.md for the full command set and references/graph-api.md for task field formats and OData query details.

Commands

Command Purpose
login / logout Browser sign-in (auth-code+PKCE) / forget the cached sign-in
test Verify auth; show signed-in user and task lists
lists List all task lists
list-create / list-update / list-delete Manage task lists
tasks Query tasks (--filter/--select/--orderby/--top/--all)
get Get one task by id
create / update / done / delete Manage tasks
checklist / checklist-add / checklist-check / checklist-delete Manage subtasks

Security notes

  • Delegated auth = the cached token acts as you. Anyone with read access to scripts/.token-cache.json can use your To Do. It's written 0600 and git-ignored — keep it that way; logout deletes it.
  • There is no client secret to leak; the public-client app id is not a secret.
  • The skill is for the signed-in user's own tasks. To act as another user you'd sign in as them (or, for an MCP server, run a separate cache per account).

Graduating to an MCP server

The Graph + auth logic lives entirely in graph.mjs (MSTodoClient, zero dependencies), so it drops straight into an @modelcontextprotocol/sdk server — expose listTasks/getTask/createTask/updateTask/deleteTask and the list/checklist methods as tools. The only extra step vs. an app-only server: run login once on the host to seed the token cache the server reads. See the note at the bottom of references/setup.md.

Description
Connect Claude to Microsoft To Do via Microsoft Graph — Claude Code skill + Claude Desktop .mcpb extension.
Readme 107 KiB
2026-07-10 14:01:12 +00:00
Languages
JavaScript 97.5%
Shell 2.5%