npm package: @mchlbckr/ms365todo
Description: Headless-friendly CLI for Microsoft To Do (Graph API)
Author: Michael Bücker
Latest version: 0.1.7

# 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)

```bash
npm i -g github:mchlbckr/ms365todo
```

### From npm

Once published:

```bash
npm i -g @mchlbckr/ms365todo
```

---

## Microsoft 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.ReadWrite`
  - `offline_access`
  - `User.Read`
- **Authentication**:
  - Enable **Allow public client flows** = Yes (required for Device Code)

Copy the **Application (client) ID**.

---

## Quick start

```bash
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:

```bash
ms365todo auth add work --tenant organizations
```

- Personal Microsoft account:

```bash
ms365todo auth add personal --tenant consumers
```

> Note: Some enterprise tenants or registrations may block personal accounts.

### Lists

```bash
ms365todo lists --profile work --tenant organizations
```

Output: `displayName<TAB>listId`

### Tasks: list

```bash
ms365todo tasks list --profile work --tenant organizations --list "Tasks"
```

Options:
- `--include-completed` (show everything)
- `--completed-only`

### Tasks: search

```bash
ms365todo tasks search --profile work --tenant organizations --list "Tasks" --query "Tim" --show-details
```

Filters:
- `--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:
```bash
ms365todo tasks search ... --json
```

### Tasks: complete

```bash
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:

```bash
chmod 700 ~/.ms365todo
chmod 600 ~/.ms365todo/*.token.json
```

---

## Development

```bash
npm install
npm test
```

---

## Roadmap

- Better server-side filtering where Graph supports it (beyond status)
- Clawdbot skill wrapper (thin wrapper around this CLI)