ms-todo-oauth
A fully-tested Microsoft To Do command-line client for managing tasks and lists via Microsoft Graph API.
⚠️This is a oauth based script. It contains a generated Azure Client ID and Secret ID
IF YOU WORRIED ABOUT YOUR PRIVACY, CONSIDER REPLACING THEM TO YOUR OWN IN scripts\ms-todo-oauth.py.
Just search for values below:
INLINECODE1
INLINECODE2
✨ Features
- - ✅ Full Task Management: Create, complete, delete, and search tasks
- 🗂️ List Organization: Create and manage multiple task lists
- ⏰ Rich Task Options: Priorities, due dates, reminders, descriptions, tags
- 🔄 Recurring Tasks: Daily, weekly, monthly patterns with custom intervals
- 📊 Multiple Views: Today, overdue, pending, statistics
- 🔍 Powerful Search: Find tasks across all lists
- 💾 Data Export: Export all tasks to JSON
- 🧪 Fully Tested: 29 comprehensive automated tests
- 🌐 Unicode Support: Full support for Chinese characters and emojis
Prerequisites
- 1. Python >= 3.9 must be installed
- Working directory: All commands MUST be run from the root of this skill (the directory containing this SKILL.md file)
- Network access: Requires internet access to Microsoft Graph API endpoints
- Microsoft Account: Personal Microsoft account (Hotmail, Outlook.com) or work/school account
- Authentication: First-time use requires OAuth2 login via browser. See Authentication section
-
Token cache:
~/.mstodo_token_cache.json (persists across sessions, auto-refreshed)
Installation & Setup
First-Time Setup
Before using this skill for the first time, dependencies must be installed:
CODEBLOCK0
Dependencies:
- -
msal (Microsoft Authentication Library) - Official Microsoft OAuth library - INLINECODE5 - HTTP client for API calls
- Specified in INLINECODE6
Environment Verification
After installation, verify the setup:
CODEBLOCK1
Troubleshooting:
- - If
Python not found, install Python 3.9 or higher from https://python.org
Testing (Optional but Recommended)
Verify all functionality works correctly:
CODEBLOCK2
See Testing section for details.
Security Notes
- - Uses official Microsoft Graph API via Microsoft's
msal library - All code is plain Python (.py files), readable and auditable
- Tokens stored locally in INLINECODE9
- All API calls go directly to Microsoft endpoints (graph.microsoft.com)
- OAuth2 standard authentication flow
- No third-party services involved
Command Reference
All commands follow this pattern:
CODEBLOCK3
Global Options
| Option | Description |
|---|
| INLINECODE10 | Show detailed information (IDs, dates, notes).Must be placed BEFORE the subcommand. |
| INLINECODE11 |
Enable debug mode to display API requests and responses. Useful for troubleshooting.
Must be placed BEFORE the subcommand. |
|
--reauth | Force re-authentication by clearing the token cache and starting fresh login |
⚠️ Common mistake: Global options MUST come before the subcommand.
- - ✅ INLINECODE13
- ✅ INLINECODE14
- ❌ INLINECODE15
Authentication
Authentication uses OAuth2 authorization code flow, designed for both interactive and automated environments.
login get — Get OAuth2 authorization URL
CODEBLOCK4
Output example:
CODEBLOCK5
What to do:
- 1. Open the provided URL in your browser
- Sign in with your Microsoft account
- Grant permissions when prompted
- You'll be redirected to a URL like: INLINECODE17
- Copy the entire code after
code= (usually a long string starting with M.R3_BAY.)
Agent behavior: Present the URL to the user and explain they need to:
- 1. Visit the URL
- Complete the login
- Copy the authorization code from the callback URL
- Provide it to you
login verify — Complete login with authorization code
CODEBLOCK6
Example:
CODEBLOCK7
Output on success:
CODEBLOCK8
Output on failure:
CODEBLOCK9
Exit code: 0 on success, 1 on failure.
Important notes:
- - Each authorization code can only be used ONCE
- If verification fails, you need to run
login get again to get a new code - Once successfully logged in, the token is cached and you won't need to login again unless:
- You run
logout
- You run
--reauth
- The token expires and cannot be auto-refreshed
logout — Clear saved login
CODEBLOCK10
Output: INLINECODE25
Only use when the user explicitly asks to switch accounts or clear login data. Under normal circumstances, the token is cached and login is automatic.
List Management
lists — List all task lists
CODEBLOCK11
Output example:
CODEBLOCK12
create-list — Create a new list
CODEBLOCK13
| Argument | Required | Description |
|---|
| INLINECODE28 | Yes | Name of the new list (supports Unicode/Chinese) |
Example:
CODEBLOCK14
Output: INLINECODE29
delete-list — Delete a list
CODEBLOCK15
| Argument/Option | Required | Description |
|---|
| INLINECODE31 | Yes | Name of the list to delete |
| INLINECODE32 |
No | Skip confirmation prompt |
⚠️ This is a destructive operation. Without -y, the command will prompt for confirmation. All tasks in the list will be deleted. Consider asking the user before deleting important lists.
Output: INLINECODE34
Exit code: 1 if list not found, 0 on success
Task Operations
add — Add a new task
CODEBLOCK16
| Option | Required | Default | Description |
|---|
| INLINECODE36 | Yes | — | Task title (positional argument, supports Unicode/Chinese/emojis) |
| INLINECODE37 |
No | (default list) | Target list name. If not specified, uses your Microsoft To Do default list. |
|
-p, --priority | No |
normal | Priority:
low,
normal,
high |
|
-d, --due | No | — | Due date. Accepts days from now (
3 or
3d) or date (
2026-02-15).
Note: Only date is supported by Microsoft To Do API, not time. |
|
-r, --reminder | No | — | Reminder datetime. Formats:
3h (hours from now),
2d (days from now),
2026-02-15 14:30 (date+time with space, needs quotes),
2026-02-15T14:30:00 (ISO format),
2026-02-15 (date only, defaults to 09:00). |
|
-R, --recurrence | No | — | Recurrence pattern. Formats:
daily (every day),
weekdays (Mon-Fri),
weekly (every week),
monthly (every month). With interval:
daily:2 (every 2 days),
weekly:3 (every 3 weeks),
monthly:2 (every 2 months). |
|
-D, --description | No | — | Task description/notes (supports multiline with quotes) |
|
-t, --tags | No | — | Comma-separated tags/categories (e.g.,
"work,urgent") |
|
--create-list | No | False | Create the list if it doesn't exist (deprecated, lists auto-create now) |
Auto-created lists: If the specified list doesn't exist, it will be automatically created.
Output example:
CODEBLOCK17
With recurrence:
CODEBLOCK18
Examples:
CODEBLOCK19
complete — Mark a task as completed
CODEBLOCK20
| Option | Required | Default | Description |
|---|
| INLINECODE66 | Yes | — | Exact task title |
| INLINECODE67 |
No | (default list) | List name where the task resides |
Title matching: Requires exact match. If unsure of exact title, use search first.
Output: INLINECODE69
Exit code: 1 if task not found, 0 on success
delete — Delete a task
CODEBLOCK21
| Option | Required | Default | Description |
|---|
| INLINECODE71 | Yes | — | Exact task title |
| INLINECODE72 |
No | (default list) | List name where the task resides |
|
-y, --yes | No | — | Skip confirmation prompt |
⚠️ Destructive operation. Without -y, will prompt for confirmation.
Output: INLINECODE75
Exit code: 1 if task not found, 0 on success
Task Views
tasks — List tasks in a specific list
CODEBLOCK22
| Option | Required | Description |
|---|
| INLINECODE77 | Yes | List name (exact match) |
| INLINECODE78 |
No | Include completed tasks (default: incomplete only) |
Output example:
CODEBLOCK23
With -a flag:
CODEBLOCK24
Exit code: 1 if list not found, 0 on success
pending — All incomplete tasks across all lists
CODEBLOCK25
| Option | Required | Description |
|---|
| INLINECODE81 | No | Group results by list |
Output example (with -g):
CODEBLOCK26
Without -g:
CODEBLOCK27
today — Tasks due today
CODEBLOCK28
Lists incomplete tasks with due date matching today's date.
Output example:
CODEBLOCK29
If no tasks: INLINECODE85
overdue — Overdue tasks
CODEBLOCK30
Lists incomplete tasks past their due date, sorted by days overdue.
Output example:
CODEBLOCK31
If no overdue tasks: INLINECODE87
detail — View full task details
CODEBLOCK32
| Option | Required | Default | Description |
|---|
| INLINECODE89 | Yes | — | Task title (supportspartial/fuzzy match) |
| INLINECODE90 |
No | (default list) | List name |
Fuzzy matching: Matches tasks containing the search string (case-insensitive).
When multiple tasks match:
- - Prefers incomplete tasks over completed
- Returns most recently modified task
Output example:
CODEBLOCK33
search — Search tasks by keyword
CODEBLOCK34
Searches across all lists in both task titles and descriptions (case-insensitive).
Output example:
CODEBLOCK35
stats — Task statistics
CODEBLOCK36
Shows aggregate statistics across all lists.
Output example:
CODEBLOCK37
export — Export all tasks to JSON
CODEBLOCK38
| Option | Required | Default | Description |
|---|
| INLINECODE94 | No | INLINECODE95 | Output file path |
Exports complete task data from all lists in JSON format.
Output: INLINECODE96
JSON structure:
CODEBLOCK39
Error Handling
Exit Codes
| Code | Meaning |
|---|
| INLINECODE97 | Success |
| INLINECODE98 |
Failure (not logged in, API error, invalid arguments, resource not found) |
|
2 | Invalid command-line arguments |
Common Error Messages
| Error | Cause | Resolution |
|---|
| INLINECODE100 | No cached token or token expired | Run login get then INLINECODE102 |
| INLINECODE103 |
Dependencies not installed | Run
pip install -r requirements.txt |
|
❌ List not found: <name> | Specified list does not exist | Check list name with
lists command. Note: exact match required. |
|
❌ Task not found: <name> | No task with exact matching title | Use
search to find exact title, or
tasks "<list>" to list all tasks |
|
❌ Error: Invalid isoformat string | DateTime parsing error | This should not occur in v1.1.0+. If you see this, report as bug. |
|
❌ Error: Unsupported HTTP method | Internal API error | This should not occur in v1.1.0+. If you see this, report as bug. |
|
❌ Error: <API error message> | Microsoft Graph API error | Retry; check network; use
--debug for full details |
|
Network error /
Connection timeout | No internet or API unreachable | Check network connection; verify access to graph.microsoft.com |
Testing
This skill includes a comprehensive test suite to ensure reliability.
Automated Testing
Run the full test suite:
CODEBLOCK40
Prerequisites:
- - Must be authenticated (logged in) before running tests
- Internet connection required
- Approximately 2-3 minutes to complete
Test Coverage (29 tests):
- - ✅ Authentication (login/logout)
- ✅ List management (create, delete, list)
- ✅ Basic task operations (add, complete, delete, list)
- ✅ Task options (priorities, due dates, reminders, descriptions, tags)
- ✅ Recurring tasks (daily, weekly, weekdays, monthly, custom intervals)
- ✅ Task views (today, overdue, pending, search, stats)
- ✅ Data export and validation
- ✅ Error handling (non-existent resources)
- ✅ Unicode support (Chinese characters, emojis)
Expected output:
CODEBLOCK41
Manual Testing
For manual verification, see MANUAL_TEST_CHECKLIST.txt which provides:
- - Step-by-step test procedures
- Expected outcomes
- 9 test categories covering all functionality
Test Cleanup
The automated test suite:
- - Creates a temporary test list (e.g.,
🧪 Test List 14:23:45) - Runs all tests in isolation
- Deletes the test list on completion
- Cleans up any temporary files
If tests are interrupted, you may need to manually delete leftover test lists.
Agent Usage Guidelines
Critical Rules
- 1. Working directory: Always
cd to the directory containing this SKILL.md before running commands. - Dependency installation: Before first use or when encountering import errors, ensure all dependencies are installed.
- Check authentication first: Before any operation, verify authentication status:
CODEBLOCK42
If this returns "Not logged in" error (exit code 1), initiate the login flow.
- 4. Task list organization: When adding tasks:
- First, run lists to see available task lists
- If user doesn't specify a list, tasks will be added to their default list (usually "Tasks" or "任务")
- Intelligently categorize tasks into appropriate lists:
- Work tasks → "Work" list
- Personal errands → "Personal" or default list
- Shopping → "Shopping" list
- Project-specific → Use project name as list
- Lists will be auto-created if they don't exist
- Support Chinese list names and Unicode characters
- 5. Destructive operations: For
delete and delete-list:
- These commands prompt for confirmation by default (blocking behavior)
- Use -y flag ONLY when:
- User has explicitly requested to delete without confirmation
- The deletion intent is unambiguous and confirmed through conversation
- When in doubt, ask the user for confirmation instead of using -y
- These operations return exit code 1 on failure (resource not found)
- 6. Global option placement:
-v, --debug, and --reauth must come BEFORE the subcommand:
- ✅ python3 scripts/ms-todo-oauth.py -v lists
- ❌ python3 scripts/ms-todo-oauth.py lists -v
- 7. Login flow:
- Do NOT call login verify until user confirms they've completed browser authentication
- Each authorization code can only be used once
- If verify fails, you must run login get again for a new code
- 8. Error handling:
- Check exit codes: 0 = success, 1 = failure, 2 = invalid arguments
- Parse error messages to provide helpful guidance
- Use --debug flag when troubleshooting API issues
Recommended Workflow for Agents
CODEBLOCK43
Task Title Matching Rules
- - Exact match required:
complete, delete commands - Partial/fuzzy match supported:
detail, search commands - Case-insensitive: All search operations
- Best practice: Use
search first to find exact title, then use it in subsequent commands
Example workflow:
CODEBLOCK44
Default List Behavior
- - When
-l is not specified, operations use the Microsoft To Do default list - The default list is typically named "Tasks" (English) or "任务" (Chinese)
- To target a specific list, always provide INLINECODE138
Example Task Categorization
User request: "Add these tasks: buy milk, finish report, call dentist"
Agent approach:
CODEBLOCK45
Quick Reference
Common Workflows
Daily task review:
CODEBLOCK46
Adding various task types:
CODEBLOCK47
Task completion workflow:
CODEBLOCK48
Data management:
CODEBLOCK49
Changelog
Version 1.1.0 (Current)
- - ✅ Fixed: DateTime parsing errors (Microsoft's 7-decimal format)
- ✅ Fixed: HTTP method parameter order bugs
- ✅ Fixed: Missing
start_date parameter in INLINECODE140 - ✅ Fixed: Missing
complete_task() method - ✅ Fixed: Error exit codes now correctly return 1 on failure
- ✅ Added: Comprehensive test suite (29 automated tests)
- ✅ Added: Better error messages and troubleshooting
- ✅ Improved: OAuth2 authentication flow documentation
- ✅ Improved: Unicode and emoji support documentation
- ✅ Improved: Agent usage guidelines
Version 1.0.2 (Previous)
- - Initial release with OAuth2 authentication
- Basic task and list management
- Recurring task support
- Multiple task views
- Data export functionality
Troubleshooting
Authentication Issues
Problem: INLINECODE142
- - Solution: Run
login get, complete browser flow, then INLINECODE144
Problem: INLINECODE145
- - Cause: Authorization code already used or expired
- Solution: Run
login get again to get a fresh code
Problem: Login worked but now getting "Not logged in" again
- - Cause: Token expired and auto-refresh failed
- Solution: Run
--reauth to force fresh login:
CODEBLOCK50
Import/Dependency Issues
Problem: INLINECODE148
- - Solution: Install dependencies: INLINECODE149
API/Network Issues
Problem: Connection timeout or network errors
- - Check: Internet connection
- Check: Can you access https://graph.microsoft.com in browser?
- Try: Using
--debug flag to see full API request/response
Problem: Unexpected API errors
- - Try: Re-authenticate: INLINECODE151
- Try: Debug mode: INLINECODE152
Task/List Not Found
Problem: INLINECODE153
- - Solution: Use
search to find exact title - Note:
complete and delete require exact title match
Problem: INLINECODE157
- - Solution: Run
lists to see exact list names - Note: List names are case-sensitive
Test Failures
Problem: Tests failing with datetime errors
- - Solution: Ensure you've applied all v1.1.0 fixes
- Check: Verify
_parse_ms_datetime() helper function exists
Problem: Tests failing with "Not logged in"
- - Solution: Authenticate before running tests:
python3 scripts/ms-todo-oauth.py login get
# Complete browser flow
python3 scripts/ms-todo-oauth.py login verify <code>
# Then run tests
python3 test_ms_todo_oauth.py
Additional Resources
- - Test Suite:
test_ms_todo_oauth.py - Automated tests - Manual Tests:
MANUAL_TEST_CHECKLIST.txt - Step-by-step testing guide - Quick Reference:
QUICK_REFERENCE.txt - Command cheat sheet - Bug Fixes:
COMPLETE_FIX_PATCH.txt - Documentation of v1.1.0 fixes
Support & Contributing
Reporting Issues:
- - Provide error message and command used
- Include output from
--debug flag if applicable - Note your Python version: INLINECODE165
- Note your OS: Windows/Mac/Linux
Testing New Features:
- - Always run the test suite after code changes
- Add new test cases to
test_ms_todo_oauth.py for new features - Update
MANUAL_TEST_CHECKLIST.txt with manual test procedures
License
MIT License - See LICENSE file for details
Version: 1.1.0
Last Updated: 2026-02-13
Status: ✅ Fully Tested & Production Ready