@mchlbckr/ms365todo
v0.1.7
Published
Headless-friendly CLI for Microsoft To Do (Graph API)
Readme
ms365todo
Headless-friendly CLI for Microsoft To Do using the Microsoft Graph API.
- Headless auth via Device Code Flow (works great on servers like raspberry pi)
- Multiple profiles (e.g.
work,personal) - List lists, add tasks, list tasks, complete tasks
- Filter/search tasks (title + body text + due date + created date)
This started as a helper for Clawdbot automation and is intended to become a Clawdbot skill later.
Install
From GitHub (easy)
npm i -g github:mchlbckr/ms365todoFrom npm
Once published:
npm i -g @mchlbckr/ms365todoMicrosoft Entra App (one-time)
Create an App Registration in Azure Portal:
- Supported account types: "Accounts in any organizational directory and personal Microsoft accounts"
- API permissions (Delegated):
Tasks.ReadWriteoffline_accessUser.Read
- Authentication:
- Enable Allow public client flows = Yes (required for Device Code)
Copy the Application (client) ID.
Quick start
export MS365TODO_CLIENT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# authorize a profile (headless)
ms365todo auth add work --tenant organizations
# list lists
ms365todo lists --profile work --tenant organizations
# list tasks (default: hides completed; uses server-side filter with fallback)
ms365todo tasks list --profile work --tenant organizations --list "Tasks"
# add a task
ms365todo tasks add --profile work --tenant organizations --list "Tasks" --title "Call Tim" --due 2026-01-30
# search tasks (default: hides completed)
ms365todo tasks search --profile work --tenant organizations --list "Tasks" --query "Data Camp" --show-details
# mark done
ms365todo tasks done --profile work --tenant organizations --list "Tasks" --id <taskId>Commands
Auth
- Work/school accounts:
ms365todo auth add work --tenant organizations- Personal Microsoft account:
ms365todo auth add personal --tenant consumersNote: Some enterprise tenants or registrations may block personal accounts.
Lists
ms365todo lists --profile work --tenant organizationsOutput: displayName<TAB>listId
Tasks: list
ms365todo tasks list --profile work --tenant organizations --list "Tasks"Options:
--include-completed(show everything)--completed-only
Tasks: search
ms365todo tasks search --profile work --tenant organizations --list "Tasks" --query "Tim" --show-detailsFilters:
--due YYYY-MM-DD(exact)--due-before YYYY-MM-DD--due-after YYYY-MM-DD--created-before YYYY-MM-DD--created-after YYYY-MM-DD--status notStarted|inProgress|completed--include-completed(if you didn’t set--status)
Output (default): id<TAB>status<TAB>due<TAB>created<TAB>title[<TAB>details]
Use JSON lines:
ms365todo tasks search ... --jsonTasks: complete
ms365todo tasks done --profile work --tenant organizations --list "Tasks" --id <taskId>Storage & security
Token caches are stored per profile:
~/.ms365todo/<profile>.token.json
Harden permissions:
chmod 700 ~/.ms365todo
chmod 600 ~/.ms365todo/*.token.jsonDevelopment
npm install
npm testRoadmap
- Better server-side filtering where Graph supports it (beyond status)
- Clawdbot skill wrapper (thin wrapper around this CLI)
