<!-- Generated by `just docs` from catalog/toolkits/todoist.yaml, catalog/expansions/todoist.yaml, catalog/evals/scorecard.json. Edit the source, not this file. -->

# Todoist

Task lists. Create and organize tasks across projects and sections, set due dates and priorities, label them, and comment.

| Property | Value |
| --- | --- |
| Slug | `todoist` |
| Definition version | `0.1.0` |
| Base URL | `https://api.todoist.com/rest/v2` |
| Auth schemes | `oauth2`, `api_key` |
| Action tools | 29 |
| By class | 12 read, 12 write, 5 destructive |
| Triggers | 0 |
| Provider rate limit | not declared, so outbound calls are unpaced |

## Measured routing accuracy

52 golden cases replayed through the router over the whole index: measured over corpus `ea4f12ad2948` (65 toolkits, 2283 tools indexed and 13 declared uncallable), 29 cases written by hand and 23 cases from the paraphrase pass. A case counts as top-1 when its gold tool ranked first and top-8 when it reached the slate at all.

| Measure | Cases | Share |
| --- | --- | --- |
| top-1 | 7/52 | 13.5% |
| top-8 | 30/52 | 57.7% |

The sweep is offline: the reranker is a deterministic identity fake that returns candidates in the order retrieval produced them, so top-1 measures retrieval order rather than a reranked slate. `just eval-live` measures the same cases through the live reranker.

## Authentication

Connect an entity with `ConnectionsService.InitiateConnection`, naming this toolkit's slug. Credentials stay in the connections vault; callers hold connected-account ids only.

### `oauth2`

| Property | Value |
| --- | --- |
| Authorization URL | `https://todoist.com/oauth/authorize` |
| Token URL | `https://todoist.com/oauth/access_token` |
| Default scopes | `data:read_write` |
| Refresh tokens | no, so the end user reauthorizes when the token expires |

### `api_key`

| Property | Value |
| --- | --- |
| Placement | `header` |
| Name | `Authorization` |
| Rendered as | `Bearer {key}` |

Submit the key with `ConnectionsService` rather than putting it in a request; it is sealed at rest and never returned.

## Tools

29 action tools. The catalog-wide slug is `todoist.<tool>`, which is what `search_tools` returns and `call_tool` takes.

### `todoist.list_projects`

List every project in the caller's Todoist account, including the Inbox. Use when the user asks what projects, lists, or boards exist. For one project's own detail, use get_project.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /projects`.

Takes no arguments.

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `projects` | array of object |  |
| `projects[].color` | string |  |
| `projects[].id` | string |  |
| `projects[].is_favorite` | boolean |  |
| `projects[].is_inbox_project` | boolean |  |
| `projects[].name` | string |  |
| `projects[].url` | string |  |

Also retrieved by: "what to-do lists do I have in todoist", "show all my todoist projects", "what lists exist in my account", "browse my todoist boards".

### `todoist.get_project`

Get one Todoist project's details by id: name, color, and whether it's the Inbox or a favorite. Use for a specific known to-do list. To browse all of them, use list_projects; for who has access, use list_project_collaborators.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /projects/{{params.project_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `project_id` | string | **yes** | Todoist project id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `color` | string |  |
| `id` | string |  |
| `is_favorite` | boolean |  |
| `is_inbox_project` | boolean |  |
| `is_shared` | boolean |  |
| `name` | string |  |
| `url` | string |  |

Also retrieved by: "tell me about this todoist list", "show me this to-do list's details", "what's in this project on todoist".

### `todoist.create_project`

Create a new project (a list or board) to organize tasks under. Use when the user wants to start, add, or set up a new project distinct from a single task. Name is required; color, favorite status, and whether it nests under a parent project are optional.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /projects`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `color` | string | no | Optional Todoist color name, e.g. "charcoal", "berry_red". |
| `is_favorite` | boolean | no | Optional, pin the project to favorites. |
| `name` | string | **yes** | Project name. |
| `parent_id` | string | no | Optional id of a parent project to nest this one under. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `color` | string |  |
| `id` | string |  |
| `is_favorite` | boolean |  |
| `name` | string |  |
| `url` | string |  |

