the tool surface, generated from the running server
MCP tools
init.Tasks speaks MCP at https://mcp.inittasks.com/mcp. It is the same data, the same scopes and the same revocation as the REST API, reached by an AI client instead of your code.
The hosted server is the way in. Point a client at that URL and it needs nothing installed. There is no package to download and no local build to run.
Connecting Claude, ChatGPT or Cursor to your own tasks needs none of the below. Start at connect an AI.
Read-only by default
A connection gets read access unless the user grants more. The server's 401 challenge asks for tasks:read tasks:write, and the approval screen starts with only read switched on; the user switches on write if they want it. 28 of the 97 tools work read-only. The rest need write access, and without it they are not registered at all. That is enforced server-side, not left to the client to respect.
Every tool needs its scopes
Each tool needs the same scopes as the REST route that does the same thing, listed in the needs column. A connection only sees the tools its permissions allow: a connection approved read-only holds tasks:read and sees every read tool, one approved to write holds tasks:write and sees every tool, and a user who edits a connection's permissions in the app (unticking notes, say) removes the tools that need what was unticked, from the next connection on (an open connection keeps its tools until it reconnects).
The tools that span several kinds of row check each row too, the way their REST routes do: search leaves out notes, capture rows and attachments the connection cannot read, get_inbox and get_someday leave out capture rows without inbox:read, list_trash leaves out notes and note folders without notes:read, and restore_trashed, permanent_delete, empty_trash and move_inbox_item refuse a row whose own write scope is missing. detach_attachment refuses to take an attachment out of its LAST place without inbox:write, because that makes an inbox item; get_todo lists attachments only with attachments:read and linked notes only with notes:read.
The tools
| tool | read-only | needs | what it does |
|---|---|---|---|
add_attachment |
[ ] | attachments:write |
Attach a link or a piece of text to a to-do, project, area or note (for a file, use upload_attachment). more |
add_subtask |
[ ] | todos:write |
Add a subtask to a to-do’s checklist: at the end, or right after another one (after, its id or exact title). more |
archive_inbox_item |
[ ] | inbox:write |
Archive an inbox item (hides it from the inbox). |
attach_note |
[ ] | notes:write |
Add an area, a project or a subproject to a note’s places (the apps’ attach to project…). more |
attach_to |
[ ] | attachments:write |
Put an existing attachment in ANOTHER place too (the apps’ attach to…): the same attachment, one stored file, also shows in that to-do, project, area or note. more |
bulk_update_todos |
[ ] | todos:write |
Do one thing to several to-dos at once, as the apps’ multi-select bar does: complete, trash, duplicate, when (a date phrase or yyyy-MM-dd, "someday", "anytime"), deadline (a date or null; a date on a someday to-do takes it out of someday, as a when does), move (a project or area name or id, or "no project"), add_tags / remove_tags (names). more |
capture_file |
[ ] | inbox:write |
Put a FILE or a picture straight into the inbox, as sharing it to init.Tasks does: a document you wrote (text) or any file as base64 (content_base64). more |
capture_inbox |
[ ] | inbox:write |
Quick-add capture into the inbox. more |
complete_heading |
[ ] | todos:write |
Complete every open to-do under a heading, exactly as complete_todo would one by one (a recurring to-do rolls to its next occurrence and stays open). more |
complete_todo |
[ ] | todos:write |
Mark a to-do done (idempotent). more |
convert_heading_to_subproject |
[ ] | containers:write todos:write |
Make a heading a subproject, in one batch: a subproject of the project with the heading’s name, every to-do under the heading moved into it in order, the heading deleted. more |
create_area |
[ ] | containers:write |
Create a top-level area. |
create_filter |
[ ] | filters:write |
Create a saved filter. more |
create_heading |
[ ] | containers:write |
Add a heading to a project or subproject: a named group of its to-dos (“before the move”, “moving day”, “after”). more |
create_note |
[ ] | notes:write |
Create a NOTE: a page of Markdown the user means to KEEP and read (a release history, a set of measurements, a paragraph they will want again). more |
create_note_folder |
[ ] | notes:write |
Create a note folder. more |
create_project |
[ ] | containers:write |
Create a project. more |
create_subproject |
[ ] | containers:write |
Create a subproject inside a project (resolved by name or id). more |
create_tag |
[ ] | tags:write |
Create a tag (names are lowercase, spaces collapsed). more |
create_todo |
[ ] | todos:write |
Create a to-do. more |
delete_attachment |
[ ] | attachments:write |
PERMANENTLY delete an attachment from every place it is in, with its stored file. more |
delete_container |
[ ] | containers:write |
Alias of trash_container. more |
delete_filter |
[ ] | filters:write |
Delete a saved filter: it moves to the TRASH, recoverably, as the apps’ delete does (restore_trashed brings it back; the to-dos it matched are never touched). more |
delete_heading |
[ ] | containers:write todos:write |
Delete a heading and KEEP its to-dos: they stay in the project, in their order, under no heading. more |
delete_inbox_item |
[ ] | inbox:write |
Delete a capture from the inbox as the apps do: it is archived, and a file or picture it holds is deleted from storage. more |
delete_subtask |
[ ] | todos:write |
Remove one subtask from a to-do’s checklist (it is gone; subtasks have no trash). |
delete_tag |
[ ] | tags:write |
Delete a tag: it moves to the TRASH, recoverably, as the apps’ delete does. more |
delete_todo |
[ ] | todos:write |
Alias of trash_todo. more |
detach_attachment |
[ ] | attachments:write |
Take an attachment out of ONE of its places (the apps’ detach). more |
detach_note |
[ ] | notes:write |
Take a note out of one area, project or subproject (the apps’ detach). more |
duplicate_todo |
[ ] | todos:write |
Duplicate a to-do, as the apps’ duplicate does: a new OPEN copy right after it, in the same project and heading, with its dates, time, reminders, tags, priority, colour and repeat rule; its subtasks are copied unticked. more |
empty_trash |
[ ] | todos:write |
Permanently delete EVERY trashed root and its subtree. more |
export_notes |
[✓] | notes:read |
Export one note, or every note, as Markdown (front matter, then the text with its embeds rewritten to standard Markdown) or plain text, in the apps' layout: <folder>/<title>.md, notes in no folder under attached notes/ or inbox/. more |
get_all_tasks |
[✓] | todos:read containers:read |
The full task tree (the apps call it “all tasks”): the open to-dos with NO project first (noProjectTodos), then areas (with their OWN to-dos, then their projects) → projects → subprojects, with recursive open-todo counts and progress. more |
get_anytime |
[✓] | todos:read containers:read |
Anytime: open, SORTED to-dos with no scheduled date, in an area, a project, a subproject, or marked "no project". more |
get_completed |
[✓] | todos:read containers:read |
Completed (was the logbook): count is the nav count; byContainer is each area/project/subproject’s completed section (its done to-dos including its descendants’, newest first: the latest 10 and how many more). more |
get_filter |
[✓] | filters:read todos:read |
A saved filter’s VIEW: the matched to-dos with their count, in list order: to-dos with no project first, then by position in the tree. more |
get_inbox |
[✓] | todos:read containers:read |
The inbox is the doorway: UNSORTED to-dos first (open, no parent, no date, and never given a when/where answer), then open capture rows in capture order. more |
get_logbook |
[✓] | todos:read containers:read |
Deprecated alias of get_completed (the logbook was renamed completed in September 2026). more |
get_next_7_days |
[✓] | todos:read containers:read |
Deprecated alias kept for older clients (next 7 days was merged into planned in September 2026): the seven days today … today+6 built from the current lists: day 0 is today (its overdue, from-earlier and today blocks), days 1–6 are planned’s six days. more |
get_note |
[✓] | notes:read |
Read ONE note the way its page shows it: the title and the Markdown body, then its folder, its places (the areas, projects and subprojects it is in), its tags, the to-dos and the other notes it is linked with, its attachments, and every embed in the text with the name it shows (an embed is written [title](note:ID), [title](task:ID), [name](container:ID),  or [name](att:ID)). |
get_note_version |
[✓] | notes:read |
One version of a note: its title and body as they were, and what changed against the version before it (added and removed runs of words). |
get_notes |
[✓] | notes:read containers:read inbox:read |
The older notes view, from before folders and places: every note in three blocks. more |
get_overview |
[✓] | todos:read containers:read |
Alias of get_all_tasks (the apps renamed the overview “all tasks”); the same payload. more |
get_planned |
[✓] | todos:read containers:read |
Planned: open to-dos scheduled after today, grouped by their scheduled date. more |
get_project |
[✓] | todos:read containers:read |
One project, subproject or area as its page shows it. more |
get_settings |
[✓] | settings:read |
The settings the account shares across devices: the first day of the week, the time a new reminder gets, the daily overdue reminder (null = off), and the shared calendar choices (each calendar’s colour and whether it shows, and whether events show in today and planned). |
get_someday |
[✓] | todos:read containers:read |
Someday, grouped: parked to-dos and parked inbox items. more |
get_today |
[✓] | todos:read containers:read |
Today, in three blocks: overdue (a missed deadline, including a to-do still in the inbox), fromEarlier (scheduled on a day that has passed), todayItems (scheduled or due today). more |
get_todo |
[✓] | todos:read |
One to-do in full: its title, notes, dates, start time, length and every reminder, its checklist of subtasks, tags, repeat, heading and project, its attachments (with every place each one is in) and the notes linked to it. more |
get_upcoming |
[✓] | todos:read containers:read |
Deprecated alias of get_planned (upcoming was renamed planned in September 2026). more |
inbox_to_someday |
[ ] | inbox:write |
Park an inbox item in someday (it stays an inbox item; parking strips its captured date, and archive keeps it). |
link_note_task |
[ ] | notes:write |
LINK a note to a to-do (many-to-many: a note can be linked to many to-dos and a to-do to many notes). more |
link_notes |
[ ] | notes:write |
Link two notes. more |
list_attachments |
[✓] | attachments:read |
Attachments (links, text, files and pictures). more |
list_filters |
[✓] | filters:read todos:read |
The saved filters, in the order they are listed in the app. more |
list_headings |
[✓] | containers:read |
The headings of a project or subproject, in order, each with its open count. more |
list_note_folders |
[✓] | notes:read |
The note folders, in sidebar order: each top-level folder followed by its subfolders (folders nest ONE level). more |
list_note_versions |
[✓] | notes:read |
A note's version history, the apps' history: its text as it was at the end of each editing stretch, the current one first (current: true), then newest first. more |
list_notes |
[✓] | notes:read |
List notes with filters (all optional, combined with AND), in the order the apps draw them: pinned first, then most recently edited. more |
list_tags |
[✓] | tags:read |
Every tag, in the order the sidebar shows them, with its colour and how many open to-dos and attachments carry it. |
list_trash |
[✓] | todos:read |
The trash view: trashed ROOTS only (a row trashed individually inside a container that was later trashed is hidden here but still purges by its own stamp), newest first. more |
move_attachment |
[ ] | attachments:write |
Reorder an attachment within ONE of its places (each place keeps its own order). more |
move_container |
[ ] | containers:write |
Move an area/project/subproject to a new parent, and/or reorder it among its new siblings. more |
move_filter |
[ ] | filters:write |
Move a saved filter in the filter list. more |
move_heading |
[ ] | containers:write |
Reorder a heading among its project’s headings (its to-dos move with it). more |
move_inbox_item |
[ ] | inbox:write todos:write |
Sort an inbox item onto a target (resolved by name or id): an area, a project, a subproject, or a to-do. more |
move_note |
[ ] | notes:write |
MOVE a note in a list: to its first place, a reorder (every place kept); to another area, project or subproject, that container becomes its ONLY place (the apps' move to…); with no parent, every place is removed. more |
move_to_anytime |
[ ] | todos:write |
Move an existing to-do to anytime: detach it from its project and clear its scheduled date, keeping its deadline and tags. more |
move_todo |
[ ] | todos:write |
Reparent and/or reorder a to-do. more |
permanent_delete |
[ ] | todos:write |
Permanently delete a row that is IN THE TRASH, by id (from list_trash, or a row inside a trashed container). more |
rename_heading |
[ ] | containers:write |
Rename a heading. more |
rename_tag |
[ ] | tags:write |
Rename a tag, or merge it into another. more |
restore_note_version |
[ ] | notes:write |
Put a note's text back to an older version. more |
restore_trashed |
[ ] | todos:write |
Restore a trashed root by id: this clears its trash stamp, and the row returns to its views untouched. more |
search |
[✓] | todos:read containers:read |
Search everything: case-insensitive substring match across to-do titles/subtitles/descriptions/subtask titles/tags, container names/subtitles/descriptions, note titles/bodies/tags/folder names (an embed in a note by its name, never its id), inbox text/urls/titles, and attachment titles/urls/text. more |
set_calendar_prefs |
[ ] | settings:write |
Change the calendar choices every device shares: show turns events in today and planned on or off; each entry of calendars sets one calendar’s colour ("#RRGGBB", or null for its own) and whether it shows. more |
set_reminder_defaults |
[ ] | settings:write |
Set the two reminder settings that sync with the account. more |
set_week_start |
[ ] | settings:write |
Set the first day of the week (shared setting): 1 = Monday (the default), 7 = Sunday, null = Monday. more |
subtask_to_todo |
[ ] | todos:write |
Turn a subtask into a to-do of its own (the apps’ make task): a new open to-do right after its parent, in the same project, heading and day; the subtask leaves the checklist. |
trash_container |
[ ] | containers:write |
Move an area/project/subproject (and, by exclusion, its whole subtree) to trash. more |
trash_note |
[ ] | notes:write |
Move a note to trash, recoverably. more |
trash_note_folder |
[ ] | notes:write |
Move a note folder to the trash, recoverably: its subfolders and every note in them go with it. more |
trash_todo |
[ ] | todos:write |
Move a to-do to trash. more |
uncomplete_todo |
[ ] | todos:write |
Reopen a done to-do (clears completedAt). more |
unlink_note_task |
[ ] | notes:write |
Remove the link between a note and a to-do. more |
unlink_notes |
[ ] | notes:write |
Remove the link between two notes. more |
update_attachment |
[ ] | attachments:write |
Rename an attachment, change a link’s url or a text attachment’s text, or set its tags (the WHOLE set, by name; [] clears them). more |
update_container |
[ ] | containers:write |
Edit an area/project/subproject. more |
update_filter |
[ ] | filters:write |
Edit a saved filter: pass name and/or criteria (the same { v:2, match, criteria:[…] } shape as create_filter). more |
update_inbox_item |
[ ] | inbox:write |
Edit a capture waiting in the inbox: its text (a text capture or a captured note), url (a link), title, or its when (a date phrase or yyyy-MM-dd; null clears it), or move it in the inbox (position: "first", "last" or the id of the capture to put it after). |
update_note |
[ ] | notes:write |
Edit a note. more |
update_note_folder |
[ ] | notes:write |
Rename, recolour, change the icon of, move or reorder a note folder. more |
update_subtask |
[ ] | todos:write |
Rename, tick, untick or move one subtask. more |
update_tag |
[ ] | tags:write |
Recolour a tag or move it in the tag list. more |
update_todo |
[ ] | todos:write |
Edit a to-do. more |
upload_attachment |
[ ] | attachments:write |
Attach a FILE to a to-do, project, area or note: a document you wrote (send text, for example the contents of notes.md or a CSV) or any file as base64 (content_base64). more |
Arguments
Every tool below is registered by the server with the schema shown. Types and required flags are rendered from that schema at build time, so they cannot drift from what the server actually accepts.
add_attachment
Attach a link or a piece of text to a to-do, project, area or note (for a file, use upload_attachment). to is an id or exact name; place_type says which kind when a name could be either. A link needs url, a text attachment text. tags are names; new ones are created.
Needs attachments:write
Arguments
kind(url,text, required)place_type(todo,container,note, optional)tags(array of string, optional)text(string, optional)title(string, optional)to(string, required)url(string (uri), optional)
add_subtask
Add a subtask to a to-do’s checklist: at the end, or right after another one (after, its id or exact title). At most 50 per to-do; a title is one line of at most 120 characters.
Needs todos:write
Arguments
after(string, optional)title(string, required)todo(string, required): the to-do: id or exact titletz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
archive_inbox_item
Archive an inbox item (hides it from the inbox).
Needs inbox:write
Arguments
id(string, required)
attach_note
Add an area, a project or a subproject to a note’s places (the apps’ attach to project…). The note then ALSO shows there; it stays everywhere else it was, and its folder does not change. Adding a place it already has changes nothing. To make one container its ONLY place, use move_note.
Needs notes:write
Arguments
note(string, required): the note idto(string, required): the area, project or subproject, by exact name or id
attach_to
Put an existing attachment in ANOTHER place too (the apps’ attach to…): the same attachment, one stored file, also shows in that to-do, project, area or note. Already there changes nothing.
Needs attachments:write
Arguments
attachment(string, required): its id, exact title or urlplace_type(todo,container,note, optional)to(string, required)
bulk_update_todos
Do one thing to several to-dos at once, as the apps’ multi-select bar does: complete, trash, duplicate, when (a date phrase or yyyy-MM-dd, "someday", "anytime"), deadline (a date or null; a date on a someday to-do takes it out of someday, as a when does), move (a project or area name or id, or "no project"), add_tags / remove_tags (names). Each to-do is resolved by id or exact title; each result says ok or why not, and one failure does not stop the others.
Needs todos:write
Arguments
action(complete,trash,duplicate,when,deadline,move,add_tags,remove_tags, required)todos(array of string, required)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.value(string or array of string, optional): when: the date or "someday" / "anytime"; deadline: a date or null; move: the destination; add_tags / remove_tags: the names
capture_file
Put a FILE or a picture straight into the inbox, as sharing it to init.Tasks does: a document you wrote (text) or any file as base64 (content_base64). name is the filename WITH its extension. At most 2 MB through this tool; a bigger file (up to the apps' 100 MB) goes through the REST API: POST https://api.inittasks.com/v1/inbox/upload with the raw bytes as the body. File it later with move_inbox_item, like any capture.
Needs inbox:write
Arguments
content_base64(string, optional): the file content as base64, for anything that is not textmime(string, optional): the media type; omitted, it is taken from the extensionname(string, required)text(string, optional): the file content as text (UTF-8)
capture_inbox
Quick-add capture into the inbox. Kind (text/url) is auto-detected. For a text capture the trailing date phrase is parsed via the canonical quick-add grammar ("call maria tomorrow", "renew passport 7 oct"). The remainder becomes the item text and the parsed date is PERSISTED on the item, ready to ride onto the to-do when it is later moved into a project. For a url the page title is fetched once, behind the outbound-fetch guard, and stored encrypted with the capture (a page that cannot be read leaves it null). Pass kind 'note' to capture a NOTE for filing later, with the Markdown body in text_or_url and an optional title in title. A note is never auto-detected, which is exactly what separates one from a scrap of captured text: say so or it is a text capture. To create a note directly inside a project instead, use create_note.
Needs inbox:write
Arguments
kind(note, optional): only 'note'. text and url are detected; a note never istext_or_url(string, required)title(string, optional): the heading of a kind:'note' capture; ignored otherwisetz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
complete_heading
Complete every open to-do under a heading, exactly as complete_todo would one by one (a recurring to-do rolls to its next occurrence and stays open). The heading stays.
Needs todos:write
Arguments
heading(string, required)project(string, optional)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
complete_todo
Mark a to-do done (idempotent). A recurring active occurrence spawns its next occurrence: a done copy is created and the active row advances to its next occurrence. Resolve by id or exact title.
Needs todos:write
Arguments
id_or_title(string, required)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
convert_heading_to_subproject
Make a heading a subproject, in one batch: a subproject of the project with the heading’s name, every to-do under the heading moved into it in order, the heading deleted. Use it when a group grows its own deadline or notes. Only in a PROJECT: a subproject cannot hold subprojects, so a heading inside a subproject is refused.
Needs containers:write todos:write
Arguments
heading(string, required)project(string, optional)
create_area
Create a top-level area.
Needs containers:write
Arguments
name(string, required)
create_filter
Create a saved filter. criteria is { v:2, match:"all"|"any", criteria:[ …criterion ] }, where "all" means a to-do must satisfy every criterion and "any" means at least one. Each criterion is a KIND with an OPERATOR and, for most operators, a value: tag (is | is_not | has_all) * project (is | is_not) * area (is | is_not) * date (has | none | is | between | within) * deadline (has | none | is | between | within) * reminder (has | none) * repeat (has | none) * weekday (is | is_not) * month (is | is_not) * priority (at_least | is) * time (has | none | between | before | after) * length (has | none | at_least | at_most | between) * subtasks (has | none | has_open) * notes (has | none) * attachments (has | none) * color (has | none | is) * title (contains | not_contains) * created (in_last | is | between) * list (is | is_not). Dates are yyyy-MM-dd; "within" has no lower bound, so overdue is included; weekday and month read the to-do's DATE, never its deadline, and a to-do with no date matches neither "is" nor "is_not". A criterion this build cannot parse is rejected here; only STORED filters may be inert. Returns the filter and its match count.
Needs filters:write
Arguments
criteria(object, required): filter criteria v2: { v:2, match:"all"|"any", criteria:[ …criterion ] }name(string, required)symbol(string, optional): its icon: an SF Symbol name, unfilled (for example "line.3.horizontal.decrease", "tag", "flag"); null for the defaulttz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
create_heading
Add a heading to a project or subproject: a named group of its to-dos (“before the move”, “moving day”, “after”). Not in an area. after = omitted (last), "start" (first), or a heading (id or name) of the same project to place it right after. Then file to-dos under it with update_todo / move_todo heading, or create_todo heading.
Needs containers:write
Arguments
after(string, optional)name(string, required)project(string, required): the project or subproject: exact name or id
create_note
Create a NOTE: a page of Markdown the user means to KEEP and read (a release history, a set of measurements, a paragraph they will want again). It is not a to-do: no done state, no dates, no priority. A note needs a title OR a body. It can sit in one FOLDER (folder), be in any number of areas, projects and subprojects (parent_name_or_id, then places), carry tags, and be LINKED to to-dos (link_todo_ids) and to other notes (link_note_ids). All optional and independent; a note with no folder, no place and no link shows in the inbox. The body may embed things: [title](note:ID) links that note, [title](task:ID) links that to-do, [name](container:ID) adds that place. To capture a note for triage later instead, use capture_inbox with kind 'note'.
Needs notes:write
Arguments
body(string, optional): the note itself, Markdown; may be omitted when a title is givencolor(string, optional): a #RRGGBB colour: a tint behind the note in the apps’ lists and cardsfolder(string, optional): a note folder, by exact name or id (list_note_folders)link_note_ids(array of string, optional): ids of other notes to link the new note with (two-way)link_todo_ids(array of string, optional): to-do ids to link the new note toparent_name_or_id(string, optional): attach it to an area, project or subproject, by exact name or id. Never a to-do (link to-dos instead)pinned(boolean, optional): create it pinned (pinned notes sort first)places(array of string, optional): more areas, projects or subprojects (names or ids) the note is in, after parent_name_or_idtags(array of string, optional): tag names; a tag that does not exist yet is createdtitle(string, optional): the heading; a note needs a title or a body
create_note_folder
Create a note folder. inside: a TOP-LEVEL folder (name or id) to nest it in; folders nest one level only. color: #RRGGBB. symbol: an SF Symbol name for the icon (default folder).
Needs notes:write
Arguments
color(string, optional)inside(string, optional)name(string, required)symbol(string, optional)
create_project
Create a project. area is resolved by name or id; omit for an area-less project. color = #RRGGBB. priority = low|medium|high (a display-only ! mark).
Needs containers:write
Arguments
area_name_or_id(string, optional)color(string, optional)name(string, required)priority(low,medium,high, optional)subtitle(string, optional)
create_subproject
Create a subproject inside a project (resolved by name or id). priority = low|medium|high (a display-only ! mark).
Needs containers:write
Arguments
name(string, required)priority(low,medium,high, optional)project(string, required)
create_tag
Create a tag (names are lowercase, spaces collapsed). Creating one that exists returns it unchanged. color is "#RRGGBB".
Needs tags:write
Arguments
color(string, optional)name(string, required)
create_todo
Create a to-do. Parent (an AREA, a project or a subproject) is resolved by exact name (case-insensitive) or id. With no parent, no when and no no_project, the to-do is a capture: it lands in the INBOX, waiting to be sorted. no_project: true files it with no project (it lists in anytime); it cannot be combined with a parent. A parent or a when sorts it too. when/deadline accept natural language ("tomorrow", "fri", "7 oct") or yyyy-MM-dd. Pass repeat to make it recurring (this clears deadline and stamps whenDate as the anchor). A repeat rule takes an optional mode ("schedule", the default fixed grid, or "afterCompletion", where the next date counts from when you complete it. afterCompletion carries ONLY freq+interval), an optional until (strict yyyy-MM-dd, the last date an occurrence may fall on, inclusive) and/or an optional count (occurrences remaining incl. the active one, 1…999, decremented on each completion). Setting a repeat with no when in schedule mode seeds the first occurrence date; in afterCompletion mode it seeds when=today. reminder is a local yyyy-MM-ddTHH:mm (one reminder). time (a start, "HH:mm"), duration_min and reminders (up to 5, each { before_min } or { at }) schedule it on its day; a time with no when dates it today. subtasks gives it a checklist.
Needs todos:write
Arguments
color(string, optional): its colour, #RRGGBB (the apps draw it as a highlight behind the row); null clears itdeadline(string, optional)description(string, optional)duration_min(integer, optional): The length in minutes, 5 to 1440 (it can exist without a time). null clears it.heading(string, optional): a HEADING of the project to put it under (id or exact name). Without parent_name_or_id, the heading’s project becomes the parent.no_project(boolean, optional): true = sorted with NO project (the "no project" answer; lists in anytime instead of the inbox). Not with parent_name_or_id.parent_name_or_id(string, optional)priority(low,medium,high, optional): a display-only mark, ! / !! / !!! before the title; never affects orderingreminder(string, optional): local-naive yyyy-MM-ddTHH:mmreminders(array of object, optional): The WHOLE reminder list, at most 5 (replaces the current one; [] or null clears it). Do not combine withreminder.repeat(object, optional)subtasks(array of object, optional): The WHOLE checklist of subtasks, in order, at most 50 (replaces the current one; [] or null clears it). For one subtask use add_subtask / update_subtask / delete_subtask.subtitle(string, optional)tags(array of string, optional): tag names, at most 64 tags of at most 64 characters; unknown tags are createdtime(string, optional): The start time, "HH:mm" on a 24-hour clock (local wall clock). On a to-do with no date it dates it today. null removes the time: the start AND the length go, and each "before" reminder becomes a fixed one at its old moment.title(string, required)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.when(string, optional)
delete_attachment
PERMANENTLY delete an attachment from every place it is in, with its stored file. There is no trash for attachments, so this needs confirm: true. To take it out of one place only, use detach_attachment.
Needs attachments:write
Arguments
attachment(string, required): its id, exact title or urlconfirm(boolean, required): must be true: this cannot be undone
delete_container
Alias of trash_container. It moves a container subtree to trash, recoverably. For an irreversible hard delete use permanent_delete.
Needs containers:write
Arguments
id_or_name(string, required)
delete_filter
Delete a saved filter: it moves to the TRASH, recoverably, as the apps’ delete does (restore_trashed brings it back; the to-dos it matched are never touched). While it is in the trash it matches nothing and list_filters leaves it out. To destroy it for good, call permanent_delete on its id afterwards. Resolve by id or exact name.
Needs filters:write
Arguments
id_or_name(string, required)
delete_heading
Delete a heading and KEEP its to-dos: they stay in the project, in their order, under no heading. The heading itself is gone for good (headings have no trash), but nothing else is lost. Returns the to-dos it held.
Needs containers:write todos:write
Arguments
heading(string, required)project(string, optional)
delete_inbox_item
Delete a capture from the inbox as the apps do: it is archived, and a file or picture it holds is deleted from storage. (archive_inbox_item keeps the file.)
Needs inbox:write
Arguments
item(string, required): its id, or its exact text, title or url
delete_subtask
Remove one subtask from a to-do’s checklist (it is gone; subtasks have no trash).
Needs todos:write
Arguments
subtask(string, required): its id or exact titletodo(string, required)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
delete_tag
Delete a tag: it moves to the TRASH, recoverably, as the apps’ delete does. While it is in the trash it is hidden everywhere (list_tags leaves it out) and a filter criterion naming it matches nothing, but every to-do, attachment and note KEEPS its name, so restore_trashed brings everything back; creating a tag of the same name restores it too. To destroy it for good (it then leaves every to-do, attachment and note), call permanent_delete on its id afterwards.
Needs tags:write
Arguments
tag(string, required): its id or name
delete_todo
Alias of trash_todo. It moves a to-do to trash, recoverably. For an irreversible hard delete use permanent_delete.
Needs todos:write
Arguments
id_or_title(string, required)
detach_attachment
Take an attachment out of ONE of its places (the apps’ detach). If it is still in other places it stays there. If that was its LAST place it becomes an inbox item holding the same link, text or file (its tags stay behind).
Needs attachments:write
Arguments
attachment(string, required): its id, exact title or urlfrom(string, required): the place: id or exact nameplace_type(todo,container,note, optional)
detach_note
Take a note out of one area, project or subproject (the apps’ detach). It stays in its other places, its folder and its links; a note left with no folder, no place and no link shows in the inbox.
Needs notes:write
Arguments
from(string, required): the area, project or subproject, by exact name or idnote(string, required): the note id
duplicate_todo
Duplicate a to-do, as the apps’ duplicate does: a new OPEN copy right after it, in the same project and heading, with its dates, time, reminders, tags, priority, colour and repeat rule; its subtasks are copied unticked. Resolve by id or exact title.
Needs todos:write
Arguments
id_or_title(string, required)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
empty_trash
Permanently delete EVERY trashed root and its subtree. The irreversible hard-delete cascade for the whole trash. Destructive, so it requires confirm: true.
Needs todos:write
Arguments
confirm(boolean, optional)
export_notes
Export one note, or every note, as Markdown (front matter, then the text with its embeds rewritten to standard Markdown) or plain text, in the apps' layout: <folder>/<title>.md, notes in no folder under attached notes/ or inbox/. Returns each file's path and content; the files and pictures the notes hold are listed by path and id (their bytes are not included).
Needs notes:read
Arguments
format(markdown,text, optional)note(string, optional): a note id; omit for every note
get_all_tasks
The full task tree (the apps call it “all tasks”): the open to-dos with NO project first (noProjectTodos), then areas (with their OWN to-dos, then their projects) → projects → subprojects, with recursive open-todo counts and progress. A project with HEADINGS lists them (headings) and gives its todos in page order: the to-dos under no heading first, then each heading’s, each to-do naming its heading. EVERY live container is in the tree, an empty one too (openCount 0). To-dos still waiting in the inbox (unsorted) are not in the tree; inbox.open counts them with the captures (see get_inbox). navCounts = inbox, today, overdue, planned, anytime, someday, overview (= all tasks), notes, completed, trash. homeCounts = the numbers the apps’ home screen shows: the same, except planned includes the today block, notes includes notes waiting in the inbox, and attachments counts every attachment on a live parent plus the shared links/images/files waiting in the inbox. The one call to understand everything.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_anytime
Anytime: open, SORTED to-dos with no scheduled date, in an area, a project, a subproject, or marked "no project". A future deadline may exist (it moves the to-do to today on its day). An unsorted to-do (still in the inbox) is NOT here. No-project to-dos first, then the tree.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_completed
Completed (was the logbook): count is the nav count; byContainer is each area/project/subproject’s completed section (its done to-dos including its descendants’, newest first: the latest 10 and how many more). days: every done to-do (non-trashed, with a completedAt), grouped by the LOCAL calendar day it was completed, newest day first, and completedAt-descending within a day. Each day carries its date, a label, a count and the to-dos. Recurring done copies appear like any done to-do; inbox items never appear. Unbounded.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_filter
A saved filter’s VIEW: the matched to-dos with their count, in list order: to-dos with no project first, then by position in the tree. Universe = open + someday visible to-dos, unsorted ones in the inbox included; done never matches (completed owns history). Whether a to-do has to satisfy EVERY criterion or just one is the filter’s own match, reported on the row. An INERT filter (criteria this build cannot parse) returns count 0, no matches, and a muted note. Resolve by id or exact name.
Needs filters:read todos:read
Arguments
id_or_name(string, required)tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_inbox
The inbox is the doorway: UNSORTED to-dos first (open, no parent, no date, and never given a when/where answer), then open capture rows in capture order. openCount counts both. A to-do leaves the inbox the moment it gets a date, a parent, someday, anytime, or "no project" (create_todo/update_todo no_project: true). Tags, a deadline or a reminder do NOT sort it. There is no way back into the inbox.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_logbook
Deprecated alias of get_completed (the logbook was renamed completed in September 2026). Completed (was the logbook): count is the nav count; byContainer is each area/project/subproject’s completed section (its done to-dos including its descendants’, newest first: the latest 10 and how many more). days: every done to-do (non-trashed, with a completedAt), grouped by the LOCAL calendar day it was completed, newest day first, and completedAt-descending within a day. Each day carries its date, a label, a count and the to-dos. Recurring done copies appear like any done to-do; inbox items never appear. Unbounded.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_next_7_days
Deprecated alias kept for older clients (next 7 days was merged into planned in September 2026): the seven days today … today+6 built from the current lists: day 0 is today (its overdue, from-earlier and today blocks), days 1–6 are planned’s six days. Prefer get_today + get_planned.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_note
Read ONE note the way its page shows it: the title and the Markdown body, then its folder, its places (the areas, projects and subprojects it is in), its tags, the to-dos and the other notes it is linked with, its attachments, and every embed in the text with the name it shows (an embed is written [title](note:ID), [title](task:ID), [name](container:ID),  or [name](att:ID)).
Needs notes:read
Arguments
note(string, required): the note id
get_note_version
One version of a note: its title and body as they were, and what changed against the version before it (added and removed runs of words).
Needs notes:read
Arguments
note(string, required): the note idversion(string, required): the version id (list_note_versions)
get_notes
The older notes view, from before folders and places: every note in three blocks. First the notes still sitting in the inbox awaiting filing, then one group per area, project or subproject that holds notes, then the notes attached to nothing (which includes notes that are only in a folder). To-dos never appear here. For folders, pins, linked to-dos and filters use list_notes and list_note_folders.
Needs notes:read containers:read inbox:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_overview
Alias of get_all_tasks (the apps renamed the overview “all tasks”); the same payload. The full task tree (the apps call it “all tasks”): the open to-dos with NO project first (noProjectTodos), then areas (with their OWN to-dos, then their projects) → projects → subprojects, with recursive open-todo counts and progress. A project with HEADINGS lists them (headings) and gives its todos in page order: the to-dos under no heading first, then each heading’s, each to-do naming its heading. EVERY live container is in the tree, an empty one too (openCount 0). To-dos still waiting in the inbox (unsorted) are not in the tree; inbox.open counts them with the captures (see get_inbox). navCounts = inbox, today, overdue, planned, anytime, someday, overview (= all tasks), notes, completed, trash. homeCounts = the numbers the apps’ home screen shows: the same, except planned includes the today block, notes includes notes waiting in the inbox, and attachments counts every attachment on a live parent plus the shared links/images/files waiting in the inbox. The one call to understand everything.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_planned
Planned: open to-dos scheduled after today, grouped by their scheduled date. days is ALWAYS the next six days (today+1 … today+6), each present even when empty; later holds only the later dates that have something. A deadline never places a to-do here (a sorted deadline-only to-do is in anytime until its day; an unsorted one stays in the inbox). Within a day: no-project to-dos first, then the tree. The apps’ planned page opens with today’s block first: that is get_today’s todayItems.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_project
One project, subproject or area as its page shows it. For a project or subproject: its open to-dos in PAGE order (todos, the ones under no heading), then its headings in order, each with its open todos; then someday (parked to-dos), doneCount, its subprojects with their open counts, and its notes. For an area: its own open to-dos and its projects. Use it before organizing a project: it shows every heading id.
Needs todos:read containers:read
Arguments
project(string, required): the project, subproject or area: exact name (case-insensitive) or idtz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_settings
The settings the account shares across devices: the first day of the week, the time a new reminder gets, the daily overdue reminder (null = off), and the shared calendar choices (each calendar’s colour and whether it shows, and whether events show in today and planned).
Needs settings:read
Takes no arguments.
get_someday
Someday, grouped: parked to-dos and parked inbox items. Parking is timeline-free (it strips dates), so no date meta renders here. Rendered top to bottom: standalone FIRST (parked to-dos with no project, then parked TEXT inbox captures); then groups, every area/project/subproject with DIRECT parked to-dos, in overview-tree order, each { container, todos }; attachments (parked url/image/file inbox items) last. containerSomeday is the raw {containerId: [todoIds]} map that also feeds each container’s own collapsible someday section.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_today
Today, in three blocks: overdue (a missed deadline, including a to-do still in the inbox), fromEarlier (scheduled on a day that has passed), todayItems (scheduled or due today). Each block lists to-dos with no project first, then the tree. Plus what was completed today. counts.today = fromEarlier + todayItems; overdue is its own number.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_todo
One to-do in full: its title, notes, dates, start time, length and every reminder, its checklist of subtasks, tags, repeat, heading and project, its attachments (with every place each one is in) and the notes linked to it. Resolve by id or exact title.
Needs todos:read
Arguments
id_or_title(string, required)tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
get_upcoming
Deprecated alias of get_planned (upcoming was renamed planned in September 2026). Planned: open to-dos scheduled after today, grouped by their scheduled date. days is ALWAYS the next six days (today+1 … today+6), each present even when empty; later holds only the later dates that have something. A deadline never places a to-do here (a sorted deadline-only to-do is in anytime until its day; an unsorted one stays in the inbox). Within a day: no-project to-dos first, then the tree. The apps’ planned page opens with today’s block first: that is get_today’s todayItems.
Needs todos:read containers:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
inbox_to_someday
Park an inbox item in someday (it stays an inbox item; parking strips its captured date, and archive keeps it).
Needs inbox:write
Arguments
id(string, required)
link_note_task
LINK a note to a to-do (many-to-many: a note can be linked to many to-dos and a to-do to many notes). Linking a pair that is already linked changes nothing. Neither row moves: a to-do never owns a note.
Needs notes:write
Arguments
note_id(string, required)todo_id(string, required)
link_notes
Link two notes. Links are two-way: each note then lists the other in its notes section. Linking a pair that is already linked changes nothing; a note cannot be linked to itself. (Writing [title](note:ID) in a note’s body with update_note links them too.)
Needs notes:write
Arguments
note(string, required): one note idother_note(string, required): the other note id
list_attachments
Attachments (links, text, files and pictures). With place, the ones IN that to-do, project, area or note, in that place’s order (an attachment can be in several places). With tag, the ones carrying that tag. With neither, every attachment once.
Needs attachments:read
Arguments
kind(url,text,image,file, optional)place(string, optional): a to-do, project, area or note: an id or an exact nameplace_type(todo,container,note, optional): say which kindplaceis when a name is ambiguoustag(string, optional)
list_filters
The saved filters, in the order they are listed in the app. Each row reports match (all = every criterion, any = at least one), its parsed criteria, a live match COUNT, a derived priorityMin when the filter carries a priority criterion, and inert=true for a filter whose criteria this client can’t parse (an unknown or newer-version shape; it matches nothing and renders a muted note). The universe is open plus someday visible to-dos; a done to-do never matches, because history belongs to completed. The three defaults low/medium/high are ordinary rows.
Needs filters:read todos:read
Arguments
tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
list_headings
The headings of a project or subproject, in order, each with its open count. Omit project for every heading in the account, by project. A heading is a named group of to-dos inside a project (“before the move”, “moving day”): it has no dates or notes of its own; if a group needs those, convert it to a subproject.
Needs containers:read
Arguments
project(string, optional): the project or subproject: exact name or id
list_note_folders
The note folders, in sidebar order: each top-level folder followed by its subfolders (folders nest ONE level). Each carries its live note count. Trashed folders are left out (list_trash shows them).
Needs notes:read
Takes no arguments.
list_note_versions
A note's version history, the apps' history: its text as it was at the end of each editing stretch, the current one first (current: true), then newest first. Each version says what made it (stretch, checkpoint, original = the first text, replaced = text that lost when two devices edited at once, restore), which kind of device wrote it, and how many words it added and removed. Read one with get_note_version.
Needs notes:read
Arguments
note(string, required): the note id
list_notes
List notes with filters (all optional, combined with AND), in the order the apps draw them: pinned first, then most recently edited. folder: a folder name or id, or 'none' for notes in no folder. attached_to: an area/project/subproject name or id the note is in (a note can be in several). linked_todo_id / linked_note_id: notes linked to that to-do / that note. tag: a tag name. placement: 'folder' (in a folder), 'attached' (no folder; in a project/area or linked to a to-do or a note: the apps' 'attached notes'), 'orphan' (none of those; shown in the inbox). pinned: true/false. search: text in the title, the body (an embed by its name), a tag or the folder's name. Live notes only. Returns compact notes with their folder, places, tags, pin, links and where they show; get_note reads one in full.
Needs notes:read
Arguments
attached_to(string, optional)folder(string, optional)limit(integer, optional)linked_note_id(string, optional)linked_todo_id(string, optional)pinned(boolean, optional)placement(folder,attached,orphan, optional)search(string, optional)tag(string, optional)
list_tags
Every tag, in the order the sidebar shows them, with its colour and how many open to-dos and attachments carry it.
Needs tags:read
Takes no arguments.
list_trash
The trash view: trashed ROOTS only (a row trashed individually inside a container that was later trashed is hidden here but still purges by its own stamp), newest first. Each entry reports its kind, label, when it was trashed, purgesAt and daysLeft (the 30-day automatic purge, whole days rounded up), and, for containers, the subtree it will take with it on permanent delete.
Needs todos:read
Takes no arguments.
move_attachment
Reorder an attachment within ONE of its places (each place keeps its own order). position: "first", "last", "up", "down", or the id of the attachment to put it after.
Needs attachments:write
Arguments
attachment(string, required)in(string, required): the place whose list to reorder: id or exact nameplace_type(todo,container,note, optional)position(string, required)
move_container
Move an area/project/subproject to a new parent, and/or reorder it among its new siblings. parent = the destination container (name or id), or the literal "top" for the top level. A move can RE-KIND the row, exactly as dragging does: move a project onto a project and it becomes a SUBPROJECT of it; move a subproject to "top" and it is PROMOTED to a project. The hierarchy is closed (area → project → subproject), so illegal moves are refused with the reason. Nothing may nest under a subproject, a project that holds subprojects can only go to an area or the top level (never into a project), an area is always top level, and nothing may move into its own contents. position = "start" | "end" (default) | the id of a sibling to place it after.
Needs containers:write
Arguments
id_or_name(string, required)parent(string, required)position(string, optional)
move_filter
Move a saved filter in the filter list. position is "first", "last", or the id or name of the filter to put it after.
Needs filters:write
Arguments
filter(string, required): its id or nameposition(string, required)
move_heading
Reorder a heading among its project’s headings (its to-dos move with it). after = "start" for first, "end" for last, or another heading (id or name) of the same project to sit right after. A heading never changes project: to move its to-dos elsewhere, move the to-dos.
Needs containers:write
Arguments
after(string, required)heading(string, required)project(string, optional)
move_inbox_item
Sort an inbox item onto a target (resolved by name or id): an area, a project, a subproject, or a to-do. A text item MOVES into a container and becomes a sorted to-do there (carrying its captured date), unless as_attachment is true, when it becomes a text ATTACHMENT of the container or to-do (the apps' move to… / attach to…). A link, image or file item always ATTACHES to a container or to-do. A NOTE capture becomes a note row: attached to an area, project or subproject, LINKED to a to-do when the target is a to-do, or with no where when the target is "standalone"; folder also files it in a note folder. Pass target "anytime" to turn a text item into a sorted, no-project, unscheduled to-do. An image or file item marked pending (shared from a device that has not uploaded it yet) cannot be filed here: only that device can, once its upload finishes; try again later.
Needs inbox:write todos:write
Arguments
as_attachment(boolean, optional): text captures only: file it as an attachment instead of a to-dofolder(string, optional): NOTE captures only: a note folder (name or id) to file the note in. Combine with a target, or pass target "standalone" for a folder only.id(string, required)target(string, required)
move_note
MOVE a note in a list: to its first place, a reorder (every place kept); to another area, project or subproject, that container becomes its ONLY place (the apps' move to…); with no parent, every place is removed. With keep_other_places, it leaves only its first place for the new one and keeps the rest (the apps' drag). Its folder and links do not change. after and before may name a TO-DO or another NOTE of that container: a container's to-dos and notes share one ordered list. Without either, the note goes to the end. To ADD a place without moving the note, use attach_note.
Needs notes:write
Arguments
after(string, optional): id of the to-do or note to sit directly afterbefore(string, optional): id of the to-do or note to sit directly beforeid(string, required)keep_other_places(boolean, optional): true: leave only its first place for this one and keep its other places (the apps' drag); default: this becomes its only placeparent_name_or_id(string, optional): destination area, project or subproject; omit for standalone
move_to_anytime
Move an existing to-do to anytime: detach it from its project and clear its scheduled date, keeping its deadline and tags. It becomes a sorted, no-project, unscheduled to-do that lists in the anytime view (never back in the inbox). To keep its project and only clear the date, use update_todo with when: null. Resolve by id or exact title.
Needs todos:write
Arguments
id_or_title(string, required)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
move_todo
Reparent and/or reorder a to-do. parent = an area, project or subproject (areas hold to-dos), or "no project" / "none" / omitted for the to-dos with no project (listed FIRST on every page). position = "start" | "end" | a sibling to-do id to place it after. A move to ANOTHER parent, or the literal "no project", is a where answer and the to-do leaves the inbox for good; a reorder in place (omitted or "none" on a to-do that has no parent) is not an answer and changes nothing else. heading = a heading of the destination (id or name) to file it under, or "none" (also "null" or "") to take it out of its heading, so a heading literally named "none" must be given by its id here; omitted, a move to another parent clears its heading and a reorder in place keeps it. A heading with no parent named moves it into the heading’s project.
Needs todos:write
Arguments
heading(string, optional)id(string, required)parent(string, optional)position(string, optional)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
permanent_delete
Permanently delete a row that is IN THE TRASH, by id (from list_trash, or a row inside a trashed container). The irreversible hard-delete cascade: a container takes its whole subtree (child containers and to-dos, and the notes whose every place is inside it unless they are in a folder). Attachments are released: one that is also somewhere else stays there, and one with no other place is deleted with its stored file. A live row is refused: when the user asks to delete something for good, first trash it (trash_todo / trash_note / trash_container), then call this. Destructive, so it requires confirm: true.
Needs todos:write
Arguments
confirm(boolean, optional)id(string, required)
rename_heading
Rename a heading. heading = its id, or its exact name (pass project when the name is not unique).
Needs containers:write
Arguments
heading(string, required)name(string, required)project(string, optional)
rename_tag
Rename a tag, or merge it into another. Tags are identified by their (normalised, lower-case) name, so a rename MOVES the tag to the new name: every to-do, attachment, note and saved filter that used it is rewritten, and the old tag’s id keeps forwarding to the new tag. A change of case only is the same tag and changes nothing. If a tag with the new name already exists, the rename is a MERGE and is refused unless merge = true; a merge keeps the existing tag’s colour, and to-dos that carried both end up with one. Identify the tag by its current name (or its id).
Needs tags:write
Arguments
merge(boolean, optional): true to merge into an existing tag of that namenew_name(string, required): the new nametag(string, required): the tag to rename: its current name, or its id
restore_note_version
Put a note's text back to an older version. Nothing is lost: the current text is kept in the history first (as a restore version), so the user can go back again.
Needs notes:write
Arguments
note(string, required): the note idversion(string, required): the version id (list_note_versions)
restore_trashed
Restore a trashed root by id: this clears its trash stamp, and the row returns to its views untouched. For a container the whole subtree returns with it. A tag or a filter in the trash comes back the same way (a tag reappears on every to-do, note and attachment that kept its name).
Needs todos:write
Arguments
id(string, required)
search
Search everything: case-insensitive substring match across to-do titles/subtitles/descriptions/subtask titles/tags, container names/subtitles/descriptions, note titles/bodies/tags/folder names (an embed in a note by its name, never its id), inbox text/urls/titles, and attachment titles/urls/text. Excludes trashed rows and archived/trashed subtrees unless include_trashed is true: then trashed to-dos, notes and containers (or ones under a trashed container) come back with trashed: true (archived subtrees never do). Someday and completed rows are included. Each hit reports which field matched and its direct-parent crumb.
Needs todos:read containers:read
Arguments
include_trashed(boolean, optional): true = also return what is in the trash, each hit marked trashed: true (restore_trashed brings one back)query(string, required): text to search for
set_calendar_prefs
Change the calendar choices every device shares: show turns events in today and planned on or off; each entry of calendars sets one calendar’s colour ("#RRGGBB", or null for its own) and whether it shows. A calendar is named "<account>/<calendar>" as the system names them, for example "you@gmail.com/work" or "icloud/home". The calendars themselves live on each device; this only changes the choices.
Needs settings:write
Arguments
calendars(array of object, optional)show(boolean, optional)
set_reminder_defaults
Set the two reminder settings that sync with the account. default_time is the time a reminder gets when it is switched on ("HH:mm", 24-hour, the wall clock of whichever device fires it); pass null to restore the 09:00 default. overdue_nudge_time turns on ONE notification a day listing anything overdue, at that local time; pass null to turn it off, because the switch and the time are one value, so there is no "on at no time". Omit either argument to leave it alone. Returns both settings. ⚠ These are account-wide; whether a given device actually shows notifications is that device's own switch, which is local to it and not settable from here.
Needs settings:write
Arguments
default_time(string, optional): HH:mm, 24-hour; null restores the 09:00 defaultoverdue_nudge_time(string, optional): HH:mm, 24-hour = the daily overdue nudge is on at that time; null = off
set_week_start
Set the first day of the week (shared setting): 1 = Monday (the default), 7 = Sunday, null = Monday. It orders the weekday columns of the date picker in the apps and decides which day their date search offers for "next week". It changes NO view, no bucket and no count (planned is always the six days after today), and weekly recurrence stays Monday-anchored.
Needs settings:write
Arguments
weekStart(number, required): 1 = Monday, 7 = Sunday, null = Monday
subtask_to_todo
Turn a subtask into a to-do of its own (the apps’ make task): a new open to-do right after its parent, in the same project, heading and day; the subtask leaves the checklist.
Needs todos:write
Arguments
subtask(string, required): its id or exact titletodo(string, required)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
trash_container
Move an area/project/subproject (and, by exclusion, its whole subtree) to trash. Only this root row is stamped; restore_trashed brings the subtree back untouched. Auto-purged after 30 days. No confirm, because trash is the safety net.
Needs containers:write
Arguments
id_or_name(string, required)
trash_note
Move a note to trash, recoverably. It leaves every view and appears in list_trash, where restore_trashed brings it back and permanent_delete destroys it. Trash auto-purges after 30 days.
Needs notes:write
Arguments
id(string, required)
trash_note_folder
Move a note folder to the trash, recoverably: its subfolders and every note in them go with it. restore_trashed (with the folder id) brings them back (a note trashed on its own before stays in the trash); permanent_delete destroys the folder, its subfolders and every note in them.
Needs notes:write
Arguments
folder(string, required): the folder, by name or id
trash_todo
Move a to-do to trash. Recoverable via restore_trashed; auto-purged after 30 days. No confirm, because trash is the safety net. Resolve by id or exact title.
Needs todos:write
Arguments
id_or_title(string, required)
uncomplete_todo
Reopen a done to-do (clears completedAt). Resolve by id or exact title.
Needs todos:write
Arguments
id_or_title(string, required)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
unlink_note_task
Remove the link between a note and a to-do. Neither the note nor the to-do changes.
Needs notes:write
Arguments
note_id(string, required)todo_id(string, required)
unlink_notes
Remove the link between two notes. Neither note changes, and an embed of the other note in the text stays where it is.
Needs notes:write
Arguments
note(string, required): one note idother_note(string, required): the other note id
update_attachment
Rename an attachment, change a link’s url or a text attachment’s text, or set its tags (the WHOLE set, by name; [] clears them). A file keeps its extension in its title: keep it when you rename one.
Needs attachments:write
Arguments
attachment(string, required): its id, exact title or urltags(array of string, optional)text(string, optional)title(string, optional)url(string (uri), optional)
update_container
Edit an area/project/subproject. Pass only fields to change. description = the free text on the row itself, shown as // comment lines at the top of its page, or null to clear. It is NOT a note: a note is its own row. deadline accepts a date phrase / yyyy-MM-dd, or null to clear (areas have no deadline). priority = low|medium|high (a display-only ! mark; projects and subprojects only, and areas never carry it), or null to clear. subtitle/name/color (#RRGGBB) and symbol (its icon) editable too. archived = true archives it, false brings it back.
Needs containers:write
Arguments
archived(boolean, optional): true archives it (it and its contents leave the lists, kept as they are), false brings it back, as the apps’ archive doescolor(string, optional)deadline(string, optional)description(string, optional)id_or_name(string, required)name(string, optional)priority(low,medium,high, optional)subtitle(string, optional)symbol(string, optional): its icon: an SF Symbol name, unfilled (for example "folder", "list.bullet", "house", "cart"), or null for the default icon of its kindtz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
update_filter
Edit a saved filter: pass name and/or criteria (the same { v:2, match, criteria:[…] } shape as create_filter). criteria REPLACES the whole set including match. There is no way to add or drop a single criterion, because a partial edit of a rule set is how a filter ends up meaning something nobody chose. A criterion this build cannot parse is rejected. Resolve by id or exact name. Returns the filter and its new match count.
Needs filters:write
Arguments
criteria(object, optional): filter criteria v2: { v:2, match:"all"|"any", criteria:[ …criterion ] }id_or_name(string, required)name(string, optional)symbol(string, optional)tz(string, optional): IANA time zone for "today" and calendar-day grouping (for example Europe/Amsterdam). Default UTC.
update_inbox_item
Edit a capture waiting in the inbox: its text (a text capture or a captured note), url (a link), title, or its when (a date phrase or yyyy-MM-dd; null clears it), or move it in the inbox (position: "first", "last" or the id of the capture to put it after).
Needs inbox:write
Arguments
item(string, required): its id, or its exact text, title or urlposition(string, optional)text(string, optional)title(string, optional)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.url(string (uri), optional)when(string, optional)
update_note
Edit a note. Pass only what changes. title = the heading, or null to clear it; body replaces the text (may be "" when the note has a title: a note needs a title or a body). folder moves it to a folder (name or id), or null takes it out of its folder; pinned pins or unpins it; tags sets its tags exactly, add_tags / remove_tags change some. The note keeps a version history: the text before your edit stays readable with list_note_versions. Embeds you add to the body connect (a note link, a to-do link or a place). Places are attach_note / detach_note / move_note; linking to-dos is link_note_task, notes link_notes.
Needs notes:write
Arguments
add_tags(array of string, optional): tag names to addbody(string, optional)color(string, optional): a #RRGGBB colour, or null for none: a tint behind the note in the apps’ lists and cardsfolder(string, optional): a folder name or id, or null for no folderid(string, required)pinned(boolean, optional)remove_tags(array of string, optional): tag names to removetags(array of string, optional): the tags, exactly (names); [] or null clears themtitle(string, optional)
update_note_folder
Rename, recolour, change the icon of, move or reorder a note folder. Pass only what changes. color/symbol null resets to the default. inside: a top-level folder name or id to move it into, or null to move it to the top level (a folder that has folders inside it can only be at the top). position: where it goes among its siblings, "start", "end" or a sibling folder (name or id) to sit right after.
Needs notes:write
Arguments
color(string, optional)folder(string, required): the folder, by name or idinside(string, optional)name(string, optional)position(string, optional): "start", "end", or a sibling folder (name or id) to sit right aftersymbol(string, optional)
update_subtask
Rename, tick, untick or move one subtask. done: true ticks it (ticking the last one does not complete the to-do). position is "first" or the id or exact title of the subtask to put it after.
Needs todos:write
Arguments
done(boolean, optional)position(string, optional)subtask(string, required): its id or exact titletitle(string, optional)todo(string, required)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.
update_tag
Recolour a tag or move it in the tag list. color "#RRGGBB" or null for the default. position "first", "last", or the id or name of the tag to put it after. To rename or merge, use rename_tag.
Needs tags:write
Arguments
color(string, optional)position(string, optional)tag(string, required): its id or name
update_todo
Edit a to-do. Pass only fields to change. status = open|someday|done. status done completes it exactly as complete_todo does (a recurring to-do spawns its next occurrence), and open on a done to-do reopens it. Parking (status→someday) is timeline-free for EVERY to-do: it STRIPS whenDate + deadline to null but KEEPS the parent (a project idea parks with its project); a RECURRING to-do keeps its rule, DORMANT, while parked. A parked to-do given a when, a deadline, a repeat or a time comes out of someday (open, dated, listed on planned; a time with no when dates it today, a repeat with no when its first day); assigning only a parent leaves it parked. status=someday sent together with a when, a deadline, a time or a new repeat does NOT park it: the date wins and it is open, as the apps’ task form saves it (someday parks a repeating to-do only when its repeat is left as it is). status=open un-parks a recurring parked to-do with a new first date: the first day its rule allows from today on (schedule mode) or today (afterCompletion). parent = an area/project/subproject name or id (areas hold to-dos), or null for no project. no_project = true is the same "no project" answer, spelled as a flag. when/deadline = a date phrase / yyyy-MM-dd, or null to clear. A when (a date, or null = anytime), a parent (or null / no_project), and status someday are when/where answers: each takes the to-do out of the inbox for good. Tags, a deadline, a reminder or a priority do not. priority = low|medium|high (display-only ! mark), or null to clear. tags replaces the tag set. repeat = a rule to make it recurring (clears deadline, re-anchors to its whenDate; takes optional mode "schedule"|"afterCompletion" + optional until yyyy-MM-dd + optional count 1…999), or null to clear the rule. reminder = a local yyyy-MM-ddTHH:mm, or null to clear (on a to-do with several reminders it replaces the EARLIEST). time / duration_min / reminders edit its schedule: a new when moves every "before" reminder with it, clearing when drops the time and those reminders. subtasks replaces the whole checklist.
Needs todos:write
Arguments
color(string, optional)deadline(string, optional)description(string, optional)duration_min(integer, optional): The length in minutes, 5 to 1440 (it can exist without a time). null clears it.heading(string, optional): a HEADING of its project (id or exact name) to file it under, or null to take it out of its heading. Withoutparent, the heading’s project becomes its parent. Changingparentalone clears its heading.id(string, required)no_project(boolean, optional): true = the "no project" answer: no parent, sorted. Not with a non-null parent.parent(string, optional)priority(low,medium,high, optional)reminder(string, optional)reminders(array of object, optional): The WHOLE reminder list, at most 5 (replaces the current one; [] or null clears it). Do not combine withreminder.repeat(object, optional)status(open,someday,done, optional)subtasks(array of object, optional): The WHOLE checklist of subtasks, in order, at most 50 (replaces the current one; [] or null clears it). For one subtask use add_subtask / update_subtask / delete_subtask.subtitle(string, optional)tags(array of string, optional)time(string, optional): The start time, "HH:mm" on a 24-hour clock (local wall clock). On a to-do with no date it dates it today. null removes the time: the start AND the length go, and each "before" reminder becomes a fixed one at its old moment.title(string, optional)tz(string, optional): IANA time zone the user is in (for example Europe/Amsterdam): "today", "tomorrow" and weekdays are resolved in it. Default UTC. Pass it whenever you know the user's zone.when(string, optional)
upload_attachment
Attach a FILE to a to-do, project, area or note: a document you wrote (send text, for example the contents of notes.md or a CSV) or any file as base64 (content_base64). name is the filename WITH its extension (it decides how the apps show it). At most 2 MB through this tool; a bigger file (up to the apps' 100 MB) goes through the REST API: POST https://api.inittasks.com/v1/attachments/upload with the raw bytes as the body (devs.inittasks.com/attachments). An image/* type makes a picture; the apps show it without a preview until it is opened.
Needs attachments:write
Arguments
content_base64(string, optional): the file content as base64, for anything that is not textmime(string, optional): the media type; omitted, it is taken from the extensionname(string, required)place_type(todo,container,note, optional)tags(array of string, optional)text(string, optional): the file content as text (UTF-8)to(string, required)
Dates and time zones
Every tool that reads a date phrase ("tomorrow", "fri", "7 oct") or needs "today" takes an optional tz, an IANA zone such as Europe/Amsterdam. Without it the day is UTC's, so pass the user's zone: at 00:30 in Amsterdam, "today" in UTC is still yesterday. An unknown zone is refused, never silently replaced by UTC.
Deleting
delete_todo, delete_container and the trash_* tools move a row to the trash, where it stays restorable for 30 days, exactly as in the apps. permanent_delete and empty_trash act only on what is already in the trash, and both need confirm: true. So when a user asks to delete something for good, the assistant does two steps: trash it, then permanent_delete it.
Filing a capture
A capture is filed once. move_inbox_item on a capture that was already filed (or archived) is refused with a sentence naming what it became, so a retried call never makes a second to-do.
What a client cannot do
- Read or write anything outside the granted scopes. A tool whose scopes the connection lacks is not there at all, and the tools that span kinds check each row. See scopes.
- Write on a read-only grant. The write tools are not registered, so a call answers a tool result with
isError: true:MCP error -32602: Tool create_todo not found. - Change any permission. There is no tool that edits a key's or a connection's scopes, not another credential's and not its own. Permissions are edited in the user's own app, on a device that holds their key. A connection that could widen itself would be a connection with no limit.
- See the user's data after they revoke. The grant carried the key, and revoking ends it.
- Rely on a search index.
searchandlist_notesdecrypt the account for the call and match in memory; there is no index on the server to query. See encryption.
Permissions are read at connect
What a connection may do comes from the user's stored record of it, not from the token presented. So a user who edits an AI connection's permissions changes what it can do, the next time it connects. An open session keeps the tool set it started with, which is the honest behaviour for a long-lived connection: a tool list that changed underneath a client mid-conversation would be worse than one that changes at the door.
Next
- Building a client for the discovery documents and the one strict rule.