> ## Documentation Index
> Fetch the complete documentation index at: https://docs.doers.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Planning

> The day's plan, ADHD-mode rounds, work sessions, the journal and habits.

23 tools. Each one is also a REST route and a CLI command, from the same definition: the same input, the same output, the same errors.

| Tool                                                | What it does                                          | Kind                                                  |
| --------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- |
| [`get_current_session`](#get_current_session)       | Get the running session                               | Read · idempotent · no outside service                |
| [`get_day_plan`](#get_day_plan)                     | Read the day's plan                                   | Read · idempotent · no outside service                |
| [`get_journal`](#get_journal)                       | Read the journal window                               | Read · idempotent · no outside service                |
| [`list_due_habits`](#list_due_habits)               | What is due on a day                                  | Read · idempotent · no outside service                |
| [`list_habit_completions`](#list_habit_completions) | What was done, over a window                          | Read · idempotent · no outside service                |
| [`list_habits`](#list_habits)                       | List your habits                                      | Read · idempotent · no outside service                |
| [`list_rounds`](#list_rounds)                       | The rounds of a day                                   | Read · idempotent · no outside service                |
| [`list_today_sessions`](#list_today_sessions)       | List the day's sessions                               | Read · idempotent · no outside service                |
| [`suggest_day_plan`](#suggest_day_plan)             | Propose a plan for the day                            | Read · idempotent · no outside service                |
| [`archive_habit`](#archive_habit)                   | Archive a habit                                       | Write · destructive · no outside service              |
| [`close_round`](#close_round)                       | Close a round                                         | Write · idempotent · no outside service               |
| [`complete_habit`](#complete_habit)                 | Complete a habit for a day                            | Write · idempotent · no outside service               |
| [`create_habit`](#create_habit)                     | Create a habit                                        | Write · no outside service                            |
| [`mark_round_engaged`](#mark_round_engaged)         | Record that a round was actually worked               | Write · idempotent · no outside service               |
| [`plan_round`](#plan_round)                         | Fill an ADHD-mode round                               | Write · idempotent · no outside service               |
| [`plan_today`](#plan_today)                         | Save the day's plan                                   | Write · idempotent · no outside service               |
| [`set_round_plan`](#set_round_plan)                 | Plan a round                                          | Write · idempotent · no outside service               |
| [`share_session`](#share_session)                   | Share a finished session to Activity, or take it back | Write · idempotent · no outside service               |
| [`start_session`](#start_session)                   | Start a session                                       | Write · no outside service                            |
| [`stop_session`](#stop_session)                     | Stop the running session                              | Write · idempotent · no outside service               |
| [`uncomplete_habit`](#uncomplete_habit)             | Undo a day's completion                               | Write · destructive · idempotent · no outside service |
| [`update_habit`](#update_habit)                     | Update a habit                                        | Write · idempotent · no outside service               |
| [`upsert_journal_entry`](#upsert_journal_entry)     | Write the day's mood and note                         | Write · idempotent · no outside service               |

## get\_current\_session

**Get the running session.**

Returns the session still running, or `null` when the timer is stopped.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/sessions/current`                                  |
| CLI       | `doers sessions get-current`                                                    |
| Touches   | `workSessions`                                                                  |
| Operation | `getCurrentSession`                                                             |

### Input

This tool takes no arguments.

### Output

<Accordion title="Output fields">
  | Field                | Type           | Allowed values                    | Description                                                                       |
  | -------------------- | -------------- | --------------------------------- | --------------------------------------------------------------------------------- |
  | `session`            | object \| null |                                   |                                                                                   |
  | `session.id`         | string         |                                   |                                                                                   |
  | `session.taskId`     | string \| null |                                   |                                                                                   |
  | `session.title`      | string         |                                   |                                                                                   |
  | `session.startedAt`  | number         |                                   | Epoch milliseconds.                                                               |
  | `session.endedAt`    | number \| null |                                   | `null` while the session is still running.                                        |
  | `session.visibility` | string         | `public`, `anonymized`, `private` | What the activity feed may show of it. Private until shared at the session's end. |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_current_session",
      "arguments": {}
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "Running: “Prepare the Acme quarterly review” since 2026-09-22T09:30:00.000Z."
        }
      ],
      "structuredContent": {
        "session": {
          "id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
          "taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
          "title": "Prepare the Acme quarterly review",
          "startedAt": 1790069400000,
          "endedAt": 1790069400000,
          "visibility": "public"
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers sessions get-current
  ```
</CodeGroup>

## get\_day\_plan

**Read the day's plan.**

Returns the saved plan for the day (3 to 5 tasks, one focus task, a note) and the state of the ADHD-mode rounds.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/plan`                                              |
| CLI       | `doers plan get`                                                                |
| Touches   | `coachPlanTasks`, `coachPlans`, `roundTasks`, `rounds`, `tasks`                 |
| Operation | `getDayPlan`                                                                    |

### Input

| Field         | Type   | Required | Default | Allowed values | Description                  |
| ------------- | ------ | -------- | ------- | -------------- | ---------------------------- |
| `day` (query) | string | no       |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`. |

### Output

<Accordion title="Output fields">
  | Field                   | Type                 | Allowed values                        | Description |
  | ----------------------- | -------------------- | ------------------------------------- | ----------- |
  | `day`                   | string               |                                       |             |
  | `plan`                  | object \| null       |                                       |             |
  | `plan.taskIds`          | string\[]            |                                       |             |
  | `plan.focusTaskId`      | string \| null       |                                       |             |
  | `plan.note`             | string               |                                       |             |
  | `plan.tasks`            | object\[]            |                                       |             |
  | `plan.tasks[].id`       | string               |                                       |             |
  | `plan.tasks[].title`    | string               |                                       |             |
  | `plan.tasks[].priority` | integer              | -9007199254740991 to 9007199254740991 |             |
  | `plan.tasks[].score`    | number (optional)    |                                       |             |
  | `plan.tasks[].reasons`  | string\[] (optional) |                                       |             |
  | `rounds`                | object\[]            |                                       |             |
  | `rounds[].index`        | integer              | -9007199254740991 to 9007199254740991 |             |
  | `rounds[].label`        | string               |                                       |             |
  | `rounds[].taskIds`      | string\[]            |                                       |             |
  | `rounds[].engaged`      | boolean              |                                       |             |
  | `rounds[].closedAt`     | number \| null       |                                       |             |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_day_plan",
      "arguments": {
        "day": "2026-09-22"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "Plan for 2026-09-22: Prepare the Acme quarterly review."
        }
      ],
      "structuredContent": {
        "day": "2026-09-22",
        "plan": {
          "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
          "focusTaskId": "330571bf-d351-4dd2-8723-26c22871d591",
          "note": "Notes for the Acme launch.",
          "tasks": [
            {
              "id": "0ebb429f-a86d-481c-8630-fac53db1c91c",
              "title": "Prepare the Acme quarterly review",
              "priority": 2,
              "score": 3,
              "reasons": ["Notes for the Acme launch."]
            }
          ]
        },
        "rounds": [
          {
            "index": 0,
            "label": "Acme",
            "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
            "engaged": true,
            "closedAt": 1790069400000
          }
        ]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers plan get --day 2026-09-22
  ```
</CodeGroup>

## get\_journal

**Read the journal window.**

The raw material of the journal: tasks completed, sessions worked, and the entries written. Nothing is bucketed by day: the caller's timezone decides where a day starts, and only the caller knows it. `since` bounds the first two; `sinceDay` bounds the entries, which are already keyed by local day.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/journal`                                           |
| CLI       | `doers journal get`                                                             |
| Touches   | `journalEntries`                                                                |
| Operation | `getJournal`                                                                    |

### Input

| Field              | Type   | Required | Default | Allowed values | Description                  |
| ------------------ | ------ | -------- | ------- | -------------- | ---------------------------- |
| `since` (query)    | number | yes      |         |                | Epoch milliseconds.          |
| `sinceDay` (query) | string | yes      |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`. |

### Output

<Accordion title="Output fields">
  | Field                       | Type            | Allowed values                        | Description                                                                       |
  | --------------------------- | --------------- | ------------------------------------- | --------------------------------------------------------------------------------- |
  | `completions`               | object\[]       |                                       |                                                                                   |
  | `completions[].id`          | string          |                                       |                                                                                   |
  | `completions[].title`       | string          |                                       |                                                                                   |
  | `completions[].completedAt` | number          |                                       | Epoch milliseconds.                                                               |
  | `completions[].projectId`   | string \| null  |                                       |                                                                                   |
  | `completions[].areaId`      | string \| null  |                                       |                                                                                   |
  | `sessions`                  | object\[]       |                                       |                                                                                   |
  | `sessions[].id`             | string          |                                       |                                                                                   |
  | `sessions[].taskId`         | string \| null  |                                       |                                                                                   |
  | `sessions[].title`          | string          |                                       |                                                                                   |
  | `sessions[].startedAt`      | number          |                                       | Epoch milliseconds.                                                               |
  | `sessions[].endedAt`        | number \| null  |                                       | `null` while the session is still running.                                        |
  | `sessions[].visibility`     | string          | `public`, `anonymized`, `private`     | What the activity feed may show of it. Private until shared at the session's end. |
  | `entries`                   | object\[]       |                                       |                                                                                   |
  | `entries[].day`             | string          | `YYYY-MM-DD`                          | Local day key, `YYYY-MM-DD`.                                                      |
  | `entries[].mood`            | integer \| null | -9007199254740991 to 9007199254740991 | 1 worst: 5 best, or `null` for a day left unrated.                                |
  | `entries[].note`            | string          |                                       |                                                                                   |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_journal",
      "arguments": {
        "since": 3,
        "sinceDay": "2026-09-22"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "1 completed · 1 session(s) · 1 entr(y/ies)."
        }
      ],
      "structuredContent": {
        "completions": [
          {
            "id": "21606b58-37ee-4917-8e56-cff2afe21083",
            "title": "Prepare the Acme quarterly review",
            "completedAt": 1790069400000,
            "projectId": "244210e4-8437-4655-8980-a70249a99369",
            "areaId": "4a91ee5f-0106-42b3-8c11-c168352f0abf"
          }
        ],
        "sessions": [
          {
            "id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
            "taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
            "title": "Prepare the Acme quarterly review",
            "startedAt": 1790069400000,
            "endedAt": 1790069400000,
            "visibility": "public"
          }
        ],
        "entries": [
          {
            "day": "2026-09-22",
            "mood": 3,
            "note": "Notes for the Acme launch."
          }
        ]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers journal get --since 3 --since-day 2026-09-22
  ```
</CodeGroup>

## list\_due\_habits

**What is due on a day.**

The habits whose rule fires on that day, each with its completion for the day if any. Archived habits are never due.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/habits/due/{day}`                                  |
| CLI       | `doers habits list-due`                                                         |
| Touches   | `habitCompletions`, `habits`                                                    |
| Operation | `listDueHabits`                                                                 |

### Input

| Field        | Type   | Required | Default | Allowed values | Description                  |
| ------------ | ------ | -------- | ------- | -------------- | ---------------------------- |
| `day` (path) | string | yes      |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`. |

### Output

<Accordion title="Output fields">
  | Field                             | Type                  | Allowed values                 | Description                                                                                   |
  | --------------------------------- | --------------------- | ------------------------------ | --------------------------------------------------------------------------------------------- |
  | `habits`                          | object\[]             |                                |                                                                                               |
  | `habits[].habit`                  | object                |                                |                                                                                               |
  | `habits[].habit.id`               | string                |                                |                                                                                               |
  | `habits[].habit.name`             | string                |                                |                                                                                               |
  | `habits[].habit.startsOn`         | string                | `YYYY-MM-DD`                   | The anchor every occurrence is expanded from.                                                 |
  | `habits[].habit.rule`             | object                |                                | A habit's rule: the task's repeat grammar without a mode, phased on `startsOn`.               |
  | `habits[].habit.rule.every`       | integer               | 1 to 365                       | The multiplier: 2 × week.                                                                     |
  | `habits[].habit.rule.unit`        | string                | `day`, `week`, `month`, `year` |                                                                                               |
  | `habits[].habit.rule.weekdays`    | integer\[] (optional) | at most 7 items, each: 1 to 7  | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit "week". |
  | `habits[].habit.target`           | object                |                                | What one occurrence asks for: a tick, a quantity in a unit, or minutes.                       |
  | `habits[].habit.target.kind`      | string                | `check`, `quantity`, `minutes` |                                                                                               |
  | `habits[].habit.target.amount`    | integer (optional)    | 1 to 100000                    |                                                                                               |
  | `habits[].habit.target.unit`      | string (optional)     | 1 to 40 characters             |                                                                                               |
  | `habits[].habit.target.minutes`   | integer (optional)    | 1 to 1440                      |                                                                                               |
  | `habits[].habit.createdAt`        | number                |                                | Epoch milliseconds.                                                                           |
  | `habits[].habit.archivedAt`       | number \| null        |                                |                                                                                               |
  | `habits[].completion`             | object \| null        |                                |                                                                                               |
  | `habits[].completion.id`          | string                |                                |                                                                                               |
  | `habits[].completion.habitId`     | string                |                                |                                                                                               |
  | `habits[].completion.day`         | string                | `YYYY-MM-DD`                   | Local day key, `YYYY-MM-DD`.                                                                  |
  | `habits[].completion.amount`      | integer \| null       | 0 to 9007199254740991          | What was done, for a quantity target.                                                         |
  | `habits[].completion.minutes`     | integer \| null       | 0 to 9007199254740991          | What was done, for a minutes target.                                                          |
  | `habits[].completion.completedAt` | number                |                                | Epoch milliseconds.                                                                           |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_due_habits",
      "arguments": {
        "day": "2026-09-22"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "- [09aee23b-1fd4-4638-818d-2c392100518a] Acme ✓"
        }
      ],
      "structuredContent": {
        "habits": [
          {
            "habit": {
              "id": "09aee23b-1fd4-4638-818d-2c392100518a",
              "name": "Acme",
              "startsOn": "2026-09-22",
              "rule": {
                "every": 3,
                "unit": "day"
              },
              "target": {
                "kind": "check"
              },
              "createdAt": 1790069400000,
              "archivedAt": 1790069400000
            },
            "completion": {
              "id": "21606b58-37ee-4917-8e56-cff2afe21083",
              "habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
              "day": "2026-09-22",
              "amount": 3,
              "minutes": 30,
              "completedAt": 1790069400000
            }
          }
        ]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers habits list-due --day 2026-09-22
  ```
</CodeGroup>

## list\_habit\_completions

**What was done, over a window.**

Every completion between two days inclusive, oldest first, archived habits included: the ledger the Logbook and the Stats read.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/habits/completions`                                |
| CLI       | `doers habits list-habit-completions`                                           |
| Touches   | `habitCompletions`, `habits`                                                    |
| Operation | `listHabitCompletions`                                                          |

### Input

| Field           | Type   | Required | Default | Allowed values | Description                  |
| --------------- | ------ | -------- | ------- | -------------- | ---------------------------- |
| `since` (query) | string | yes      |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`. |
| `until` (query) | string | yes      |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`. |

### Output

<Accordion title="Output fields">
  | Field                       | Type            | Allowed values        | Description                           |
  | --------------------------- | --------------- | --------------------- | ------------------------------------- |
  | `completions`               | object\[]       |                       |                                       |
  | `completions[].id`          | string          |                       |                                       |
  | `completions[].habitId`     | string          |                       |                                       |
  | `completions[].day`         | string          | `YYYY-MM-DD`          | Local day key, `YYYY-MM-DD`.          |
  | `completions[].amount`      | integer \| null | 0 to 9007199254740991 | What was done, for a quantity target. |
  | `completions[].minutes`     | integer \| null | 0 to 9007199254740991 | What was done, for a minutes target.  |
  | `completions[].completedAt` | number          |                       | Epoch milliseconds.                   |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_habit_completions",
      "arguments": {
        "since": "2026-09-22",
        "until": "2026-09-22"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "1 completion(s)."
        }
      ],
      "structuredContent": {
        "completions": [
          {
            "id": "21606b58-37ee-4917-8e56-cff2afe21083",
            "habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
            "day": "2026-09-22",
            "amount": 3,
            "minutes": 30,
            "completedAt": 1790069400000
          }
        ]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers habits list-habit-completions --since 2026-09-22 --until 2026-09-22
  ```
</CodeGroup>

## list\_habits

**List your habits.**

Every habit, oldest first. Archived ones only when asked for.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/habits`                                            |
| CLI       | `doers habits list`                                                             |
| Touches   | `habitCompletions`, `habits`                                                    |
| Operation | `listHabits`                                                                    |

### Input

| Field                     | Type    | Required | Default | Allowed values | Description                       |
| ------------------------- | ------- | -------- | ------- | -------------- | --------------------------------- |
| `includeArchived` (query) | boolean | no       |         |                | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field                     | Type                  | Allowed values                 | Description                                                                                   |
  | ------------------------- | --------------------- | ------------------------------ | --------------------------------------------------------------------------------------------- |
  | `habits`                  | object\[]             |                                |                                                                                               |
  | `habits[].id`             | string                |                                |                                                                                               |
  | `habits[].name`           | string                |                                |                                                                                               |
  | `habits[].startsOn`       | string                | `YYYY-MM-DD`                   | The anchor every occurrence is expanded from.                                                 |
  | `habits[].rule`           | object                |                                | A habit's rule: the task's repeat grammar without a mode, phased on `startsOn`.               |
  | `habits[].rule.every`     | integer               | 1 to 365                       | The multiplier: 2 × week.                                                                     |
  | `habits[].rule.unit`      | string                | `day`, `week`, `month`, `year` |                                                                                               |
  | `habits[].rule.weekdays`  | integer\[] (optional) | at most 7 items, each: 1 to 7  | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit "week". |
  | `habits[].target`         | object                |                                | What one occurrence asks for: a tick, a quantity in a unit, or minutes.                       |
  | `habits[].target.kind`    | string                | `check`, `quantity`, `minutes` |                                                                                               |
  | `habits[].target.amount`  | integer (optional)    | 1 to 100000                    |                                                                                               |
  | `habits[].target.unit`    | string (optional)     | 1 to 40 characters             |                                                                                               |
  | `habits[].target.minutes` | integer (optional)    | 1 to 1440                      |                                                                                               |
  | `habits[].createdAt`      | number                |                                | Epoch milliseconds.                                                                           |
  | `habits[].archivedAt`     | number \| null        |                                |                                                                                               |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_habits",
      "arguments": {
        "includeArchived": true
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "- [09aee23b-1fd4-4638-818d-2c392100518a] Acme"
        }
      ],
      "structuredContent": {
        "habits": [
          {
            "id": "09aee23b-1fd4-4638-818d-2c392100518a",
            "name": "Acme",
            "startsOn": "2026-09-22",
            "rule": {
              "every": 3,
              "unit": "day"
            },
            "target": {
              "kind": "check"
            },
            "createdAt": 1790069400000,
            "archivedAt": 1790069400000
          }
        ]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers habits list --include-archived true
  ```
</CodeGroup>

## list\_rounds

**The rounds of a day.**

Returns every round already planned, engaged or closed for that day, in order. A day with nothing on it returns an empty list rather than inventing rounds: a round exists once something has been said about it.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/rounds`                                            |
| CLI       | `doers rounds list`                                                             |
| Touches   | `rounds`                                                                        |
| Operation | `listRounds`                                                                    |

### Input

| Field         | Type   | Required | Default | Allowed values | Description                  |
| ------------- | ------ | -------- | ------- | -------------- | ---------------------------- |
| `day` (query) | string | yes      |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`. |

### Output

<Accordion title="Output fields">
  | Field               | Type           | Allowed values                        | Description                                      |
  | ------------------- | -------------- | ------------------------------------- | ------------------------------------------------ |
  | `rounds`            | object\[]      |                                       |                                                  |
  | `rounds[].day`      | string         | `YYYY-MM-DD`                          | Local day key, `YYYY-MM-DD`.                     |
  | `rounds[].index`    | integer        | -9007199254740991 to 9007199254740991 | Which round of the day, counting from zero.      |
  | `rounds[].taskIds`  | string\[]      |                                       | The mini-plan, in display order.                 |
  | `rounds[].engaged`  | boolean        |                                       | A session was started, or a planned task ticked. |
  | `rounds[].closedAt` | number \| null |                                       | When it was closed. The first close wins.        |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_rounds",
      "arguments": {
        "day": "2026-09-22"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "- round 0: 1 task(s), engaged, closed"
        }
      ],
      "structuredContent": {
        "rounds": [
          {
            "day": "2026-09-22",
            "index": 0,
            "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
            "engaged": true,
            "closedAt": 1790069400000
          }
        ]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers rounds list 2026-09-22
  ```
</CodeGroup>

## list\_today\_sessions

**List the day's sessions.**

Sessions started at or after `since`, newest first. `since` is the start of the day in the caller's timezone, which only the caller knows: the server does not guess it. At most 100 are returned.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/sessions`                                          |
| CLI       | `doers sessions list-today`                                                     |
| Touches   | `workSessions`                                                                  |
| Operation | `listTodaySessions`                                                             |

### Input

| Field           | Type   | Required | Default | Allowed values | Description         |
| --------------- | ------ | -------- | ------- | -------------- | ------------------- |
| `since` (query) | number | yes      |         |                | Epoch milliseconds. |

### Output

<Accordion title="Output fields">
  | Field                   | Type           | Allowed values                    | Description                                                                       |
  | ----------------------- | -------------- | --------------------------------- | --------------------------------------------------------------------------------- |
  | `sessions`              | object\[]      |                                   |                                                                                   |
  | `sessions[].id`         | string         |                                   |                                                                                   |
  | `sessions[].taskId`     | string \| null |                                   |                                                                                   |
  | `sessions[].title`      | string         |                                   |                                                                                   |
  | `sessions[].startedAt`  | number         |                                   | Epoch milliseconds.                                                               |
  | `sessions[].endedAt`    | number \| null |                                   | `null` while the session is still running.                                        |
  | `sessions[].visibility` | string         | `public`, `anonymized`, `private` | What the activity feed may show of it. Private until shared at the session's end. |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_today_sessions",
      "arguments": {
        "since": 3
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "- [3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb] Prepare the Acme quarterly review"
        }
      ],
      "structuredContent": {
        "sessions": [
          {
            "id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
            "taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
            "title": "Prepare the Acme quarterly review",
            "startedAt": 1790069400000,
            "endedAt": 1790069400000,
            "visibility": "public"
          }
        ]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers sessions list-today --since 3
  ```
</CodeGroup>

## suggest\_day\_plan

**Propose a plan for the day.**

Computes a proposed plan from the prioritisation engine and splits the day into rounds. **Writes nothing**: it is a draft to put to the user, then commit with `PUT /v2/plan`.

Each round gets at most 3 tasks, the heaviest first.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/plan/suggestion`                                   |
| CLI       | `doers plan suggest`                                                            |
| Touches   | `coachPlanTasks`, `coachPlans`, `roundTasks`, `rounds`, `tasks`                 |
| Operation | `suggestDayPlan`                                                                |

### Input

| Field               | Type    | Required | Default   | Allowed values | Description                                     |
| ------------------- | ------- | -------- | --------- | -------------- | ----------------------------------------------- |
| `day` (query)       | string  | no       |           | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`.                    |
| `workStart` (query) | string  | no       | `"09:00"` | `HH:MM`        | Time `HH:MM`: only meaningful alongside a date. |
| `workEnd` (query)   | string  | no       | `"18:00"` | `HH:MM`        | Time `HH:MM`: only meaningful alongside a date. |
| `roundMin` (query)  | integer | no       | `120`     | 30 to 240      | *No description in the registry.*               |
| `maxTasks` (query)  | integer | no       | `5`       | 1 to 6         | *No description in the registry.*               |

### Output

<Accordion title="Output fields">
  | Field                   | Type                 | Allowed values                        | Description |
  | ----------------------- | -------------------- | ------------------------------------- | ----------- |
  | `day`                   | string               |                                       |             |
  | `suggestion`            | object\[]            |                                       |             |
  | `suggestion[].id`       | string               |                                       |             |
  | `suggestion[].title`    | string               |                                       |             |
  | `suggestion[].priority` | integer              | -9007199254740991 to 9007199254740991 |             |
  | `suggestion[].score`    | number (optional)    |                                       |             |
  | `suggestion[].reasons`  | string\[] (optional) |                                       |             |
  | `focusTaskId`           | string \| null       |                                       |             |
  | `rounds`                | object\[]            |                                       |             |
  | `rounds[].index`        | integer              | -9007199254740991 to 9007199254740991 |             |
  | `rounds[].label`        | string               |                                       |             |
  | `rounds[].taskIds`      | string\[]            |                                       |             |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "suggest_day_plan",
      "arguments": {
        "day": "2026-09-22",
        "workStart": "09:00"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "Proposal for 2026-09-22:\n- [650ffa82-126b-44c5-83df-581cbc078399] Prepare the Acme quarterly review"
        }
      ],
      "structuredContent": {
        "day": "2026-09-22",
        "suggestion": [
          {
            "id": "650ffa82-126b-44c5-83df-581cbc078399",
            "title": "Prepare the Acme quarterly review",
            "priority": 2,
            "score": 3,
            "reasons": ["Notes for the Acme launch."]
          }
        ],
        "focusTaskId": "330571bf-d351-4dd2-8723-26c22871d591",
        "rounds": [
          {
            "index": 0,
            "label": "Acme",
            "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"]
          }
        ]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers plan suggest --day 2026-09-22 --work-start 09:00
  ```
</CodeGroup>

## archive\_habit

**Archive a habit.**

Takes it out of the list and out of what is due. Its completions stay, so what was done can still be counted. Archiving twice is a no-op.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · destructive · no outside service                                        |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/habits/{habitId}/archive`                         |
| CLI       | `doers habits archive`                                                          |
| Touches   | `habitCompletions`, `habits`                                                    |
| Operation | `archiveHabit`                                                                  |

### Input

| Field            | Type   | Required | Default | Allowed values | Description                       |
| ---------------- | ------ | -------- | ------- | -------------- | --------------------------------- |
| `habitId` (path) | string | yes      |         |                | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field                  | Type                  | Allowed values                 | Description                                                                                   |
  | ---------------------- | --------------------- | ------------------------------ | --------------------------------------------------------------------------------------------- |
  | `habit`                | object                |                                |                                                                                               |
  | `habit.id`             | string                |                                |                                                                                               |
  | `habit.name`           | string                |                                |                                                                                               |
  | `habit.startsOn`       | string                | `YYYY-MM-DD`                   | The anchor every occurrence is expanded from.                                                 |
  | `habit.rule`           | object                |                                | A habit's rule: the task's repeat grammar without a mode, phased on `startsOn`.               |
  | `habit.rule.every`     | integer               | 1 to 365                       | The multiplier: 2 × week.                                                                     |
  | `habit.rule.unit`      | string                | `day`, `week`, `month`, `year` |                                                                                               |
  | `habit.rule.weekdays`  | integer\[] (optional) | at most 7 items, each: 1 to 7  | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit "week". |
  | `habit.target`         | object                |                                | What one occurrence asks for: a tick, a quantity in a unit, or minutes.                       |
  | `habit.target.kind`    | string                | `check`, `quantity`, `minutes` |                                                                                               |
  | `habit.target.amount`  | integer (optional)    | 1 to 100000                    |                                                                                               |
  | `habit.target.unit`    | string (optional)     | 1 to 40 characters             |                                                                                               |
  | `habit.target.minutes` | integer (optional)    | 1 to 1440                      |                                                                                               |
  | `habit.createdAt`      | number                |                                | Epoch milliseconds.                                                                           |
  | `habit.archivedAt`     | number \| null        |                                |                                                                                               |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "archive_habit",
      "arguments": {
        "habitId": "09aee23b-1fd4-4638-818d-2c392100518a"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: habit archived [09aee23b-1fd4-4638-818d-2c392100518a]"
        }
      ],
      "structuredContent": {
        "habit": {
          "id": "09aee23b-1fd4-4638-818d-2c392100518a",
          "name": "Acme",
          "startsOn": "2026-09-22",
          "rule": {
            "every": 3,
            "unit": "day"
          },
          "target": {
            "kind": "check"
          },
          "createdAt": 1790069400000,
          "archivedAt": 1790069400000
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers habits archive --habit-id 09aee23b-1fd4-4638-818d-2c392100518a
  ```
</CodeGroup>

## close\_round

**Close a round.**

Marks the round finished, stamping the moment. **The first close wins**: calling it again leaves the original timestamp alone, because when the work stopped is the fact worth keeping.

A round that was never planned or engaged has nothing to close and answers 404.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/rounds/{day}/{index}/close`                       |
| CLI       | `doers rounds close`                                                            |
| Touches   | `rounds`                                                                        |
| Operation | `closeRound`                                                                    |

### Input

| Field          | Type    | Required | Default | Allowed values | Description                                 |
| -------------- | ------- | -------- | ------- | -------------- | ------------------------------------------- |
| `day` (path)   | string  | yes      |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`.                |
| `index` (path) | integer | yes      |         | 0 to 5         | Which round of the day, counting from zero. |

### Output

<Accordion title="Output fields">
  | Field            | Type           | Allowed values                        | Description                                      |
  | ---------------- | -------------- | ------------------------------------- | ------------------------------------------------ |
  | `round`          | object         |                                       |                                                  |
  | `round.day`      | string         | `YYYY-MM-DD`                          | Local day key, `YYYY-MM-DD`.                     |
  | `round.index`    | integer        | -9007199254740991 to 9007199254740991 | Which round of the day, counting from zero.      |
  | `round.taskIds`  | string\[]      |                                       | The mini-plan, in display order.                 |
  | `round.engaged`  | boolean        |                                       | A session was started, or a planned task ticked. |
  | `round.closedAt` | number \| null |                                       | When it was closed. The first close wins.        |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "close_round",
      "arguments": {
        "day": "2026-09-22",
        "index": 0
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: round 0 closed."
        }
      ],
      "structuredContent": {
        "round": {
          "day": "2026-09-22",
          "index": 0,
          "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
          "engaged": true,
          "closedAt": 1790069400000
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers rounds close 2026-09-22 0
  ```
</CodeGroup>

## complete\_habit

**Complete a habit for a day.**

Records the occurrence, with what was done for a measured target. Doing it again for the same day updates the one record rather than adding a second. Refused on a day the habit is not due, and on an archived habit.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `PUT https://api.doers.sh/v2/habits/{habitId}/completions/{day}`                |
| CLI       | `doers habits complete`                                                         |
| Touches   | `habitCompletions`, `habits`                                                    |
| Operation | `completeHabit`                                                                 |

### Input

| Field            | Type    | Required | Default | Allowed values | Description                       |
| ---------------- | ------- | -------- | ------- | -------------- | --------------------------------- |
| `habitId` (path) | string  | yes      |         |                | *No description in the registry.* |
| `day` (path)     | string  | yes      |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`.      |
| `amount`         | integer | no       |         | 0 to 100000    | *No description in the registry.* |
| `minutes`        | integer | no       |         | 0 to 1440      | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field                    | Type            | Allowed values        | Description                           |
  | ------------------------ | --------------- | --------------------- | ------------------------------------- |
  | `completion`             | object          |                       |                                       |
  | `completion.id`          | string          |                       |                                       |
  | `completion.habitId`     | string          |                       |                                       |
  | `completion.day`         | string          | `YYYY-MM-DD`          | Local day key, `YYYY-MM-DD`.          |
  | `completion.amount`      | integer \| null | 0 to 9007199254740991 | What was done, for a quantity target. |
  | `completion.minutes`     | integer \| null | 0 to 9007199254740991 | What was done, for a minutes target.  |
  | `completion.completedAt` | number          |                       | Epoch milliseconds.                   |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "complete_habit",
      "arguments": {
        "habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
        "day": "2026-09-22",
        "amount": 3,
        "minutes": 30
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: done for 2026-09-22"
        }
      ],
      "structuredContent": {
        "completion": {
          "id": "21606b58-37ee-4917-8e56-cff2afe21083",
          "habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
          "day": "2026-09-22",
          "amount": 3,
          "minutes": 30,
          "completedAt": 1790069400000
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers habits complete --habit-id 09aee23b-1fd4-4638-818d-2c392100518a --day 2026-09-22 --amount 3 --minutes 30
  ```
</CodeGroup>

## create\_habit

**Create a habit.**

A name, the day it starts, a rule, and a target. The rule is the task's repeat grammar without a mode: a habit is always phased on the day it starts.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · no outside service                                                      |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/habits`                                           |
| CLI       | `doers habits create`                                                           |
| Touches   | `habitCompletions`, `habits`                                                    |
| Operation | `createHabit`                                                                   |

### Input

| Field            | Type       | Required | Default | Allowed values                 | Description                                                                                   |
| ---------------- | ---------- | -------- | ------- | ------------------------------ | --------------------------------------------------------------------------------------------- |
| `name`           | string     | yes      |         | 1 to 200 characters            | *No description in the registry.*                                                             |
| `startsOn`       | string     | yes      |         | `YYYY-MM-DD`                   | Local day key, `YYYY-MM-DD`.                                                                  |
| `rule`           | object     | yes      |         |                                | A habit's rule: the task's repeat grammar without a mode, phased on `startsOn`.               |
| `rule.every`     | integer    | yes      |         | 1 to 365                       | The multiplier: 2 × week.                                                                     |
| `rule.unit`      | string     | yes      |         | `day`, `week`, `month`, `year` | *No description in the registry.*                                                             |
| `rule.weekdays`  | integer\[] | no       |         | at most 7 items, each: 1 to 7  | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit "week". |
| `target`         | object     | yes      |         |                                | What one occurrence asks for: a tick, a quantity in a unit, or minutes.                       |
| `target.kind`    | string     | yes      |         | `check`, `quantity`, `minutes` | *No description in the registry.*                                                             |
| `target.amount`  | integer    | no       |         | 1 to 100000                    | *No description in the registry.*                                                             |
| `target.unit`    | string     | no       |         | 1 to 40 characters             | *No description in the registry.*                                                             |
| `target.minutes` | integer    | no       |         | 1 to 1440                      | *No description in the registry.*                                                             |

### Output

<Accordion title="Output fields">
  | Field                  | Type                  | Allowed values                 | Description                                                                                   |
  | ---------------------- | --------------------- | ------------------------------ | --------------------------------------------------------------------------------------------- |
  | `habit`                | object                |                                |                                                                                               |
  | `habit.id`             | string                |                                |                                                                                               |
  | `habit.name`           | string                |                                |                                                                                               |
  | `habit.startsOn`       | string                | `YYYY-MM-DD`                   | The anchor every occurrence is expanded from.                                                 |
  | `habit.rule`           | object                |                                | A habit's rule: the task's repeat grammar without a mode, phased on `startsOn`.               |
  | `habit.rule.every`     | integer               | 1 to 365                       | The multiplier: 2 × week.                                                                     |
  | `habit.rule.unit`      | string                | `day`, `week`, `month`, `year` |                                                                                               |
  | `habit.rule.weekdays`  | integer\[] (optional) | at most 7 items, each: 1 to 7  | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit "week". |
  | `habit.target`         | object                |                                | What one occurrence asks for: a tick, a quantity in a unit, or minutes.                       |
  | `habit.target.kind`    | string                | `check`, `quantity`, `minutes` |                                                                                               |
  | `habit.target.amount`  | integer (optional)    | 1 to 100000                    |                                                                                               |
  | `habit.target.unit`    | string (optional)     | 1 to 40 characters             |                                                                                               |
  | `habit.target.minutes` | integer (optional)    | 1 to 1440                      |                                                                                               |
  | `habit.createdAt`      | number                |                                | Epoch milliseconds.                                                                           |
  | `habit.archivedAt`     | number \| null        |                                |                                                                                               |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "create_habit",
      "arguments": {
        "name": "Acme",
        "startsOn": "2026-09-22",
        "rule": {
          "every": 3,
          "unit": "day"
        },
        "target": {
          "kind": "check"
        }
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: habit created [09aee23b-1fd4-4638-818d-2c392100518a] Acme"
        }
      ],
      "structuredContent": {
        "habit": {
          "id": "09aee23b-1fd4-4638-818d-2c392100518a",
          "name": "Acme",
          "startsOn": "2026-09-22",
          "rule": {
            "every": 3,
            "unit": "day"
          },
          "target": {
            "kind": "check"
          },
          "createdAt": 1790069400000,
          "archivedAt": 1790069400000
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers habits create Acme --starts-on 2026-09-22
  # rule, target: structured argument(s) the CLI cannot pass as flags.
  ```
</CodeGroup>

## mark\_round\_engaged

**Record that a round was actually worked.**

Engaged means a session was started or a planned task ticked during the round: the difference between a day that was planned and a day that happened.

Idempotent, and it creates the round if nothing was planned for it: working an unplanned block still counts.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/rounds/{day}/{index}/engage`                      |
| CLI       | `doers rounds engage`                                                           |
| Touches   | `rounds`                                                                        |
| Operation | `markRoundEngaged`                                                              |

### Input

| Field          | Type    | Required | Default | Allowed values | Description                                 |
| -------------- | ------- | -------- | ------- | -------------- | ------------------------------------------- |
| `day` (path)   | string  | yes      |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`.                |
| `index` (path) | integer | yes      |         | 0 to 5         | Which round of the day, counting from zero. |

### Output

<Accordion title="Output fields">
  | Field            | Type           | Allowed values                        | Description                                      |
  | ---------------- | -------------- | ------------------------------------- | ------------------------------------------------ |
  | `round`          | object         |                                       |                                                  |
  | `round.day`      | string         | `YYYY-MM-DD`                          | Local day key, `YYYY-MM-DD`.                     |
  | `round.index`    | integer        | -9007199254740991 to 9007199254740991 | Which round of the day, counting from zero.      |
  | `round.taskIds`  | string\[]      |                                       | The mini-plan, in display order.                 |
  | `round.engaged`  | boolean        |                                       | A session was started, or a planned task ticked. |
  | `round.closedAt` | number \| null |                                       | When it was closed. The first close wins.        |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "mark_round_engaged",
      "arguments": {
        "day": "2026-09-22",
        "index": 0
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: round 0 engaged."
        }
      ],
      "structuredContent": {
        "round": {
          "day": "2026-09-22",
          "index": 0,
          "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
          "engaged": true,
          "closedAt": 1790069400000
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers rounds engage 2026-09-22 0
  ```
</CodeGroup>

## plan\_round

**Fill an ADHD-mode round.**

Replaces a round's mini-plan: 3 tasks maximum, the heaviest first. A task lives in one round only: it is removed from the day's other rounds.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `PUT https://api.doers.sh/v2/plan/rounds/{index}`                               |
| CLI       | `doers plan round`                                                              |
| Touches   | `coachPlanTasks`, `coachPlans`, `roundTasks`, `rounds`, `tasks`                 |
| Operation | `planRound`                                                                     |

### Input

| Field          | Type      | Required | Default | Allowed values              | Description                       |
| -------------- | --------- | -------- | ------- | --------------------------- | --------------------------------- |
| `index` (path) | integer   | yes      |         | 0 to 5                      | *No description in the registry.* |
| `taskIds`      | string\[] | yes      |         | at most 3 items, each: UUID | Identifier of a row.              |
| `day`          | string    | no       |         | `YYYY-MM-DD`                | Local day key, `YYYY-MM-DD`.      |

### Output

<Accordion title="Output fields">
  | Field     | Type      | Allowed values                        | Description |
  | --------- | --------- | ------------------------------------- | ----------- |
  | `day`     | string    |                                       |             |
  | `index`   | integer   | -9007199254740991 to 9007199254740991 |             |
  | `taskIds` | string\[] |                                       |             |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "plan_round",
      "arguments": {
        "index": 0,
        "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
        "day": "2026-09-22"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: round 1 planned (1 task(s))."
        }
      ],
      "structuredContent": {
        "day": "2026-09-22",
        "index": 0,
        "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers plan round 0 --task-ids 0ebb429f-a86d-481c-8630-fac53db1c91c --day 2026-09-22
  ```
</CodeGroup>

## plan\_today

**Save the day's plan.**

Replaces the day's plan. `focusTaskId` names THE priority: if it is not in `taskIds`, the first task is used instead. The note is a short encouragement shown at the top of Today.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `PUT https://api.doers.sh/v2/plan`                                              |
| CLI       | `doers plan set`                                                                |
| Touches   | `coachPlanTasks`, `coachPlans`, `roundTasks`, `rounds`, `tasks`                 |
| Operation | `planToday`                                                                     |

### Input

| Field         | Type      | Required | Default | Allowed values              | Description                       |
| ------------- | --------- | -------- | ------- | --------------------------- | --------------------------------- |
| `taskIds`     | string\[] | yes      |         | at most 6 items, each: UUID | Identifier of a row.              |
| `focusTaskId` | string    | no       |         | UUID                        | Identifier of a row.              |
| `note`        | string    | no       | `""`    | 0 to 300 characters         | *No description in the registry.* |
| `day`         | string    | no       |         | `YYYY-MM-DD`                | Local day key, `YYYY-MM-DD`.      |

### Output

<Accordion title="Output fields">
  | Field         | Type           | Allowed values | Description |
  | ------------- | -------------- | -------------- | ----------- |
  | `day`         | string         |                |             |
  | `taskIds`     | string\[]      |                |             |
  | `focusTaskId` | string \| null |                |             |
  | `note`        | string         |                |             |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "plan_today",
      "arguments": {
        "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
        "focusTaskId": "330571bf-d351-4dd2-8723-26c22871d591",
        "note": ""
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: plan for 2026-09-22 saved (1 task(s))."
        }
      ],
      "structuredContent": {
        "day": "2026-09-22",
        "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
        "focusTaskId": "330571bf-d351-4dd2-8723-26c22871d591",
        "note": "Notes for the Acme launch."
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers plan set --task-ids 0ebb429f-a86d-481c-8630-fac53db1c91c --focus-task-id 330571bf-d351-4dd2-8723-26c22871d591 --note ""
  ```
</CodeGroup>

## set\_round\_plan

**Plan a round.**

Replaces the round's mini-plan. At most 3 tasks: one substantial and two small is the shape it was built for; a longer list is not a plan.

**A task belongs to one round of the day.** Planning it here removes it from any other round of the same day, so it cannot appear twice.

An empty list clears the plan. The round itself is created if it does not exist yet. When movedTaskIds and both interval bounds are supplied, those tasks are also softly scheduled onto the target day without changing deadlines or completion state.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `PUT https://api.doers.sh/v2/rounds/{day}/{index}/plan`                         |
| CLI       | `doers rounds plan`                                                             |
| Touches   | `roundTasks`, `rounds`, `tasks`                                                 |
| Operation | `setRoundPlan`                                                                  |

### Input

| Field           | Type      | Required | Default | Allowed values              | Description                                                              |
| --------------- | --------- | -------- | ------- | --------------------------- | ------------------------------------------------------------------------ |
| `day` (path)    | string    | yes      |         | `YYYY-MM-DD`                | Local day key, `YYYY-MM-DD`.                                             |
| `index` (path)  | integer   | yes      |         | 0 to 5                      | Which round of the day, counting from zero.                              |
| `taskIds`       | string\[] | yes      |         | at most 3 items, each: UUID | In display order. Pass an empty array to clear the plan.                 |
| `movedTaskIds`  | string\[] | no       |         | at most 3 items, each: UUID | The subset moved by this request and softly scheduled into the interval. |
| `roundStartMin` | integer   | no       |         | 0 to 1439                   | Inclusive target interval start, in minutes after midnight.              |
| `roundEndMin`   | integer   | no       |         | 1 to 1440                   | Exclusive target interval end, in minutes after midnight.                |

### Output

<Accordion title="Output fields">
  | Field                    | Type           | Allowed values                        | Description                                      |
  | ------------------------ | -------------- | ------------------------------------- | ------------------------------------------------ |
  | `round`                  | object         |                                       |                                                  |
  | `round.day`              | string         | `YYYY-MM-DD`                          | Local day key, `YYYY-MM-DD`.                     |
  | `round.index`            | integer        | -9007199254740991 to 9007199254740991 | Which round of the day, counting from zero.      |
  | `round.taskIds`          | string\[]      |                                       | The mini-plan, in display order.                 |
  | `round.engaged`          | boolean        |                                       | A session was started, or a planned task ticked. |
  | `round.closedAt`         | number \| null |                                       | When it was closed. The first close wins.        |
  | `removedFromOtherRounds` | integer        | -9007199254740991 to 9007199254740991 |                                                  |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "set_round_plan",
      "arguments": {
        "day": "2026-09-22",
        "index": 0,
        "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"]
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: round 0 planned with 1 task(s)."
        }
      ],
      "structuredContent": {
        "round": {
          "day": "2026-09-22",
          "index": 0,
          "taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
          "engaged": true,
          "closedAt": 1790069400000
        },
        "removedFromOtherRounds": 3
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers rounds plan 2026-09-22 0 --task-ids 0ebb429f-a86d-481c-8630-fac53db1c91c
  ```
</CodeGroup>

## share\_session

**Share a finished session to Activity, or take it back.**

Public shows the effort and the task's title; anonymized shows the effort and only where the task lived; private, the default, shows nothing. Only a finished session of your own; a running one is refused.

|           |                                                                                  |
| --------- | -------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`)  |
| REST      | `PUT https://api.doers.sh/v2/sessions/{sessionId}/visibility`                    |
| CLI       | `doers sessions share`                                                           |
| Touches   | `areas`, `follows`, `projects`, `sessionFlames`, `tasks`, `user`, `workSessions` |
| Operation | `shareSession`                                                                   |

### Input

| Field              | Type   | Required | Default | Allowed values                    | Description                                                                                                                                                            |
| ------------------ | ------ | -------- | ------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sessionId` (path) | string | yes      |         |                                   | *No description in the registry.*                                                                                                                                      |
| `visibility`       | string | yes      |         | `public`, `anonymized`, `private` | Who sees this task on shared and social surfaces: public shows title and project, anonymized shows only the area, private shows nothing. New tasks default to private. |

### Output

<Accordion title="Output fields">
  | Field                | Type           | Allowed values                    | Description                                                                       |
  | -------------------- | -------------- | --------------------------------- | --------------------------------------------------------------------------------- |
  | `session`            | object         |                                   |                                                                                   |
  | `session.id`         | string         |                                   |                                                                                   |
  | `session.taskId`     | string \| null |                                   |                                                                                   |
  | `session.title`      | string         |                                   |                                                                                   |
  | `session.startedAt`  | number         |                                   | Epoch milliseconds.                                                               |
  | `session.endedAt`    | number \| null |                                   | `null` while the session is still running.                                        |
  | `session.visibility` | string         | `public`, `anonymized`, `private` | What the activity feed may show of it. Private until shared at the session's end. |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "share_session",
      "arguments": {
        "sessionId": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
        "visibility": "public"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: session is public"
        }
      ],
      "structuredContent": {
        "session": {
          "id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
          "taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
          "title": "Prepare the Acme quarterly review",
          "startedAt": 1790069400000,
          "endedAt": 1790069400000,
          "visibility": "public"
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers sessions share --session-id 3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb --visibility public
  ```
</CodeGroup>

## start\_session

**Start a session.**

Starts the timer. Any session still running is stopped first, so this is safe to call without checking the current state.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · no outside service                                                      |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/sessions`                                         |
| CLI       | `doers sessions start`                                                          |
| Touches   | `workSessions`                                                                  |
| Operation | `startSession`                                                                  |

### Input

| Field    | Type           | Required | Default | Allowed values      | Description                       |
| -------- | -------------- | -------- | ------- | ------------------- | --------------------------------- |
| `taskId` | string \| null | no       |         | UUID                | *No description in the registry.* |
| `title`  | string         | no       |         | 0 to 500 characters | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field                | Type           | Allowed values                    | Description                                                                       |
  | -------------------- | -------------- | --------------------------------- | --------------------------------------------------------------------------------- |
  | `session`            | object         |                                   |                                                                                   |
  | `session.id`         | string         |                                   |                                                                                   |
  | `session.taskId`     | string \| null |                                   |                                                                                   |
  | `session.title`      | string         |                                   |                                                                                   |
  | `session.startedAt`  | number         |                                   | Epoch milliseconds.                                                               |
  | `session.endedAt`    | number \| null |                                   | `null` while the session is still running.                                        |
  | `session.visibility` | string         | `public`, `anonymized`, `private` | What the activity feed may show of it. Private until shared at the session's end. |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "start_session",
      "arguments": {
        "taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
        "title": "Prepare the Acme quarterly review"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: session “Prepare the Acme quarterly review” started [3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb]."
        }
      ],
      "structuredContent": {
        "session": {
          "id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
          "taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
          "title": "Prepare the Acme quarterly review",
          "startedAt": 1790069400000,
          "endedAt": 1790069400000,
          "visibility": "public"
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers sessions start --task-id 0ebb429f-a86d-481c-8630-fac53db1c91c --title "Prepare the Acme quarterly review"
  ```
</CodeGroup>

## stop\_session

**Stop the running session.**

Stops the timer and returns the session it closed. Returns `null` when nothing was running: stopping a stopped timer is not an error.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/sessions/stop`                                    |
| CLI       | `doers sessions stop`                                                           |
| Touches   | `workSessions`                                                                  |
| Operation | `stopSession`                                                                   |

### Input

This tool takes no arguments.

### Output

<Accordion title="Output fields">
  | Field                | Type           | Allowed values                    | Description                                                                       |
  | -------------------- | -------------- | --------------------------------- | --------------------------------------------------------------------------------- |
  | `session`            | object \| null |                                   |                                                                                   |
  | `session.id`         | string         |                                   |                                                                                   |
  | `session.taskId`     | string \| null |                                   |                                                                                   |
  | `session.title`      | string         |                                   |                                                                                   |
  | `session.startedAt`  | number         |                                   | Epoch milliseconds.                                                               |
  | `session.endedAt`    | number \| null |                                   | `null` while the session is still running.                                        |
  | `session.visibility` | string         | `public`, `anonymized`, `private` | What the activity feed may show of it. Private until shared at the session's end. |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "stop_session",
      "arguments": {}
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: session “Prepare the Acme quarterly review” stopped."
        }
      ],
      "structuredContent": {
        "session": {
          "id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
          "taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
          "title": "Prepare the Acme quarterly review",
          "startedAt": 1790069400000,
          "endedAt": 1790069400000,
          "visibility": "public"
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers sessions stop
  ```
</CodeGroup>

## uncomplete\_habit

**Undo a day's completion.**

Removes the occurrence's record. Not found when there was none.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · destructive · idempotent · no outside service                           |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `DELETE https://api.doers.sh/v2/habits/{habitId}/completions/{day}`             |
| CLI       | `doers habits uncomplete`                                                       |
| Touches   | `habitCompletions`, `habits`                                                    |
| Operation | `uncompleteHabit`                                                               |

### Input

| Field            | Type   | Required | Default | Allowed values | Description                       |
| ---------------- | ------ | -------- | ------- | -------------- | --------------------------------- |
| `habitId` (path) | string | yes      |         |                | *No description in the registry.* |
| `day` (path)     | string | yes      |         | `YYYY-MM-DD`   | Local day key, `YYYY-MM-DD`.      |

### Output

<Accordion title="Output fields">
  | Field | Type    | Allowed values | Description |
  | ----- | ------- | -------------- | ----------- |
  | `ok`  | boolean | `true`         |             |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "uncomplete_habit",
      "arguments": {
        "habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
        "day": "2026-09-22"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: completion removed"
        }
      ],
      "structuredContent": {
        "ok": true
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers habits uncomplete --habit-id 09aee23b-1fd4-4638-818d-2c392100518a --day 2026-09-22
  ```
</CodeGroup>

## update\_habit

**Update a habit.**

Any of the name, the start day, the rule or the target. History is untouched.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `PATCH https://api.doers.sh/v2/habits/{habitId}`                                |
| CLI       | `doers habits update`                                                           |
| Touches   | `habitCompletions`, `habits`                                                    |
| Operation | `updateHabit`                                                                   |

### Input

| Field            | Type       | Required | Default | Allowed values                 | Description                                                                                   |
| ---------------- | ---------- | -------- | ------- | ------------------------------ | --------------------------------------------------------------------------------------------- |
| `habitId` (path) | string     | yes      |         |                                | *No description in the registry.*                                                             |
| `name`           | string     | no       |         | 1 to 200 characters            | *No description in the registry.*                                                             |
| `startsOn`       | string     | no       |         | `YYYY-MM-DD`                   | Local day key, `YYYY-MM-DD`.                                                                  |
| `rule`           | object     | no       |         |                                | A habit's rule: the task's repeat grammar without a mode, phased on `startsOn`.               |
| `rule.every`     | integer    | yes      |         | 1 to 365                       | The multiplier: 2 × week.                                                                     |
| `rule.unit`      | string     | yes      |         | `day`, `week`, `month`, `year` | *No description in the registry.*                                                             |
| `rule.weekdays`  | integer\[] | no       |         | at most 7 items, each: 1 to 7  | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit "week". |
| `target`         | object     | no       |         |                                | What one occurrence asks for: a tick, a quantity in a unit, or minutes.                       |
| `target.kind`    | string     | yes      |         | `check`, `quantity`, `minutes` | *No description in the registry.*                                                             |
| `target.amount`  | integer    | no       |         | 1 to 100000                    | *No description in the registry.*                                                             |
| `target.unit`    | string     | no       |         | 1 to 40 characters             | *No description in the registry.*                                                             |
| `target.minutes` | integer    | no       |         | 1 to 1440                      | *No description in the registry.*                                                             |

### Output

<Accordion title="Output fields">
  | Field                  | Type                  | Allowed values                 | Description                                                                                   |
  | ---------------------- | --------------------- | ------------------------------ | --------------------------------------------------------------------------------------------- |
  | `habit`                | object                |                                |                                                                                               |
  | `habit.id`             | string                |                                |                                                                                               |
  | `habit.name`           | string                |                                |                                                                                               |
  | `habit.startsOn`       | string                | `YYYY-MM-DD`                   | The anchor every occurrence is expanded from.                                                 |
  | `habit.rule`           | object                |                                | A habit's rule: the task's repeat grammar without a mode, phased on `startsOn`.               |
  | `habit.rule.every`     | integer               | 1 to 365                       | The multiplier: 2 × week.                                                                     |
  | `habit.rule.unit`      | string                | `day`, `week`, `month`, `year` |                                                                                               |
  | `habit.rule.weekdays`  | integer\[] (optional) | at most 7 items, each: 1 to 7  | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit "week". |
  | `habit.target`         | object                |                                | What one occurrence asks for: a tick, a quantity in a unit, or minutes.                       |
  | `habit.target.kind`    | string                | `check`, `quantity`, `minutes` |                                                                                               |
  | `habit.target.amount`  | integer (optional)    | 1 to 100000                    |                                                                                               |
  | `habit.target.unit`    | string (optional)     | 1 to 40 characters             |                                                                                               |
  | `habit.target.minutes` | integer (optional)    | 1 to 1440                      |                                                                                               |
  | `habit.createdAt`      | number                |                                | Epoch milliseconds.                                                                           |
  | `habit.archivedAt`     | number \| null        |                                |                                                                                               |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "update_habit",
      "arguments": {
        "habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
        "name": "Acme",
        "startsOn": "2026-09-22"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: habit updated [09aee23b-1fd4-4638-818d-2c392100518a] Acme"
        }
      ],
      "structuredContent": {
        "habit": {
          "id": "09aee23b-1fd4-4638-818d-2c392100518a",
          "name": "Acme",
          "startsOn": "2026-09-22",
          "rule": {
            "every": 3,
            "unit": "day"
          },
          "target": {
            "kind": "check"
          },
          "createdAt": 1790069400000,
          "archivedAt": 1790069400000
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers habits update --habit-id 09aee23b-1fd4-4638-818d-2c392100518a --name Acme --starts-on 2026-09-22
  ```
</CodeGroup>

## upsert\_journal\_entry

**Write the day's mood and note.**

Creates the day's entry or patches it. An omitted field is left alone; an explicit `null` mood clears the rating, which is how the app toggles a face off.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `PUT https://api.doers.sh/v2/journal/{day}`                                     |
| CLI       | `doers journal upsert-journal-entry`                                            |
| Touches   | `journalEntries`                                                                |
| Operation | `upsertJournalEntry`                                                            |

### Input

| Field        | Type            | Required | Default | Allowed values        | Description                       |
| ------------ | --------------- | -------- | ------- | --------------------- | --------------------------------- |
| `day` (path) | string          | yes      |         | `YYYY-MM-DD`          | Local day key, `YYYY-MM-DD`.      |
| `mood`       | integer \| null | no       |         | 1 to 5                | *No description in the registry.* |
| `note`       | string          | no       |         | 0 to 10000 characters | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field        | Type            | Allowed values                        | Description                                        |
  | ------------ | --------------- | ------------------------------------- | -------------------------------------------------- |
  | `entry`      | object          |                                       |                                                    |
  | `entry.day`  | string          | `YYYY-MM-DD`                          | Local day key, `YYYY-MM-DD`.                       |
  | `entry.mood` | integer \| null | -9007199254740991 to 9007199254740991 | 1 worst: 5 best, or `null` for a day left unrated. |
  | `entry.note` | string          |                                       |                                                    |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "upsert_journal_entry",
      "arguments": {
        "day": "2026-09-22",
        "mood": 3,
        "note": "Notes for the Acme launch."
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: journal entry for 2026-09-22 saved."
        }
      ],
      "structuredContent": {
        "entry": {
          "day": "2026-09-22",
          "mood": 3,
          "note": "Notes for the Acme launch."
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers journal upsert-journal-entry 2026-09-22 --mood 3 --note "Notes for the Acme launch."
  ```
</CodeGroup>
