Skip to main content
Glama
README.md
# todo-planner-mcp

> **Status: unmaintained.** A working, live-tested proof of concept (all 38 tools passed against
> a real Microsoft 365 tenant, October 2026). It's no longer actively developed. Feel free to fork
> it; issues and pull requests may not get a response.

An MCP (Model Context Protocol) server that exposes **Microsoft To Do** and
**Microsoft Planner** over the Microsoft Graph API with **delegated** auth, so an
assistant (e.g. a PA skill) can read *and* write your personal tasks (To Do) and your
assignable team tasks (Planner).

## Why

- The built-in Microsoft 365 connector is **read-only** and has **no Tasks/Planner** scope.
- To Do = personal catch-all. Planner = shared, assignable, cross-plan work.
- This server covers full CRUD on both, including **assigning Planner tasks to other people**.

## Requirements

- Python 3.10+
- A Microsoft Entra (Azure AD) **app registration**. Two supported modes:
  - **With a client secret** (confidential client, browser sign-in): add a **Web** platform
    redirect URI `http://localhost:8400/callback` (or whatever `TPM_REDIRECT_URI` is).
  - **Without a secret** (public client, device code): Authentication →
    **Allow public client flows: Yes**.
- Delegated API permissions: `User.Read`, `User.ReadBasic.All` (member names),
  `Tasks.ReadWrite` (To Do + Planner tasks), `Group.Read.All` (plan member lookup for
  assignment; needs tenant-admin consent), `Notes.Read.All` (OneNote, incl. team notebooks).
  See `docs/graph-reference.md` for the verified per-endpoint permissions.
  - Planner needs a **work/school account** (plans live on Microsoft 365 groups).
    A personal account can use To Do only.

## Setup

`<repo>` is your clone, `<venv>` wherever you keep the virtualenv
(on WSL, keep it in the Linux home, not on `/mnt/c` — it's flaky there).

```bash
python3 -m venv <venv>
<venv>/bin/pip install -e <repo>      # Windows: <venv>\Scripts\pip
cd <repo>
cp .env.example .env                  # set TPM_CLIENT_ID, TPM_TENANT_ID, TPM_CLIENT_SECRET
cp .mcp.json.example .mcp.json        # set "command" to <venv>/bin/python
<venv>/bin/python -m todo_planner_mcp.server --check   # offline sanity check
<venv>/bin/python -m todo_planner_mcp.server --login   # one-time sign-in
```

`--login` prints a sign-in URL (secret mode: open it, and the browser redirects back to
the localhost listener; WSL2 forwards localhost from Windows) or a device code (public mode).
The token is cached at `TPM_TOKEN_CACHE` and refreshed silently afterwards.
`.env` is read from the project root regardless of the working directory.

## Run as an MCP server

`.mcp.json` in the project root (git-ignored; copy from `.mcp.json.example`) registers the server with Claude Code (stdio). Claude Code
asks you to approve it the first time you start a session here. Run `--login` first,
because an interactive sign-in can't happen cleanly inside the MCP process.

## Tools

**To Do:** `todo_list_lists`, `todo_find_list`, `todo_create_list`, `todo_update_list`,
`todo_delete_list`, `todo_list_tasks`, `todo_get_task`, `todo_create_task`,
`todo_update_task`, `todo_complete_task`, `todo_delete_task`,
`todo_list_checklist_items`, `todo_add_checklist_item`, `todo_check_checklist_item`,
`todo_delete_checklist_item`.

**Planner:** `planner_my_tasks`, `planner_list_plans`, `planner_get_plan`,
`planner_list_buckets`, `planner_create_bucket`, `planner_list_tasks`,
`planner_get_task`, `planner_create_task`, `planner_update_task`,
`planner_assign_task`, `planner_unassign_task`, `planner_complete_task`,
`planner_delete_task`, `planner_set_description`, `planner_add_checklist_item`,
`planner_list_plan_members`, `planner_find_member`.

**OneNote (read-only, `Notes.Read`):** `onenote_list_notebooks`, `onenote_list_sections`,
`onenote_list_pages`, `onenote_search_pages` (title only), `onenote_get_page` (content as plain text).

**Health:** `whoami`.

## Notes

- Planner PATCH/DELETE use optimistic concurrency; the client fetches the current
  `@odata.etag` and retries once on 409/412 automatically.
- Secrets: `.env` and the token cache are git-ignored. Keep them private.

## License

MIT. See [LICENSE](LICENSE). Provided as-is, without warranty.

TDQS

B3.1/5.0

Scored across 38 tools

Disambiguation4/5

Tools are cleanly partitioned by domain prefix (todo_, planner_, onenote_) and action, so most purposes are clearly distinct. Minor overlap exists between planner_find_member and planner_list_plan_members (both exist to obtain user ids for assignment), and todo_update_task vs todo_complete_task are close, but descriptions disambiguate.

Naming Consistency4/5

Consistent snake_case verb_noun pattern with domain prefixes throughout (todo_create_task, planner_assign_task, onenote_get_page). Deviations are minor: the awkward todo_list_lists (list_lists) and the prefix-less whoami, which breaks the otherwise uniform scheme.

Tool Count3/5

38 tools is heavy for a single server, sitting above the comfortable range. It is mitigated by spanning three distinct products (roughly 14 To Do, 17 Planner, 5 OneNote), each of which is reasonably scoped on its own, but the aggregate surface is large.

Completeness4/5

To Do has full list/task/checklist CRUD lifecycle and Planner covers task CRUD plus assignment and membership lookup. Gaps remain: Planner buckets can be created/listed but not updated/deleted, plans cannot be created/deleted, and OneNote is entirely read-only (no page creation or editing).

Maintenance

ActivityMaintained
ResponsivenessNo issues