Also retrieved by: "start a new to-do list", "set up a new todoist project", "make a new list for this", "begin tracking a new todoist initiative".

### `todoist.update_project`

Rename a Todoist project, change its color, or toggle its favorite status. Use when the user wants to edit an existing to-do list rather than create a new one. Only the fields given change; the rest are untouched.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /projects/{{params.project_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `color` | string | no | New Todoist color name, e.g. "charcoal", "berry_red". |
| `is_favorite` | boolean | no | New favorite status. |
| `name` | string | no | New project name. |
| `project_id` | string | **yes** | Todoist project id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `color` | string |  |
| `id` | string |  |
| `is_favorite` | boolean |  |
| `name` | string |  |

Also retrieved by: "rename this to-do list", "change the color of this todoist project", "pin this list to favorites", "edit this todoist project's name".

### `todoist.delete_project`

Permanently delete a Todoist project and every to-do, section, and comment inside it. Irreversible. Use only when the user is explicit about erasing or permanently removing a whole to-do list, not just archiving or clearing its items.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `project:delete`. Calls `DELETE /projects/{{params.project_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `project_id` | string | **yes** | Todoist project id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `deleted` | boolean |  |

Also retrieved by: "wipe out this whole todoist list", "erase this to-do list entirely", "permanently remove this project from todoist".

### `todoist.list_project_collaborators`

List the people who share a Todoist project, with name and email. Use for "who has access to this to-do list" or "who's it shared with". Only applies to shared projects; a personal one returns an empty list.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /projects/{{params.project_id}}/collaborators`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `project_id` | string | **yes** | Todoist project id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `collaborators` | array of object |  |
| `collaborators[].email` | string |  |
| `collaborators[].id` | string |  |
| `collaborators[].name` | string |  |

Also retrieved by: "who has access to this todoist list", "who's this to-do list shared with", "see everyone on this todoist project".

### `todoist.list_sections`

List the sections (sub-groupings, like columns on a board) inside a project, or across every project if none is given. Use when the user asks what sections or groups a project has. To look up a section id before filing a task, use this first.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /sections`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `project_id` | string | no | Optional project id to restrict the listing to. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `sections` | array of object |  |
| `sections[].id` | string |  |
| `sections[].name` | string |  |
| `sections[].order` | integer |  |
| `sections[].project_id` | string |  |

Also retrieved by: "what groupings does this to-do list have", "show the headings on this todoist project", "what sections exist in this list".

### `todoist.create_section`

Create a new section inside a project, to group related tasks. Use when the user wants to add a column, phase, or heading to a project's board, distinct from a whole new project.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /sections`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `name` | string | **yes** | Section name. |
| `project_id` | string | **yes** | Project id the section belongs to. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `id` | string |  |
| `name` | string |  |
| `project_id` | string |  |

Also retrieved by: "add a heading to this to-do list", "make a new grouping in this todoist project", "set up a phase for this list".

### `todoist.get_section`

Get one Todoist section's name and project by id. Use for a specific known grouping inside a to-do list. To browse all sections in a project, use list_sections.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /sections/{{params.section_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `section_id` | string | **yes** | Todoist section id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `id` | string |  |
| `name` | string |  |
| `project_id` | string |  |

Also retrieved by: "what's this grouping called", "show me this heading's details", "which todoist list does this belong to".

### `todoist.update_section`

Rename a Todoist section. Use when the user wants to relabel a grouping inside a to-do list without moving its items.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /sections/{{params.section_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `name` | string | **yes** | New section name. |
| `section_id` | string | **yes** | Todoist section id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `id` | string |  |
| `name` | string |  |

Also retrieved by: "rename this heading", "relabel this grouping", "give this part of the list a new name".

### `todoist.delete_section`

Permanently delete a Todoist section and every to-do inside it. Irreversible. Use only when the user is explicit about removing a whole grouping, not just the items in it.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `data:delete`. Calls `DELETE /sections/{{params.section_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `section_id` | string | **yes** | Todoist section id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `deleted` | boolean |  |

Also retrieved by: "remove this whole heading from the list", "erase this grouping and its to-dos", "get rid of this part of the project entirely".

### `todoist.list_tasks`

List active (not yet completed) tasks, optionally filtered to a project, section, label, or a Todoist filter query like "today" or "overdue". Use for "what's on my list", "show tasks due this week", or browsing a project's open items. For one specific known task, use get_task.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /tasks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `filter` | string | no | Optional Todoist filter query, e.g. "today", "overdue", "p1 & @work". |
| `label` | string | no | Optional label name to restrict the listing to. |
| `project_id` | string | no | Optional project id to restrict the listing to. |
| `section_id` | string | no | Optional section id to restrict the listing to. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `tasks` | array of object |  |
| `tasks[].content` | string |  |
| `tasks[].due` | object |  |
| `tasks[].due.date` | string |  |
| `tasks[].due.datetime` | string |  |
| `tasks[].due.string` | string |  |
| `tasks[].id` | string |  |
| `tasks[].is_completed` | boolean |  |
| `tasks[].labels` | array of string |  |
| `tasks[].priority` | integer |  |
| `tasks[].project_id` | string |  |
| `tasks[].section_id` | string |  |
| `tasks[].url` | string |  |

Also retrieved by: "what's on my to-do list", "show what's due this week in todoist", "what do I have to do today", "what's overdue on my list", "browse open items in this todoist project".

### `todoist.get_task`

Get one Todoist to-do's full detail by id: content, description, due date, priority, labels, and completion status. Use for a specific known item on the list. To find to-dos by project, section, label, or filter, use list_tasks.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /tasks/{{params.task_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `task_id` | string | **yes** | Todoist task id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `assignee_id` | string |  |
| `comment_count` | integer |  |
| `content` | string |  |
| `created_at` | string |  |
| `description` | string |  |
| `due` | object |  |
| `due.date` | string |  |
| `due.datetime` | string |  |
| `due.is_recurring` | boolean |  |
| `due.string` | string |  |
| `id` | string |  |
| `is_completed` | boolean |  |
| `labels` | array of string |  |
| `priority` | integer |  |
| `project_id` | string |  |
| `section_id` | string |  |
| `url` | string |  |

Also retrieved by: "pull up this to-do's details", "show me everything about this item on my list", "what's the status of this to-do".

### `todoist.create_task`

Create a new Todoist task: a to-do, reminder, or item to track. Use when the user wants to add, jot down, or schedule something to do. Content is required; project, section, due date (plain language such as tomorrow, or an ISO date), priority, and labels are all optional and default to the Inbox with no due date.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /tasks`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `assignee_id` | string | no | Optional user id to assign the task to, in a shared project. |
| `content` | string | **yes** | Task title, e.g. "Send the Q3 report". |
| `description` | string | no | Optional longer note or details, in markdown. |
| `due_date` | string (date) | no | Optional due date, ISO 8601 (YYYY-MM-DD), no time. |
| `due_string` | string | no | Optional natural-language due date/time, e.g. "tomorrow at 5pm", "every monday". Takes priority over due_date. |
| `labels` | array of string | no | Optional label names to attach on creation. |
| `priority` | integer | no | Optional priority: 1 normal, 2 medium, 3 high, 4 urgent. |
| `project_id` | string | no | Optional project id to file the task under. Defaults to Inbox. |
| `section_id` | string | no | Optional section id to file the task under. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `content` | string |  |
| `due` | object |  |
| `due.date` | string |  |
| `due.string` | string |  |
| `id` | string |  |
| `priority` | integer |  |
| `project_id` | string |  |
| `url` | string |  |

Also retrieved by: "add a to-do to todoist", "jot this down for later", "remind me to do this", "put this on my list", "schedule something to do".

### `todoist.update_task`

Edit a task's content, description, due date, priority, or labels. Use when the user wants to change, reword, reschedule, or reprioritize an existing task. Only the fields given change; the rest are untouched. This cannot move a task to a different project or section; recreate it there instead.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /tasks/{{params.task_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `content` | string | no | New task title. |
| `description` | string | no | New longer note or details, in markdown. |
| `due_date` | string (date) | no | New due date, ISO 8601 (YYYY-MM-DD), no time. |
| `due_string` | string | no | New natural-language due date/time, e.g. "next friday". Takes priority over due_date. |
| `labels` | array of string | no | New full set of label names, replacing the old set. |
| `priority` | integer | no | New priority: 1 normal, 2 medium, 3 high, 4 urgent. |
| `task_id` | string | **yes** | Todoist task id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `content` | string |  |
| `due` | object |  |
| `due.date` | string |  |
| `due.string` | string |  |
| `id` | string |  |
| `priority` | integer |  |

Also retrieved by: "change the due date on this to-do", "reword this item on my list", "reschedule this to-do", "bump the priority on this item".

### `todoist.close_task`

Mark a task as done, checking it off. Use when the user says they finished, completed, or checked off a task. A recurring task instead advances to its next occurrence rather than disappearing. To undo this, use reopen_task; to remove the task entirely, use delete_task.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /tasks/{{params.task_id}}/close`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `task_id` | string | **yes** | Todoist task id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `closed` | boolean |  |

Also retrieved by: "check this off my list", "mark this to-do as done", "I finished this one", "complete this item".

### `todoist.reopen_task`

Reopen a completed task, putting it back on the active list. Use when the user says a task was checked off by mistake or needs to be done again. To mark it done instead, use close_task.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /tasks/{{params.task_id}}/reopen`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `task_id` | string | **yes** | Todoist task id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `reopened` | boolean |  |

Also retrieved by: "undo checking this off", "put this back on my list", "I need to do this again".

### `todoist.delete_task`

Permanently delete a Todoist to-do. Irreversible: the item and its comments are gone, unlike close_task which can be undone with reopen_task. Use only when the user is explicit about erasing or removing it entirely, not just finishing it.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `data:delete`. Calls `DELETE /tasks/{{params.task_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `task_id` | string | **yes** | Todoist task id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `deleted` | boolean |  |

Also retrieved by: "erase this to-do for good", "permanently remove this item from my list", "wipe this to-do entirely".

### `todoist.list_labels`

List the caller's personal Todoist labels: the @ tags that appear on to-dos across every project, with name and color. Use to look up a label name before calling create_task, update_task, or list_tasks with a label filter, or when the user asks what labels exist.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /labels`.

Takes no arguments.

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `labels` | array of object |  |
| `labels[].color` | string |  |
| `labels[].id` | string |  |
| `labels[].is_favorite` | boolean |  |
| `labels[].name` | string |  |

Also retrieved by: "what tags do I have in todoist", "show my saved labels", "what @ tags can I use".

### `todoist.get_label`

Get one Todoist @ label's name, color, and favorite status by id. Use for a specific known tag. To browse all of them, use list_labels.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /labels/{{params.label_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `label_id` | string | **yes** | Todoist label id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `color` | string |  |
| `id` | string |  |
| `is_favorite` | boolean |  |
| `name` | string |  |

Also retrieved by: "show me this tag's details", "what color is this @ label", "is this one of my favorite tags".

### `todoist.create_label`

Create a new personal label (tag), with a name and optional color. Use when the user wants a new tag or category that does not exist yet, before attaching it to tasks.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /labels`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `color` | string | no | Optional Todoist color name, e.g. "charcoal", "berry_red". |
| `is_favorite` | boolean | no | Optional, pin the label to favorites. |
| `name` | string | **yes** | Label name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `color` | string |  |
| `id` | string |  |
| `name` | string |  |

Also retrieved by: "make a new @ tag", "add a label I can use on to-dos", "set up a new category for my list".

### `todoist.update_label`

Rename a Todoist @ label, change its color, or toggle its favorite status. Use when the user wants to edit an existing tag rather than create a new one. Every to-do already carrying this label keeps it under the new name.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /labels/{{params.label_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `color` | string | no | New Todoist color name, e.g. "charcoal", "berry_red". |
| `is_favorite` | boolean | no | New favorite status. |
| `label_id` | string | **yes** | Todoist label id. |
| `name` | string | no | New label name. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `color` | string |  |
| `id` | string |  |
| `name` | string |  |

Also retrieved by: "rename this @ tag", "change the color of this label", "pin this tag to favorites".

### `todoist.delete_label`

Permanently delete a personal label. Irreversible: the label is removed from every task that carried it. Use only when the user is explicit about erasing a tag entirely, not just removing it from one task.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `data:delete`. Calls `DELETE /labels/{{params.label_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `label_id` | string | **yes** | Todoist label id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `deleted` | boolean |  |

Also retrieved by: "erase this @ tag entirely", "permanently remove this label", "get rid of this category for good".

### `todoist.list_shared_labels`

List every label name in use across the caller's tasks, including ones used by collaborators that never became a personal label. Use for a fuller picture of tag names in play than list_labels, which shows only the caller's own saved labels.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /labels/shared`.

Takes no arguments.

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `names` | array of string |  |

Also retrieved by: "what @ tags is everyone using across my to-dos", "show every label name in play", "what tags show up that aren't in my saved list".

### `todoist.list_comments`

List the comments already posted on a task or a project. Use when the user asks what's been said or discussed there. Give exactly one of task_id or project_id. To add a new one, use create_comment.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /comments`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `project_id` | string | no | Project id to list comments for. Give this or task_id, not both. |
| `task_id` | string | no | Task id to list comments for. Give this or project_id, not both. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `comments` | array of object |  |
| `comments[].content` | string |  |
| `comments[].id` | string |  |
| `comments[].posted_at` | string |  |
| `comments[].project_id` | string |  |
| `comments[].task_id` | string |  |

Also retrieved by: "what's been said on this to-do", "show the discussion on this todoist project", "read the notes here".

### `todoist.get_comment`

Get one Todoist comment's text and posted time by id. Use for a specific known note on a to-do or list. To browse a task or project's comments, use list_comments.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `GET /comments/{{params.comment_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `comment_id` | string | **yes** | Todoist comment id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `content` | string |  |
| `id` | string |  |
| `posted_at` | string |  |
| `project_id` | string |  |
| `task_id` | string |  |

Also retrieved by: "show me this note's text", "pull up this one comment", "when was this posted".

### `todoist.create_comment`

Post a comment on a task or a project. Use when the user wants to note, reply, or leave a message there. Give exactly one of task_id or project_id, plus the comment text.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /comments`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `content` | string | **yes** | Comment text. |
| `project_id` | string | no | Project id to comment on. Give this or task_id, not both. |
| `task_id` | string | no | Task id to comment on. Give this or project_id, not both. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `content` | string |  |
| `id` | string |  |
| `posted_at` | string |  |
| `project_id` | string |  |
| `task_id` | string |  |

Also retrieved by: "leave a note on this to-do", "post a message on this list", "reply on this item".

### `todoist.update_comment`

Edit the text of an existing comment on a task or project. Use when the user wants to fix or reword something they already posted.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /comments/{{params.comment_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `comment_id` | string | **yes** | Todoist comment id. |
| `content` | string | **yes** | New comment text. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `content` | string |  |
| `id` | string |  |

Also retrieved by: "fix what I said in this note", "reword this comment", "edit what I posted earlier".

### `todoist.delete_comment`

Permanently delete a comment from a task or project. Irreversible. Use only when the user is explicit about removing a comment entirely, not just editing it.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). Scopes `data:delete`. Calls `DELETE /comments/{{params.comment_id}}`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `comment_id` | string | **yes** | Todoist comment id. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `deleted` | boolean |  |

Also retrieved by: "remove this note entirely", "erase this comment for good", "take down what I posted".
