# Multies MCP tools

> Every tool the Multies MCP server at https://multies.si/api/v1/mcp offers (198 tools), generated from the server itself. Each tool names the API key scope it needs. Page: https://multies.si/developers/mcp

## Show only the tools a key can use

A key with limited scopes can hide the tools it can't use, so an agent's tool list stays short and every tool it sees will work.

- Per key: turn on "Show only the tools this key can use" when you create or edit a key in Settings, Developers. It is on by default for new keys with picked areas, and off for Read only keys and for keys made before it existed. Full access keys always see every tool. Over the API: `showOnlyUsableTools: true` on `POST` or `PATCH /api/developer/keys`.
- Per connection: add `?tools=scoped` to the MCP URL (`https://multies.si/api/v1/mcp?tools=scoped`), or send the header `X-Multies-Tools: scoped`. `?tools=all` shows every tool even when the key hides them. This works for API keys and for OAuth sign-ins: a read only sign-in then sees only read tools.
- A hidden tool is only hidden from `tools/list`. Calling it by name still gets the same `insufficient_scope` (or `read_only_key`) answer as before.
- To see a key's list without an MCP client: `GET https://multies.si/api/mcp-tools?view=key` with `Authorization: Bearer <key>`, or preview any scopes with `GET https://multies.si/api/mcp-tools?scope=mail:read+tasks:write`.

## Mail

### list_inboxes

The inboxes this key can use: agent inboxes (with their approval rules and today's sends) and, for workspace keys, the team's mailboxes.

Scope: `mail:read` (read only)

Example call:

```json
{"name":"list_inboxes","arguments":{}}
```

### list_threads

Recent threads, newest first, with sender, snippet, unread count and which agents took part.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `agentId` | string | no | Only this agent's inboxes. Agent keys always use their own. |
| `mailboxId` | string | no |  |
| `unread` | boolean | no | Only threads with unread mail. |
| `limit` | integer | no |  Default 20. |
| `split` | string | no | Only this Inbox tab: important, other, or one of your split ids (mail_split_list). |

Example call:

```json
{"name":"list_threads","arguments":{"limit":3}}
```

### read_thread

Every message in a thread: the new text with quoted history removed, one-time codes, links, attachments, who wrote it (agent, person or outside sender), and any reply waiting for approval.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |

Example call:

```json
{"name":"read_thread","arguments":{"threadId":"thr_0079meh8"}}
```

### search

Search subject, sender, recipients and body across the mail this key can read.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `query` | string | yes |  |
| `limit` | integer | no |  Default 10. |

Example call:

```json
{"name":"search","arguments":{"query":"invoice","limit":3}}
```

### search_everything

One search across mail, tasks (title, notes or a key like OPS-12), docs, chat, contacts and deals, grouped by type, newest first. Only what this key can open: an agent key sees its own inboxes and public channels.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string | yes |  |
| `types` | array of one of | no |  |
| `limit` | integer | no |  Default 5. |

Example call:

```json
{"name":"search_everything","arguments":{"q":"invoice","limit":3}}
```

### send_email

Send a new email as an agent inbox. Respects the agent's allowed recipients and daily cap. If the agent needs approval, the result is pending_approval and a person decides; do not resend.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `agentId` | string | no | Which agent sends. Not needed with an agent key. |
| `to` | array of string | yes |  |
| `cc` | array of string | no |  |
| `subject` | string | yes |  |
| `text` | string | yes | Plain text body. |

Example call:

```json
{"name":"send_email","arguments":{"agentId":"agt_0079e6a5","to":["ada@example.com"],"subject":"Your invoice 1042","text":"Hi Ada, here is invoice 1042. Thanks, Sam"}}
```

### reply

Reply to the latest message from the other side of a thread, threaded with a Re: subject, as an agent. Same rules as send_email.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |
| `text` | string | yes |  |
| `replyAll` | boolean | no |  Default false. |
| `agentId` | string | no | Which agent replies. Not needed with an agent key. |

Example call:

```json
{"name":"reply","arguments":{"threadId":"thr_0079meh8","agentId":"agt_0079e6a5","text":"Thanks Ada, the invoice is on its way."}}
```

### wait_for_email

Wait up to timeoutSeconds for new mail to an agent inbox (for example a sign up code), then return the new messages, parsed. Pass the cursor from the last call to avoid repeats.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `agentId` | string | no |  |
| `timeoutSeconds` | integer | no |  Default 25. |
| `cursor` | integer | no | The cursor returned by the previous call. |

Example call:

```json
{"name":"wait_for_email","arguments":{}}
```

### snooze_thread

Hide a thread from Inbox until a time; it comes back to the top of Inbox then. A new reply wakes it early.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |
| `preset` | one of: later_today, tomorrow, next_week | no | later_today: three hours on; tomorrow and next_week: 8:00 in the person's own time zone. |
| `at` | string | no | An exact time, ISO 8601 with a zone, e.g. 2026-11-02T09:00:00+11:00. |
| `local` | string | no | A wall clock time in the key owner's own time zone, e.g. 2026-11-02T09:00. |

Example call:

```json
{"name":"snooze_thread","arguments":{"threadId":"thr_0079meh8","preset":"tomorrow"}}
```

### schedule_send

Schedule a new email from an agent inbox for a later time. When due it is sent exactly like send_email: allowed recipients, daily cap and approval rules apply then. Cancel with cancel_scheduled.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `agentId` | string | no | Which agent sends. Not needed with an agent key. |
| `to` | array of string | yes |  |
| `cc` | array of string | no |  |
| `subject` | string | yes |  |
| `text` | string | yes | Plain text body. |
| `preset` | one of: later_today, tomorrow, next_week | no | later_today: three hours on; tomorrow and next_week: 8:00 in the person's own time zone. |
| `at` | string | no | An exact time, ISO 8601 with a zone, e.g. 2026-11-02T09:00:00+11:00. |
| `local` | string | no | A wall clock time in the key owner's own time zone, e.g. 2026-11-02T09:00. |

Example call:

```json
{"name":"schedule_send","arguments":{"agentId":"agt_0079e6a5","to":["ada@example.com"],"subject":"Friendly reminder","text":"Hi Ada, a quick reminder about invoice 1042.","preset":"tomorrow"}}
```

### list_scheduled

Snoozed threads, scheduled sends and reminders waiting for a reply, in the mailboxes this key can read.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `view` | one of: snoozed, scheduled | no |  Default "scheduled". |

Example call:

```json
{"name":"list_scheduled","arguments":{"view":"snoozed"}}
```

### cancel_scheduled

Cancel a scheduled send or reminder, or unsnooze a thread, by the id list_scheduled gave.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |

Example call:

```json
{"name":"cancel_scheduled","arguments":{"id":"id_8d7c6b5a"}}
```

### assign_thread

Gives a mail thread an owner: a workspace member (userId) who can open the thread's mailbox. They get a notification unless they assigned it to themselves. Pass userId null to unassign.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |
| `userId` | string | yes |  |

Example call:

```json
{"name":"assign_thread","arguments":{"threadId":"thr_0079meh8","userId":"usr_0079xdeo"}}
```

### unassign_thread

Takes the owner off a mail thread, so it shows under Unassigned again.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |

Example call:

```json
{"name":"unassign_thread","arguments":{"threadId":"thr_8d7c6b5a"}}
```

### set_thread_status

status done takes the thread out of the open lists (All, Mine, Unassigned) and records when; waiting means we replied and the customer has the ball (it shows under Waiting and goes back to open when they write); open brings it back.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |
| `status` | one of: open, waiting, done | yes |  |

Example call:

```json
{"name":"set_thread_status","arguments":{"threadId":"thr_0079meh8","status":"waiting"}}
```

### list_threads_by_view

Shared inbox threads, newest first, in one view: open (every open thread), mine (open and assigned to me), unassigned, assigned (to assignee, or to anyone), waiting (we replied, the customer has the ball), done, or all. Each thread carries its assignee and status. Pass before from nextCursor for the next page.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `view` | one of: all, open, mine, unassigned, assigned, waiting, done | no |  Default "open". |
| `assignee` | string | no | A user id, for the assigned, waiting and done views. |
| `mailboxId` | string | no |  |
| `before` | string | no |  |
| `limit` | integer | no |  Default 20. |

Example call:

```json
{"name":"list_threads_by_view","arguments":{}}
```

### get_reply_stats

First response and resolution times for threads whose first inbound message falls in the range (default the last 30 days, at most 90), per mailbox or per person, in calendar hours (milliseconds in the answer). At most 2,000 threads are scanned; sampled: true says the answer was cut.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `mailboxId` | string | no |  |
| `from` | string | no | ISO date or time. |
| `to` | string | no | ISO date or time. |
| `groupBy` | one of: mailbox, person | no |  Default "mailbox". |

Example call:

```json
{"name":"get_reply_stats","arguments":{}}
```

### list_thread_comments

Team only notes on a mail thread, oldest first, with who wrote each one and who it mentions, plus the teammates who can be mentioned. Notes are never part of read_thread or any mail that is sent.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |

Example call:

```json
{"name":"list_thread_comments","arguments":{"threadId":"thr_0079meh8"}}
```

### add_thread_comment

Adds a team only note to a mail thread. The outside sender never sees it. Mention teammates with "@Full Name" in the text or pass mentions (user ids or emails); mentioned people who can open the thread get a notification.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |
| `body` | string | yes |  |
| `mentions` | array of string | no | User ids or email addresses of teammates to notify. |

Example call:

```json
{"name":"add_thread_comment","arguments":{"threadId":"thr_0079meh8","body":"I'll take this one, the PDF is ready."}}
```

### delete_thread_comment

Deletes a note on a thread. Only the note's author, or a workspace key, can delete it.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |
| `commentId` | string | yes |  |

Example call:

```json
{"name":"delete_thread_comment","arguments":{"threadId":"thr_8d7c6b5a","commentId":"com_8d7c6b5a"}}
```

### get_thread_presence

People who have a shared inbox thread open right now and whether each is just viewing or writing a reply. Check it before replying so you don't answer on top of a teammate. Entries expire 40 seconds after the last heartbeat.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |

Example call:

```json
{"name":"get_thread_presence","arguments":{"threadId":"thr_8d7c6b5a"}}
```

### list_thread_drafts

Draft replies saved in a shared inbox thread, in mailboxes this key can open: who wrote each, when it was last saved, and a preview.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `threadId` | string | yes |  |

Example call:

```json
{"name":"list_thread_drafts","arguments":{"threadId":"thr_8d7c6b5a"}}
```

### take_over_draft

Makes the key's person the owner of a teammate's draft reply so they can finish and send it. The previous author is notified once, and their next save of that draft is refused instead of overwriting. Not for agent keys.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `draftId` | string | yes |  |

Example call:

```json
{"name":"take_over_draft","arguments":{"draftId":"dra_8d7c6b5a"}}
```

### list_snippets

The workspace's saved replies (shared ones plus your own private ones), by name, with their shortcut, subject and body. Bodies may hold variables: {{first_name}}, {{name}}, {{email}} (the recipient), {{my_name}}, {{my_first_name}}, {{company}} (the workspace), {{mailbox}} (the sending address), {{date}}. Use render_snippet to fill them in for a thread.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string | no | Filter by name, shortcut or text. |

Example call:

```json
{"name":"list_snippets","arguments":{}}
```

### render_snippet

Returns a saved reply's subject and body with its variables filled in. Pass threadId to address the thread's newest sender (the thread must be one you can open), or to for a new message. Nothing is sent: use the reply tools to send the text.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `snippetId` | string | yes |  |
| `threadId` | string | no |  |
| `to` | string | no | Recipient, e.g. "Grace Hopper <grace@example.com>". |
| `mailboxId` | string | no | The mailbox you will send from, for {{mailbox}}. |

Example call:

```json
{"name":"render_snippet","arguments":{"snippetId":"snp_007a5llr","threadId":"thr_0079meh8"}}
```

### create_snippet

Saves a reusable reply for the workspace. Plain text body; variables: {{first_name}}, {{name}}, {{email}} (the recipient), {{my_name}}, {{my_first_name}}, {{company}} (the workspace), {{mailbox}} (the sending address), {{date}}. Shared with the team unless shared is false.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `body` | string | yes |  |
| `subject` | string | no |  |
| `shortcut` | string | no | One word, used as /word in compose. Unique in the workspace. |
| `shared` | boolean | no |  |

Example call:

```json
{"name":"create_snippet","arguments":{"name":"Invoice sent","body":"Hi {{first_name}}, your invoice is attached. Thanks!","shortcut":"inv","shared":true}}
```

### mail_split_list

Your Inbox tabs: Important (mail from people, including verified first time senders), Other (newsletters, notifications, receipts), then your own splits, each with its unread count, plus each split's rules. Pass a tab id as split to list_threads.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `mailboxId` | string | no |  |

Example call:

```json
{"name":"mail_split_list","arguments":{}}
```

### mail_split_create

Adds a tab to your Inbox for mail that matches rules. Rules: fromContains, fromDomain (example.com), to (an address or a mailbox id), subjectContains, calendarInvite and fromTeammate (no value). match all (default) or any. leavesImportant (default true) takes matching mail out of Important and Other.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `rules` | array of object | yes |  |
| `match` | one of: all, any | no |  |
| `leavesImportant` | boolean | no |  |

Example call:

```json
{"name":"mail_split_create","arguments":{"name":"Follow up with Ada","rules":[{"field":"fromContains"}]}}
```

### mail_split_update

Renames, reorders or changes the rules of one of your splits. Rules: fromContains, fromDomain (example.com), to (an address or a mailbox id), subjectContains, calendarInvite and fromTeammate (no value). match all (default) or any. leavesImportant (default true) takes matching mail out of Important and Other.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `splitId` | string | yes |  |
| `name` | string | no |  |
| `rules` | array of object | no |  |
| `match` | one of: all, any | no |  |
| `leavesImportant` | boolean | no |  |
| `position` | integer | no |  |

Example call:

```json
{"name":"mail_split_update","arguments":{"splitId":"spl_8d7c6b5a"}}
```

### mail_split_delete

Removes one of your splits. Its mail goes back to Important or Other; no mail is deleted.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `splitId` | string | yes |  |

Example call:

```json
{"name":"mail_split_delete","arguments":{"splitId":"spl_8d7c6b5a"}}
```

### mail_read_status

Whether a sent message was opened: { tracked, opens, firstOpenAt, lastOpenAt }. tracked is false when the sender had read status off (Settings > Mail). Image blocking means a message can be read without showing as opened.

Scope: `mail:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `messageId` | string | yes |  |

Example call:

```json
{"name":"mail_read_status","arguments":{"messageId":"msg_8d7c6b5a"}}
```

### mail_bulk_action

Archive, snooze, move, mark read or unread, star, trash or delete up to 500 messages in one call. Each inverse undoes its action: inbox undoes archive or trash, unread undoes read, unsnooze undoes snooze. delete is forever. move needs to (a connected mailbox's folder key, "f:<path>"); snooze needs until (ISO time) or preset. Ids the key can't open are skipped.

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `ids` | array of string | yes |  |
| `action` | one of: read, unread, star, unstar, archive, inbox, spam, trash, delete, move, snooze, unsnooze | yes |  |
| `to` | string | no | For move: the folder key. |
| `until` | string | no | For snooze: when it comes back, ISO 8601 with a zone. |
| `preset` | one of: later_today, tomorrow, next_week | no | For snooze instead of until. |

Example call:

```json
{"name":"mail_bulk_action","arguments":{"ids":["id_8d7c6b5a"],"action":"read"}}
```

### mail_bulk_job

Archive, move to Inbox, spam, trash (delete; Undo restores), snooze (Undo clears it), move to a synced folder (Undo moves it back), mark read or unread, star or unstar EVERY message in a folder or search (up to 20000), as one job. Give your own job_id; calling again with the same job_id continues the job until status is "done" (each call does up to 900). Mail that arrived after max_received_at is left alone (default: now). undo: true puts back exactly what the job changed (repeat until "reverted").

Scope: `mail:send`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `job_id` | string | yes |  |
| `action` | one of: read, unread, star, unstar, archive, inbox, spam, trash, snooze, move | no | Needed to start a job. |
| `mailbox_id` | string | no | Needed to start a job. |
| `folder` | one of: inbox, archive, spam, trash, starred | no |  |
| `query` | string | no | A search instead of (or inside) a folder. |
| `exclude_ids` | array of string | no |  |
| `to` | string | no | move: the folder key, like "f:Projects". |
| `snooze_until` | string | no | snooze: ISO time the threads come back. |
| `snooze_preset` | one of: later_today, tomorrow, next_week | no |  |
| `max_received_at` | string | no | ISO time; later arrivals are left alone. |
| `undo` | boolean | no |  |

Example call:

```json
{"name":"mail_bulk_job","arguments":{"job_id":"job_8d7c6b5a"}}
```

## Tasks and projects

### my_work

What is waiting today for the person (or, with an agent key, the agent): tasks due today and overdue, mentions, mail threads on my tasks, approvals waiting and today's meetings.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `timeZone` | string | no | IANA zone for 'today', e.g. Australia/Sydney. Defaults to the person's or workspace's zone. |

Example call:

```json
{"name":"my_work","arguments":{"timeZone":"Australia/Sydney"}}
```

### list_tasks

Tasks in the workspace, filtered. assignee takes me, none, member:<id> or agent:<id>. Returns short rows; call get_task for the thread and comments.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | no |  |
| `status` | one of: todo, doing, done | no |  |
| `assignee` | string | no |  |
| `priority` | one of: none, low, medium, high, urgent | no |  |
| `label` | string | no |  |
| `q` | string | no |  |
| `threadId` | string | no | Tasks made from this email thread. |
| `limit` | integer | no |  Default 50. |
| `type` | one of: task, story, bug, epic | no | Only this type. |

Example call:

```json
{"name":"list_tasks","arguments":{"limit":3}}
```

### get_task

One task by id or reference (OPS-12): fields, subtasks, comments, the email thread it came from (newest text only) and its history.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |

Example call:

```json
{"name":"get_task","arguments":{"id":"TSK-1"}}
```

### next_task

The most urgent open task assigned to this agent, with its thread and comments, or null. Agents with their own key can call this in a loop: take the task, do it, comment, mark it done.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `agentId` | string | no | Not needed with an agent key. |

Example call:

```json
{"name":"next_task","arguments":{}}
```

### create_task

Create a task. Pass messageId or threadId to make it from an email: the title defaults to the subject and the task links to the thread.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | string | no | Required unless messageId or threadId is given. |
| `notes` | string | no |  |
| `projectId` | string | no |  |
| `status` | one of: todo, doing, done | no |  |
| `assignee` | string | no | member:<userId> or agent:<agentId>. Use "me" in list_tasks for your own. |
| `priority` | one of: none, low, medium, high, urgent | no |  |
| `due` | string | no | ISO date, e.g. 2026-10-31. |
| `labels` | array of string | no |  |
| `parentId` | string | no | Make it a subtask. |
| `messageId` | string | no |  |
| `threadId` | string | no |  |
| `type` | one of: task, story, bug, epic | no | task (default), story, bug or epic. Pass an epic's id as parentId to put the task in that epic. |
| `points` | number | no | The estimate, in the project's unit (points or hours). |
| `sprintId` | string | no | Put the task in a planned or active sprint of its project (see list_sprints). |

Example call:

```json
{"name":"create_task","arguments":{"title":"Follow up with Ada about invoice 1042","notes":"She asked for a PDF copy.","priority":"high","due":"2026-11-03","labels":["billing"]}}
```

### update_task

Change a task: status (todo, doing, done) or a project status id, assignee, priority, due date, labels, title, notes, type (task, story, bug, epic), estimate (points) or sprint (sprintId).

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `title` | string | no |  |
| `notes` | string | no |  |
| `status` | one of: todo, doing, done | no |  |
| `statusId` | string | no |  |
| `assignee` | string | no | member:<userId> or agent:<agentId>. Use "me" in list_tasks for your own. |
| `priority` | one of: none, low, medium, high, urgent | no |  |
| `due` | string | no |  |
| `labels` | array of string | no |  |
| `type` | one of: task, story, bug, epic | no | task, story, bug or epic. |
| `points` | number | no | The estimate in the project's unit; null clears it. |
| `sprintId` | string | no | Move to a sprint of the task's project; null moves it to the backlog. |

Example call:

```json
{"name":"update_task","arguments":{"id":"TSK-1","status":"doing","assignee":"member:usr_0079xdeo"}}
```

### comment_on_task

Add a comment to a task, for example what you did or what you need from a person.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `body` | string | yes |  |

Example call:

```json
{"name":"comment_on_task","arguments":{"id":"TSK-1","body":"Sent the PDF, waiting on Ada."}}
```

### list_projects

Projects with their ordered statuses (each in a todo, doing or done group) and task counts.

Scope: `tasks:read` (read only)

Example call:

```json
{"name":"list_projects","arguments":{}}
```

### start_timer

Start tracking time on a task (id or reference like OPS-12) as this agent. A timer already running stops first. Needs an agent key.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `note` | string | no |  |

Example call:

```json
{"name":"start_timer","arguments":{"taskId":"OPS-12"}}
```

### stop_timer

Stop this agent's running timer. Returns the entry with its seconds, or null if nothing was running.

Scope: `tasks:write`

Example call:

```json
{"name":"stop_timer","arguments":{}}
```

### log_time

Add minutes spent on a task (or a project) on a date (YYYY-MM-DD, default today). Workspace keys pass person (member:<id> or agent:<id>).

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | no |  |
| `projectId` | string | no |  |
| `minutes` | number | yes |  |
| `date` | string | no |  |
| `note` | string | no |  |
| `billable` | boolean | no |  |
| `person` | string | no |  |

Example call:

```json
{"name":"log_time","arguments":{"taskId":"tsk_007agkj7","minutes":25,"date":"2026-11-02","note":"Prepared the PDF","billable":true}}
```

### get_timesheet

Time per person and project, by day, for a date range (from, to as YYYY-MM-DD; default the last 8 days). Filter by person (me, member:<id>, agent:<id>) or project.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string | no |  |
| `to` | string | no |  |
| `person` | string | no |  |
| `projectId` | string | no |  |

Example call:

```json
{"name":"get_timesheet","arguments":{"from":"2026-10-27","to":"2026-11-03"}}
```

### set_task_blocked_by

Record that taskId can't start or finish until blockedBy is done (both ids or references). lagDays (optional, whole days -365 to 365) sets a wait after the blocker ends, or a lead when negative (the task may start that many days early); call again with a new lagDays to change it on an existing link. Pass remove: true to take the dependency off. Returns what blocks the task and what it blocks, each with lagDays.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `blockedBy` | string | yes |  |
| `remove` | boolean | no |  |
| `lagDays` | integer | no |  |

Example call:

```json
{"name":"set_task_blocked_by","arguments":{"taskId":"tsk_007aua70","blockedBy":"tsk_007agkj7"}}
```

### get_report

Numbers for the last N days (default 30): tasks by status and assignee, overdue tasks, tasks done per day, time per project and the deals pipeline in AUD.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `days` | integer | no |  |
| `projectId` | string | no |  |

Example call:

```json
{"name":"get_report","arguments":{"days":30}}
```

### list_people

Everyone in the workspace with title and bio: people (kind human), AI agent members (kind agent) and mail agents (with their inbox).

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | one of: human, agent | no |  |

Example call:

```json
{"name":"list_people","arguments":{}}
```

### list_custom_fields

The custom fields on a project with their type and, for select fields, their options (id and label). Currency is AUD.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |

Example call:

```json
{"name":"list_custom_fields","arguments":{"projectId":"prj_8d7c6b5a"}}
```

### create_custom_field

Types: text, number, currency (AUD), date, select, multiselect, person, checkbox, url, formula, rollup. Select types take option labels. A formula takes config { expression } (like {Budget} * 1.1); a rollup takes config { source, fn, field } (create_formula_field and create_rollup_field explain both).

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `name` | string | yes |  |
| `type` | one of: text, number, currency, date, select, multiselect, person, checkbox, url, formula, rollup | yes |  |
| `options` | array of string | no |  |
| `config` | object | no |  |

Example call:

```json
{"name":"create_custom_field","arguments":{"projectId":"prj_8d7c6b5a","name":"Follow up with Ada","type":"text"}}
```

### set_task_fields

values maps a field id or field name to a value. Text and URL: string. Number and currency (AUD): number. Date: YYYY-MM-DD. Select: option label or id. Multi select: list of labels. Person: member:<id> or agent:<id>. Checkbox: true or false. null clears.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `values` | object | yes |  |

Example call:

```json
{"name":"set_task_fields","arguments":{"taskId":"OPS-12","values":{}}}
```

### find_tasks_by_field

Tasks in a project whose field matches. op is eq, ne, gt, gte, lt, lte, contains, empty or notempty. Optionally sort by a field.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `fieldId` | string | yes |  |
| `op` | one of: eq, ne, gt, gte, lt, lte, contains, empty, notempty | no |  |
| `value` | string | no |  |
| `sortBy` | string | no |  |
| `desc` | boolean | no |  |

Example call:

```json
{"name":"find_tasks_by_field","arguments":{"projectId":"prj_8d7c6b5a","fieldId":"fie_8d7c6b5a"}}
```

### get_portfolio

Every project with owner, progress (percent done), overdue count, time logged, next due date and the health flag set by people (on_track, at_risk, off_track).

Scope: `tasks:read` (read only)

Example call:

```json
{"name":"get_portfolio","arguments":{}}
```

### set_project_health

Set the health flag on the portfolio: on_track, at_risk, off_track, or null to clear, with an optional short note.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `health` | one of | yes |  |
| `note` | string | no |  |

Example call:

```json
{"name":"set_project_health","arguments":{"projectId":"prj_8d7c6b5a","health":"on_track"}}
```

### update_project

Change a project's name, description, color or key. The key (letters and digits, up to 6) must be unique in the workspace without regard to case; a taken key is refused with key_taken and nothing changes.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `name` | string | no |  |
| `description` | string | no |  |
| `color` | string | no |  |
| `key` | string | no |  |

Example call:

```json
{"name":"update_project","arguments":{"projectId":"prj_8d7c6b5a"}}
```

### list_templates

Starter templates (client onboarding, content calendar, sales pipeline, bug tracker, meeting notes, project brief) and the workspace's saved ones.

Scope: `tasks:read` (read only)

Example call:

```json
{"name":"list_templates","arguments":{}}
```

### use_template

Creates a project (statuses, custom fields, tasks with due dates from startDate), a task in projectId for a task template, or a doc for a doc template.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `templateId` | string | yes |  |
| `name` | string | no |  |
| `projectId` | string | no |  |
| `startDate` | string | no |  |

Example call:

```json
{"name":"use_template","arguments":{"templateId":"tem_8d7c6b5a"}}
```

### create_template

kind project: data { project: { name, description? }, tasks: [{ title, notes?, priority?, dueInDays?, subtasks? }] }. kind task: data { title, notes?, subtasks? }. kind doc: data { title, text } with one paragraph per line, # headings and - bullets.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | one of: project, task, doc | yes |  |
| `name` | string | no |  |
| `description` | string | no |  |
| `data` | object | yes |  |

Example call:

```json
{"name":"create_template","arguments":{"kind":"project","data":{}}}
```

### set_task_repeat

freq daily, weekly, monthly or yearly; interval for every N; weekdays (0 Sunday to 6 Saturday) for weekly; monthDay for monthly; until YYYY-MM-DD. Finishing the task makes the next one. Pass freq none to stop.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `freq` | one of: daily, weekly, monthly, yearly, none | yes |  |
| `interval` | integer | no |  |
| `weekdays` | array of integer | no |  |
| `monthDay` | integer | no |  |
| `until` | string | no |  |

Example call:

```json
{"name":"set_task_repeat","arguments":{"taskId":"OPS-12","freq":"daily"}}
```

### list_goals

Every goal with its key results, progress (0 to 100, from numbers and linked tasks, rolled up through child goals), health and a summary.

Scope: `tasks:read` (read only)

Example call:

```json
{"name":"list_goals","arguments":{}}
```

### create_goal

A goal with optional key results. Key result kinds: number, currency (AUD), percent (start, target, current) or tasks (taskIds or projectId).

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `description` | string | no |  |
| `parentId` | string | no |  |
| `due` | string | no |  |
| `keyResults` | array of object | no |  |

Example call:

```json
{"name":"create_goal","arguments":{"name":"Get paid faster","description":"Cut the average days to payment.","due":"2026-12-31","keyResults":[{"name":"Average days to payment","kind":"number","start":30,"target":14,"current":21}]}}
```

### update_key_result

Set current (and optionally target) on a number, currency or percent key result, or replace the linked taskIds on a tasks key result.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `keyResultId` | string | yes |  |
| `current` | number | no |  |
| `target` | number | no |  |
| `taskIds` | array of string | no |  |

Example call:

```json
{"name":"update_key_result","arguments":{"keyResultId":"key_8d7c6b5a"}}
```

### list_notifications

The notifications inbox of the person who made this key (workspace keys only): mentions, assignments, comments, approvals and due-soon items.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `unread` | boolean | no |  |
| `category` | one of: mention, assignment, comment, approval, due_soon, chat, email, status | no |  |

Example call:

```json
{"name":"list_notifications","arguments":{"unread":true}}
```

### list_epics

Epics in the workspace or one project, each with progress: done of total over its items and their subtasks, percent, points when tasks carry points, and the date span of its items.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | no |  |

Example call:

```json
{"name":"list_epics","arguments":{}}
```

### get_epic

One epic by id or reference (OPS-7) with its progress and its items (stories, tasks and bugs).

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |

Example call:

```json
{"name":"get_epic","arguments":{"id":"id_8d7c6b5a"}}
```

### add_to_epic

Put tasks, stories or bugs in an epic (by id or reference). An item in another epic moves. Pass remove: true to take them out instead.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `epicId` | string | yes |  |
| `ids` | array of string | yes |  |
| `remove` | boolean | no |  |

Example call:

```json
{"name":"add_to_epic","arguments":{"epicId":"epi_8d7c6b5a","ids":["id_8d7c6b5a"]}}
```

### list_sprints

A project's sprints (planned, active, completed), oldest first, with task and point counts, and the project's estimate unit.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |

Example call:

```json
{"name":"list_sprints","arguments":{"projectId":"prj_007ajb9k"}}
```

### get_sprint

One sprint with its tasks and burndown: per day, the points (or tasks when nothing is estimated) left at the end of that day, and the ideal line.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `timeZone` | string | no | IANA zone for day lines. Defaults to the person's or workspace's zone. |

Example call:

```json
{"name":"get_sprint","arguments":{"id":"id_8d7c6b5a"}}
```

### create_sprint

Plan a sprint in a project. Defaults: Sprint N, starting the day after the last sprint ends (or today), two weeks long.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `name` | string | no |  |
| `goal` | string | no |  |
| `startAt` | string | no | ISO date or time, e.g. 2026-11-02. |
| `endAt` | string | no |  |

Example call:

```json
{"name":"create_sprint","arguments":{"projectId":"prj_007ajb9k","name":"Sprint 12","goal":"Close every open invoice","startAt":"2026-11-02","endAt":"2026-11-15"}}
```

### start_sprint

Start a planned sprint. A project has one active sprint at a time.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |

Example call:

```json
{"name":"start_sprint","arguments":{"id":"id_8d7c6b5a"}}
```

### complete_sprint

Complete the active sprint. Unfinished tasks carry over to the next planned sprint (made if there is none) or to the backlog. Done tasks stay.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `carryOver` | one of: next, backlog | no | Where unfinished tasks go. Default next. |

Example call:

```json
{"name":"complete_sprint","arguments":{"id":"id_8d7c6b5a"}}
```

### add_to_sprint

Move tasks into a planned or active sprint (from the backlog or another sprint).

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | The sprint id. |
| `taskIds` | array of string | yes | Task ids or references like OPS-12, up to 500, all in the sprint's project. |

Example call:

```json
{"name":"add_to_sprint","arguments":{"id":"id_8d7c6b5a","taskIds":["OPS-12"]}}
```

### remove_from_sprint

Move tasks out of a sprint, back to the project's backlog.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | The sprint id. |
| `taskIds` | array of string | yes | Task ids or references like OPS-12, up to 500, all in the sprint's project. |

Example call:

```json
{"name":"remove_from_sprint","arguments":{"id":"id_8d7c6b5a","taskIds":["OPS-12"]}}
```

### list_triage

New work waiting in Triage (from mail rules, public forms, incoming hooks or the API), newest first, before it becomes a normal task. Accept, decline or merge each one.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | no |  |
| `limit` | integer | no |  |

Example call:

```json
{"name":"list_triage","arguments":{}}
```

### triage_accept

Makes a Triage item a normal task, in the same step optionally setting its project, assignee (member:<userId> or agent:<agentId>), status, priority and due date.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `projectId` | string | no |  |
| `assignee` | string | no |  |
| `status` | one of: todo, doing, done | no |  |
| `priority` | one of: none, low, medium, high, urgent | no |  |
| `due` | string | no | ISO date or time, or null. |

Example call:

```json
{"name":"triage_accept","arguments":{"id":"id_8d7c6b5a"}}
```

### triage_decline

Declines and deletes a Triage item with an optional reason. reply: true also emails the sender a short polite note (skipped for no-reply addresses); message replaces the default text.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `reason` | string | no |  |
| `reply` | boolean | no |  |
| `message` | string | no |  |

Example call:

```json
{"name":"triage_decline","arguments":{"id":"id_8d7c6b5a"}}
```

### triage_merge

Folds a Triage item into an existing task: its notes become a comment on the target, its mail thread moves to the target when the target has none, and the item is deleted.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `targetId` | string | yes | The task id to merge into. |

Example call:

```json
{"name":"triage_merge","arguments":{"id":"id_8d7c6b5a","targetId":"tar_8d7c6b5a"}}
```

### create_triage_item

Puts new work in the Triage queue for a person to accept, instead of making a task straight away. from is an email address to reply to, if any. Without projectId it goes to the default project.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | string | yes |  |
| `notes` | string | no |  |
| `source` | one of: mail, form, api, chat | no |  |
| `from` | string | no |  |
| `projectId` | string | no |  |

Example call:

```json
{"name":"create_triage_item","arguments":{"title":"Follow up with Ada"}}
```

### list_checklist

The checklist items inside a task, in order, with total and done counts. taskId takes a task id or a reference like OPS-12.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |

Example call:

```json
{"name":"list_checklist","arguments":{"taskId":"tsk_007agkj7"}}
```

### add_checklist_items

Adds one or more checklist items to the end of a task's checklist (up to 200 per task). Each item can carry an assignee (member:<id> or agent:<id>) and a due date (YYYY-MM-DD).

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `items` | array of object | yes |  |

Example call:

```json
{"name":"add_checklist_items","arguments":{"taskId":"tsk_007agkj7","items":[{"title":"Export the PDF"},{"title":"Email it to Ada"}]}}
```

### update_checklist_item

Changes a checklist item: done (tick or untick), title, assignee (member:<id>, agent:<id> or null), due (YYYY-MM-DD or null).

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `itemId` | string | yes |  |
| `done` | boolean | no |  |
| `title` | string | no |  |
| `assignee` | string | no |  |
| `due` | string | no |  |

Example call:

```json
{"name":"update_checklist_item","arguments":{"itemId":"ite_8d7c6b5a"}}
```

### reorder_checklist

Puts a task's checklist in a new order. ids lists every item id of that checklist once.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `ids` | array of string | yes |  |

Example call:

```json
{"name":"reorder_checklist","arguments":{"taskId":"OPS-12","ids":["id_8d7c6b5a"]}}
```

### delete_checklist_item

Removes an item from its task's checklist.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `itemId` | string | yes |  |

Example call:

```json
{"name":"delete_checklist_item","arguments":{"itemId":"ite_8d7c6b5a"}}
```

### checklist_item_to_subtask

Creates a subtask of the item's task with the same title, assignee and due date, and removes the item from the checklist.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `itemId` | string | yes |  |

Example call:

```json
{"name":"checklist_item_to_subtask","arguments":{"itemId":"ite_8d7c6b5a"}}
```

### list_task_watchers

Who watches a task (they hear about new comments and status changes) and whether you do. taskId takes a task id or a reference like OPS-12.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |

Example call:

```json
{"name":"list_task_watchers","arguments":{"taskId":"OPS-12"}}
```

### watch_task

Starts watching a task: you (a member key) or the member named by userId (an agent key must name one). Watching twice changes nothing.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `userId` | string | no |  |

Example call:

```json
{"name":"watch_task","arguments":{"taskId":"tsk_007agkj7"}}
```

### unwatch_task

Stops watching a task: you (a member key) or the member named by userId.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `userId` | string | no |  |

Example call:

```json
{"name":"unwatch_task","arguments":{"taskId":"OPS-12"}}
```

### duplicate_task

Copies a task (new number, first to-do status) with its notes, assignee, priority, dates, labels, type, estimate, sprint, repeat rule and custom field values. By default also copies subtasks (3 levels, 200 tasks) and the checklist (unticked). Options: title (default "<title> (copy)"), projectId, subtasks, checklist, assignee, dependencies (copy "blocked by" links, default false).

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `title` | string | no |  |
| `projectId` | string | no |  |
| `subtasks` | boolean | no |  |
| `checklist` | boolean | no |  |
| `assignee` | boolean | no |  |
| `dependencies` | boolean | no |  |

Example call:

```json
{"name":"duplicate_task","arguments":{"taskId":"tsk_007agkj7","title":"Follow up with Grace about invoice 1043"}}
```

### search_tasks

Finds tasks with the task query language. Terms are ANDed, commas mean any of, a leading minus negates, quotes keep words together. Keys: assignee (me, none, a name or email), status (todo, doing, done, open or a status name), label, priority (urgent, high, medium, low, none; >= works), due (today, 2026-11-02, 7d, -3d, none; < and > work), sprint (current, next, none or a name), type (task, story, bug, epic), project (key or name), created and updated (a date or 7d meaning 7 days ago), points (>=3, none), has (subtasks, checklist, due, assignee, labels, points, parent, notes), is (overdue, open, done, unassigned, subtask, mine), title. Example: assignee:me status:doing label:bug due:<7d -label:wontfix "login page".

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string | yes |  |
| `projectId` | string | no |  |
| `limit` | integer | no |  Default 50. |

Example call:

```json
{"name":"search_tasks","arguments":{"q":"invoice","limit":3}}
```

### start_task_run

With an AI agent member's key: starts your run on a task you are assigned to or mentioned on (or claims a run a person queued for you), so your steps and result show on the task. moveToDoing moves the task to a doing status. With a person's or workspace key: queues a run for agentUserId. One queued or running run per agent and task. Returns the run; keep its id for add_run_step and finish_task_run.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes | A task id or a reference like OPS-12. |
| `moveToDoing` | boolean | no |  |
| `note` | string | no | An optional first step. |
| `agentUserId` | string | no | Only when queuing a run for an agent with a person's or workspace key. |

Example call:

```json
{"name":"start_task_run","arguments":{"taskId":"OPS-12"}}
```

### add_run_step

Appends one step to your run: kind is note, tool, comment, status_change; text up to 1000 characters. A run holds up to 200 steps. Only the run's own agent can log steps.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `runId` | string | yes |  |
| `kind` | one of: note, tool, comment, status_change | no |  Default "note". |
| `text` | string | yes |  |

Example call:

```json
{"name":"add_run_step","arguments":{"runId":"run_8d7c6b5a","text":"Example"}}
```

### finish_task_run

Finishes a run with status succeeded, failed or cancelled and a short result. moveTo moves the task to done or to its review status; comment posts the result as your comment on the task. A person's or workspace key can only cancel.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `runId` | string | yes |  |
| `status` | one of: succeeded, failed, cancelled | yes |  |
| `result` | string | no |  |
| `moveTo` | one of: done, review | no |  |
| `comment` | boolean | no |  |

Example call:

```json
{"name":"finish_task_run","arguments":{"runId":"run_8d7c6b5a","status":"succeeded"}}
```

### list_task_runs

With taskId: that task's runs, newest first, with steps and results. Without: runs across the workspace (no steps), filtered by agentUserId and status.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | no |  |
| `agentUserId` | string | no |  |
| `status` | one of: queued, running, succeeded, failed, cancelled | no |  |
| `limit` | integer | no |  |

Example call:

```json
{"name":"list_task_runs","arguments":{}}
```

### agent_run_cancel

Cancels a queued or running run so no agent picks it up or keeps working on it. A person's key, a full workspace key, or the run's own agent key can; another agent's key can't. reason (up to 500 characters) is kept as the run's result. A finished run is refused (run_finished); an already cancelled run comes back unchanged. Returns { run }.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `runId` | string | yes |  |
| `reason` | string | no |  |

Example call:

```json
{"name":"agent_run_cancel","arguments":{"runId":"run_8d7c6b5a"}}
```

### notification_list

Your notifications in a view: inbox (default: not done, not snoozed), later (snoozed) or done. Each item has doneAt and snoozedUntil; the answer has viewCounts { inbox, later, done } and unread (Inbox only).

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `view` | one of: inbox, later, done | no |  |
| `unread` | boolean | no |  |
| `category` | one of: mention, assignment, comment, approval, due_soon, chat, email, status | no |  |
| `limit` | integer | no |  |
| `before` | string | no |  |

Example call:

```json
{"name":"notification_list","arguments":{}}
```

### notification_done

Moves one notification (id) or many (ids, up to 500) out of the Inbox to Done and marks them read.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | no |  |
| `ids` | array of string | no |  |

Example call:

```json
{"name":"notification_done","arguments":{}}
```

### notification_undone

Clears done and any snooze on one notification.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |

Example call:

```json
{"name":"notification_undone","arguments":{"id":"id_8d7c6b5a"}}
```

### notification_snooze

Moves a notification to Later until a time: until (ISO, in the future, at most 90 days ahead) or preset later_today, tomorrow or next_week in your time zone. It comes back to the top of the Inbox, unread.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `until` | string | no |  |
| `preset` | one of: later_today, tomorrow, next_week | no |  |

Example call:

```json
{"name":"notification_snooze","arguments":{"id":"id_8d7c6b5a"}}
```

### catchup_get

A digest of a chat channel, task or doc since your last visit: counts (messages, replies, comments, edits, status and assignee changes, mentions of you), who did it, latest decisions and the newest items. Set markVisited to record this visit.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | one of: channel, task, doc | yes |  |
| `id` | string | yes |  |
| `markVisited` | boolean | no |  |

Example call:

```json
{"name":"catchup_get","arguments":{"type":"task","id":"tsk_007agkj7"}}
```

### get_counts

Your unread counts in one read: mail { inbox, important, other }, chat { unread, mentions }, notifications { unread }, triage (items waiting), tasks { dueToday, overdue } (assigned to you). tz is an IANA zone for due today (default UTC+10).

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `tz` | string | no |  |

Example call:

```json
{"name":"get_counts","arguments":{"tz":"Australia/Sydney"}}
```

### task_triage_list

Tasks waiting in Triage (from mail, forms, the API and agents), newest first, with the count. view: pending (default) or snoozed. Each item has triage { state, source, from, snoozedUntil }.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | no |  |
| `view` | one of: pending, snoozed | no |  |
| `limit` | integer | no |  |

Example call:

```json
{"name":"task_triage_list","arguments":{}}
```

### task_triage_action

action: accept (optional statusId, status, projectId, assignee member:<id> or agent:<id>), decline (optional reason), snooze (until: ISO date or date-time, at most a year out), unsnooze, duplicate (duplicateOf: the task id it repeats) or restore (undo an accept, decline or duplicate from the last day). comment: a one line note written with an accept or decline (the answer carries comment.id); pass that as commentId with restore to remove it in the same undo.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `action` | one of: accept, decline, snooze, unsnooze, duplicate, restore | yes |  |
| `statusId` | string | no |  |
| `status` | one of: todo, doing, done | no |  |
| `projectId` | string | no |  |
| `assignee` | string | no |  |
| `reason` | string | no |  |
| `until` | string | no |  |
| `duplicateOf` | string | no |  |
| `comment` | string | no |  |
| `commentId` | string | no |  |

Example call:

```json
{"name":"task_triage_action","arguments":{"id":"id_8d7c6b5a","action":"accept"}}
```

### check_task_schedule

Lists clashes along "blocked by" links: a task that starts before the last day of a task blocking it plus the link's lagDays (a negative lagDays is a lead). Each clash names both tasks, lagDays, how many days it must move and fix { taskId, start, due } (pass those to reschedule_task to clear it). With projectId the answer also has the project's schedule rules (workingDaysOnly, daysOff, strict). Done tasks never clash.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | no |  |

Example call:

```json
{"name":"check_task_schedule","arguments":{}}
```

### reschedule_task

Sets a task's start and/or due (YYYY-MM-DD; null clears). Unless moveDependents is false, the tasks waiting on it move too. Flexible (default): a waiting task that would now start too early (before a blocker's last day plus the link's lag) shifts later by just enough, keeping its length; moving earlier never pulls later tasks. Strict (the project's setting, or strict: true for this move): every waiting task moves by the same number of days, earlier or later. With working days only on, days off are skipped. preview: true returns the plan and changes nothing. At most 50 tasks move at once.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |
| `start` | string | no |  |
| `due` | string | no |  |
| `moveDependents` | boolean | no |  |
| `preview` | boolean | no |  |
| `strict` | boolean | no |  |

Example call:

```json
{"name":"reschedule_task","arguments":{"taskId":"OPS-12"}}
```

### set_project_schedule

workingDaysOnly: lead, lag and shifts count working days and a moved task never starts or ends on a day off (daysOff: week days 0 Sunday to 6 Saturday, default Saturday and Sunday). strict: moving a task by N days moves every task that waits on it by the same N days, earlier or later; off is the flexible rule (later only, just enough). Fields left out keep their value. check_task_schedule with projectId reads them.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `workingDaysOnly` | boolean | no |  |
| `daysOff` | array of integer | no |  |
| `strict` | boolean | no |  |

Example call:

```json
{"name":"set_project_schedule","arguments":{"projectId":"prj_8d7c6b5a"}}
```

### bulk_update_tasks

Apply one change to up to 500 tasks by id or reference (OPS-12): status (todo, doing, done) or a statusId, assignee, priority, due or start date (null clears), labels to add or remove, a type (task, story, bug), or a project to move them to. If any task is not in this workspace nothing is changed.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `ids` | array of string | yes |  |
| `status` | one of: todo, doing, done | no |  |
| `statusId` | string | no |  |
| `assignee` | string | no | member:<userId> or agent:<agentId>, or null for nobody. |
| `priority` | one of: none, low, medium, high, urgent | no |  |
| `dueAt` | string | no | ISO date, e.g. 2026-11-03. null clears. |
| `startAt` | string | no |  |
| `addLabels` | array of string | no |  |
| `removeLabels` | array of string | no |  |
| `projectId` | string | no | Move the tasks here; each status maps to the same group. |
| `type` | one of: task, story, bug | no | Set the type. Epics are changed one at a time with update_task. |

Example call:

```json
{"name":"bulk_update_tasks","arguments":{"ids":["id_8d7c6b5a"]}}
```

### get_workload

Open tasks and estimates per person (plus Unassigned) per week, Monday first, with a capacity flag. overloaded lists each person and week over capacity (default 20 points or 40 hours a week; pass capacity to change it). A task sits in the week of its due date, or its start date when it has none; overdue holds open tasks due before the range. Use from (a date) and weeks (1 to 12) to pick the range, for example from next Monday with weeks 1 for next week.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string | no | A date like 2026-11-02; the range starts on the Monday of its week. Default this week. |
| `weeks` | integer | no |  Default 4. |
| `projectIds` | array of string | no |  |
| `sprintId` | string | no |  |
| `people` | array of string | no | member:<id>, agent:<id> or none. |
| `unit` | one of: points, hours | no |  Default "points". |
| `capacity` | number | no |  |
| `tz` | string | no | An IANA zone; default the workspace zone. |
| `includeTasks` | boolean | no | Include each cell's task list; off by default to keep the answer short. Default false. |

Example call:

```json
{"name":"get_workload","arguments":{}}
```

### set_weekly_capacity

Stores how much one person (member:<id> or agent:<id>, from list_members or get_workload) can take on per week, in points and or hours. null clears a value back to the default (20 points, 40 hours); a value left out stays. get_workload then flags over capacity against it. Owners and admins can set anyone's; a member their own.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `person` | string | yes |  |
| `points` | number | no |  |
| `hours` | number | no |  |

Example call:

```json
{"name":"set_weekly_capacity","arguments":{"person":"member:usr_8d7c6b5a","points":20}}
```

### list_dashboards

Dashboards you can open (shared ones and your own), with their widget counts.

Scope: `tasks:read` (read only)

Example call:

```json
{"name":"list_dashboards","arguments":{}}
```

### list_dashboard_widget_types

Every dashboard widget type with what it shows, its group, the charts it can use, its default chart and size, the source it reads (savedViewId, projectId with filters, or mailboxId) and each setting it takes with the allowed values and the default. Use it before create_dashboard or add_dashboard_widget. Optional type returns one. Reads no data.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | one of: count, breakdown, due, completed, burndown, goals, reply_times, mail_volume, workload, calculation, battery, pivot, created_completed, task_list, time_tracked, note | no |  |

Example call:

```json
{"name":"list_dashboard_widget_types","arguments":{}}
```

### get_dashboard_data

Every widget's numbers for one dashboard in one call, computed now (counts, groups, due and overdue tasks, completed per week, sprint burndown, goal progress, reply times, mail per day, workload, calculations with trend and goal, battery, pivot tables, created vs completed, task lists, time tracked, notes). Writes nothing.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `dashboardId` | string | yes |  |
| `tz` | string | no |  |

Example call:

```json
{"name":"get_dashboard_data","arguments":{"dashboardId":"das_8d7c6b5a"}}
```

### create_dashboard

Make a dashboard with up to 24 widgets, or starter "team" for Team overview (tasks by status and by person, due this week, completed per week). Private unless shared is true; a dashboard made by an agent key is always shared.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | no |  |
| `shared` | boolean | no |  |
| `starter` | one of: team | no |  |
| `widgets` | array of object | no |  |

Example call:

```json
{"name":"create_dashboard","arguments":{"name":"Billing","starter":"team"}}
```

### add_dashboard_widget

Add one widget at the end of a dashboard. Use savedViewId to reuse a saved view's filters, or projectId and filters.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `dashboardId` | string | yes |  |
| `type` | one of: count, breakdown, due, completed, burndown, goals, reply_times, mail_volume, workload, calculation, battery, pivot, created_completed, task_list, time_tracked, note | yes | count (a number), breakdown (tasks grouped by groupBy), due (due this week and overdue), completed (per week, last 8 weeks), burndown (the project's active sprint), goals, reply_times, mail_volume (per day, 14 days), workload (per person, 4 weeks). R38: calculation (a number: tasks done or created, points done or hours tracked in range, sum or per day average, with a goal and the change against the previous range), battery (to do, in progress and done as one bar with the done percent), pivot (counts by groupBy rows and columnBy columns), created_completed (created vs completed per day or week in range), task_list (up to 10 tasks sorted by sort), time_tracked (hours per day or week in range and the top 5 people), note (text you write). |
| `title` | string | no |  |
| `groupBy` | one of: status, assignee, priority, project, sprint, type, label, mailbox, person | no | breakdown: status, assignee, priority, project, sprint, type or label. reply_times: mailbox or person. pivot rows: status, assignee, priority, project or type. |
| `columnBy` | one of: status, assignee, priority, project, type | no | pivot columns (default status; never the same as the rows). |
| `range` | one of: 7d, 30d, 90d, 180d | no | calculation, created_completed, time_tracked: the days ending today (default 30d). |
| `metric` | one of: done, created, points, hours | no | calculation: done, created, points or hours (default done). |
| `op` | one of: sum, avg | no | calculation: sum for the range or avg per day (default sum). |
| `goal` | number | no | calculation: a target; the data carries progress in percent. |
| `sort` | one of: due, priority, updated | no | task_list: due, priority or updated (default due). |
| `text` | string | no | note: the text to show. |
| `chart` | one of: number, bar, donut, line, table | no |  |
| `size` | number | no |  |
| `savedViewId` | string | no | Apply a saved view's filters and project. |
| `projectId` | string | no |  |
| `mailboxId` | string | no |  |
| `filters` | object | no |  |

Example call:

```json
{"name":"add_dashboard_widget","arguments":{"dashboardId":"das_8d7c6b5a","type":"count"}}
```

### get_computed_fields

With taskId (an id or a reference like OPS-12): each formula and rollup field on the task's project with its value. With projectId: the project level rollups over its tasks. A value that can't be worked out is "#ERROR" with an error message. Computed when read; nothing is stored.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | no |  |
| `projectId` | string | no |  |

Example call:

```json
{"name":"get_computed_fields","arguments":{}}
```

### create_formula_field

A read only field worked out from other values, like {Budget} * 1.1 or if({points} > 5, "big", "small"). Field names go in braces; built ins: points, due, start, created, completed, status, priority, title, assignee. Functions: if, round, floor, ceil, abs, min, max, sum, concat, len, upper, lower, days_between, today, now, date_add, is_empty, coalesce. Up to 500 characters.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `name` | string | yes |  |
| `expression` | string | yes |  |

Example call:

```json
{"name":"create_formula_field","arguments":{"projectId":"prj_8d7c6b5a","name":"Follow up with Ada","expression":"Example"}}
```

### create_rollup_field

Aggregates child tasks: source subtasks (a task's subtasks), epic_children (an epic's items and their subtasks) or project (one value over the whole project, shown in its header). fn: sum, count, count_done, average, min, max or percent_done. field: points, or a number, currency or formula field id or name (not needed for count, count_done and percent_done).

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `name` | string | yes |  |
| `source` | one of: subtasks, epic_children, project | yes |  |
| `fn` | one of: sum, count, count_done, average, min, max, percent_done | yes |  |
| `field` | string | no |  |

Example call:

```json
{"name":"create_rollup_field","arguments":{"projectId":"prj_8d7c6b5a","name":"Follow up with Ada","source":"subtasks","fn":"sum"}}
```

### list_saved_views

Saved views you can open (shared ones and your own), optionally for one project: id, name, view type and filters.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | no |  |

Example call:

```json
{"name":"list_saved_views","arguments":{}}
```

### create_saved_view

Save a view of tasks for people to open: view board, list, calendar, timeline, sprints or workload, an optional projectId, and filters (assignee, status, priority, label, type, due, q). Shared with the workspace unless shared is false; a view made by a key with no person behind it is always shared.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `view` | one of: board, list, calendar, timeline, sprints, workload | yes |  |
| `projectId` | string | no |  |
| `filters` | object | no |  |
| `shared` | boolean | no |  |

Example call:

```json
{"name":"create_saved_view","arguments":{"name":"Follow up with Ada","view":"board"}}
```

### delete_saved_view

Remove a saved view by id. Tasks are not touched.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `viewId` | string | yes |  |

Example call:

```json
{"name":"delete_saved_view","arguments":{"viewId":"vie_8d7c6b5a"}}
```

### get_board_settings

A project board's swimlanes (none, assignee, epic, priority or project) and column limits: { [statusId]: { max, min } }.

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |

Example call:

```json
{"name":"get_board_settings","arguments":{"projectId":"prj_8d7c6b5a"}}
```

### set_board_settings

Change a project board: swimlanes, the whole limits map (replaces it), or one column's limit with column { id (a status id), max, min } where null clears. Limits are whole numbers 1 to 999. Cards can still go into a full column; the board shows it as over the limit.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `swimlanes` | one of: none, assignee, epic, priority, project | no |  |
| `limits` | object | no |  |
| `column` | object | no |  |

Example call:

```json
{"name":"set_board_settings","arguments":{"projectId":"prj_8d7c6b5a"}}
```

### list_task_comments

Every comment on a task (id or reference like MB-12), oldest first, with its author and editedAt (null until edited).

Scope: `tasks:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `taskId` | string | yes |  |

Example call:

```json
{"name":"list_task_comments","arguments":{"taskId":"tsk_007agkj7"}}
```

### edit_task_comment

Replaces the text of a comment you wrote (fix a typo or a wrong number). The comment then shows as edited.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `commentId` | string | yes |  |
| `body` | string | yes |  |

Example call:

```json
{"name":"edit_task_comment","arguments":{"commentId":"com_8d7c6b5a","body":"Example"}}
```

### delete_task_comment

Deletes a task comment. The author, an owner or an admin can.

Scope: `tasks:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `commentId` | string | yes |  |

Example call:

```json
{"name":"delete_task_comment","arguments":{"commentId":"com_8d7c6b5a"}}
```

## Chat

### list_channels

Public chat channels in the workspace with their topic and last message.

Scope: `chat:read` (read only)

Example call:

```json
{"name":"list_channels","arguments":{}}
```

### read_channel

Recent top level messages in a channel, oldest first, with mentions, links, attachments and reply counts. Pass since (ISO time) to get only newer or changed messages.

Scope: `chat:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `channelId` | string | yes |  |
| `limit` | integer | no |  |
| `since` | string | no |  |

Example call:

```json
{"name":"read_channel","arguments":{"channelId":"chn_007bg81w","limit":3}}
```

### read_chat_thread

A top level chat message and all its replies.

Scope: `chat:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `messageId` | string | yes |  |

Example call:

```json
{"name":"read_chat_thread","arguments":{"messageId":"msg_8d7c6b5a"}}
```

### post_message

Post a message in a public channel, or reply in a thread with parentId. Mention a person with <@member:USER_ID> (ids from list_assignees or get_task), link a task with <#task:ID> or an email thread with <#thread:ID>. Chat stays inside the workspace, so it needs no approval.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `channelId` | string | yes |  |
| `body` | string | yes |  |
| `parentId` | string | no |  |

Example call:

```json
{"name":"post_message","arguments":{"channelId":"chn_007bg81w","body":"Standup: invoices sent, 2 follow ups today, nothing blocked."}}
```

### message_to_task

Make a task from a chat message. The task links back to the message and the message shows the task. Set triage: true to send it to the Triage queue instead.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `messageId` | string | yes |  |
| `title` | string | no |  |
| `projectId` | string | no |  |
| `assignee` | string | no |  |
| `triage` | boolean | no |  |

Example call:

```json
{"name":"message_to_task","arguments":{"messageId":"chm_007biys9","title":"Check the 2 invoice follow ups"}}
```

### pin_message

Pins a top level chat message to the top of its channel (pinned: true) or unpins it (pinned: false). Use it for a channel's welcome, rules or key links.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `messageId` | string | yes |  |
| `pinned` | boolean | no |  Default true. |

Example call:

```json
{"name":"pin_message","arguments":{"messageId":"chm_007biys9","pinned":true}}
```

### react_to_chat_message

Adds an emoji reaction to a chat message or thread reply in a public channel, or takes it off when this key already reacted with that emoji. Send one emoji character. The answer has the message's reactions with counts.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `messageId` | string | yes |  |
| `emoji` | string | yes |  |

Example call:

```json
{"name":"react_to_chat_message","arguments":{"messageId":"chm_007biys9","emoji":"👍"}}
```

### chat_typing

Shows "<name> is typing" to people who have the channel open, for about 6 seconds. Call again every 3 seconds or so while you write. Nothing is stored. Answers { ok, sent }; sent is false when called faster than every 3 seconds.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `channelId` | string | yes |  |

Example call:

```json
{"name":"chat_typing","arguments":{"channelId":"chn_8d7c6b5a"}}
```

### create_report

Reports a chat message (targetType message, messageId) or a person (targetType user, userId) to the Multies team. reason: spam, harassment, hate, sexual, violence, self_harm or other; note up to 500 characters; context chat, meeting or dm. Answers { id, status: open }. 20 a day.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `targetType` | one of: message, user | yes |  |
| `messageId` | string | no |  |
| `userId` | string | no |  |
| `context` | one of: chat, meeting, dm | no |  |
| `reason` | one of: spam, harassment, hate, sexual, violence, self_harm, other | yes |  |
| `note` | string | no |  |

Example call:

```json
{"name":"create_report","arguments":{"targetType":"message","reason":"spam"}}
```

### list_blocks

The people this key's owner blocked: { blocks: [{ userId, name, avatarUrl, createdAt }] }.

Scope: `chat:read` (read only)

Example call:

```json
{"name":"list_blocks","arguments":{}}
```

### add_block

Blocks a person (userId): their chat messages are hidden from you and they can't message you. They are not told. Answers { blocked, created, blocks }.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `userId` | string | yes |  |

Example call:

```json
{"name":"add_block","arguments":{"userId":"usr_8d7c6b5a"}}
```

### remove_block

Unblocks a person (userId). Answers { ok: true }, or not_found when you had not blocked them.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `userId` | string | yes |  |

Example call:

```json
{"name":"remove_block","arguments":{"userId":"usr_8d7c6b5a"}}
```

### edit_chat_message

Replaces the text of a chat message you posted, with the same markup as post_message. The message then shows as edited.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `messageId` | string | yes |  |
| `body` | string | yes |  |

Example call:

```json
{"name":"edit_chat_message","arguments":{"messageId":"msg_8d7c6b5a","body":"Example"}}
```

### delete_chat_message

Deletes a chat message. The author, an owner or an admin can. Replies keep their place under a deleted placeholder.

Scope: `chat:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `messageId` | string | yes |  |

Example call:

```json
{"name":"delete_chat_message","arguments":{"messageId":"msg_8d7c6b5a"}}
```

## Docs and forms

### search_docs

Find docs by words in the title or text.

Scope: `docs:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string | no |  |
| `projectId` | string | no |  |

Example call:

```json
{"name":"search_docs","arguments":{"q":"billing"}}
```

### read_doc

A doc's plain text, title and links.

Scope: `docs:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |

Example call:

```json
{"name":"read_doc","arguments":{"id":"doc_007bog8z"}}
```

### create_doc

Write a doc from plain text (one paragraph per line, # for headings, - for bullets), optionally linked to a task, project, thread or contact.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | string | yes |  |
| `text` | string | yes |  |
| `taskId` | string | no |  |
| `projectId` | string | no |  |
| `contactId` | string | no |  |
| `threadId` | string | no |  |

Example call:

```json
{"name":"create_doc","arguments":{"title":"Billing playbook","text":"# Billing playbook\n\nSend invoices on the 1st. Follow up after 7 days."}}
```

### append_to_doc

Add text to the end of a doc without rewriting it.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `text` | string | yes |  |

Example call:

```json
{"name":"append_to_doc","arguments":{"id":"doc_007bog8z","text":"Escalate to the account owner after 14 days."}}
```

### list_forms

Public forms in this workspace, with their links and how many times each was submitted.

Scope: `docs:read` (read only)

Example call:

```json
{"name":"list_forms","arguments":{}}
```

### create_form

A public form whose submissions become tasks (target task) or contacts (target contact). Fields: label, type (text, email, textarea, phone, select, number, date), required, options for select. Returns the public link.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `description` | string | no |  |
| `target` | one of: task, contact | no |  |
| `projectId` | string | no |  |
| `fields` | array of object | no |  |

Example call:

```json
{"name":"create_form","arguments":{"name":"Billing question","description":"Ask us anything about your invoice.","target":"task","fields":[{"label":"Email","type":"email","required":true},{"label":"Question","type":"textarea","required":true}]}}
```

### docs_append

Adds a section to the end of a doc and keeps everything already there. markdown takes headings, paragraphs, bullet, numbered and task lists, quotes, code, bold, italic, strike and links. Pass ifVersion (the version read_doc gave you) to fail with version_conflict instead of writing if the doc changed since.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `markdown` | string | yes |  |
| `ifVersion` | integer | no |  |

Example call:

```json
{"name":"docs_append","arguments":{"id":"id_8d7c6b5a","markdown":"Example"}}
```

### form_logic_set

Shows a question only when conditions on EARLIER questions hold, and sets its answer rules. logic: { join: "all" | "any", conditions: [{ field: <question id>, op: is | is_not | contains | answered | not_answered | gt | lt, value }] }, null clears it. rules: minLength, maxLength (text), min, max (number), minSelected, maxSelected (multiselect), pattern and patternMessage (text, phone); null clears them. A hidden question is never required. Loops, a question depending on itself or on a later question answer validation_failed. Question ids come from list_forms.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `formId` | string | yes |  |
| `fieldId` | string | yes |  |
| `logic` | object | no |  |
| `rules` | object | no |  |
| `required` | boolean | no |  |

Example call:

```json
{"name":"form_logic_set","arguments":{"formId":"for_8d7c6b5a","fieldId":"fie_8d7c6b5a"}}
```

### form_results

A form's results: total responses, a summary per question (counts per option for choices, average/min/max for numbers, latest answers for text) and the newest responses with their answers keyed by question id. from and to (YYYY-MM-DD) filter by day, q searches answers, limit is how many responses to return (up to 50).

Scope: `docs:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `formId` | string | yes |  |
| `from` | string | no |  |
| `to` | string | no |  |
| `q` | string | no |  |
| `limit` | integer | no |  |

Example call:

```json
{"name":"form_results","arguments":{"formId":"for_8d7c6b5a"}}
```

### list_doc_versions

Saved versions of a doc, newest first: id, docVersion, title, name, reason (edit or restore), words, author { type, name } and savedAt, plus the page now (version, words, editedBy). A version is kept when a new editing session starts (10 minutes after the last save, or someone else edits), when someone saves one, and before every restore; the newest 50 unnamed ones per doc are kept, named ones always. Pass an id to read_doc_version to see it and what changed since.

Scope: `docs:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `docId` | string | yes |  |
| `limit` | integer | no |  |

Example call:

```json
{"name":"list_doc_versions","arguments":{"docId":"doc_8d7c6b5a"}}
```

### read_doc_version

One version's title and plain text (content: true adds the Tiptap JSON), and sinceThen { added, removed, titleChanged }: the lines added and removed between that version and the page now. diff: true adds the line diff (type same, add or del; at most 2,000 lines).

Scope: `docs:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `docId` | string | yes |  |
| `versionId` | string | yes |  |
| `diff` | boolean | no |  |
| `content` | boolean | no |  |

Example call:

```json
{"name":"read_doc_version","arguments":{"docId":"doc_8d7c6b5a","versionId":"ver_8d7c6b5a"}}
```

### save_doc_version

Keeps the page as it is now under a name (up to 80 characters; left out: "Version N"), for example before a big rewrite. Named versions are never pruned. One row written.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `docId` | string | yes |  |
| `name` | string | no |  |

Example call:

```json
{"name":"save_doc_version","arguments":{"docId":"doc_8d7c6b5a"}}
```

### restore_doc_version

Puts a doc back to a saved version (title and content). The page as it is now is saved first as a version (reason restore), so the restore can be undone by restoring that one. ifVersion (the doc version you read) makes it fail with version_conflict if the doc changed since. Two rows written.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `docId` | string | yes |  |
| `versionId` | string | yes |  |
| `ifVersion` | integer | no |  |

Example call:

```json
{"name":"restore_doc_version","arguments":{"docId":"doc_8d7c6b5a","versionId":"ver_8d7c6b5a"}}
```

### docs_add_block

Adds one block to the end of a doc and keeps everything already there. type table takes rows (an array of rows of cell text; the first row is the header unless header is false). type image takes an https url and alt text. type callout takes text (markdown) and a variant: info, success, warning or danger. Pass ifVersion to fail with version_conflict if the doc changed since you read it.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `type` | one of: table, image, callout | yes |  |
| `rows` | array of array of string | no |  |
| `header` | boolean | no |  |
| `url` | string | no |  |
| `alt` | string | no |  |
| `text` | string | no |  |
| `variant` | one of: info, success, warning, danger | no |  |
| `ifVersion` | integer | no |  |

Example call:

```json
{"name":"docs_add_block","arguments":{"id":"id_8d7c6b5a","type":"table"}}
```

### get_doc_tree

The workspace's docs as a tree of pages and sub pages (id, title, parentId, position, depth, children). Pages nest at most 6 levels deep. Use flat: true for one line per page with its depth instead.

Scope: `docs:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `flat` | boolean | no |  Default false. |

Example call:

```json
{"name":"get_doc_tree","arguments":{"flat":true}}
```

### move_doc

Puts a doc under another page (parentId, or null for the top level) and, optionally, right before or after a sibling (beforeId or afterId). With neither it goes last. A page can't go under itself or its own sub pages; 6 levels at most.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `docId` | string | yes |  |
| `parentId` | string | no |  |
| `beforeId` | string | no |  |
| `afterId` | string | no |  |

Example call:

```json
{"name":"move_doc","arguments":{"docId":"doc_8d7c6b5a"}}
```

### get_backlinks

Lists the docs whose body links to a doc or a task (task id or ref like OPS-12), newest first, with a short snippet of the text around each link.

Scope: `docs:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | one of: doc, task | yes |  |
| `id` | string | yes |  |

Example call:

```json
{"name":"get_backlinks","arguments":{"type":"doc","id":"id_8d7c6b5a"}}
```

### create_share_link

Makes a link anyone can open without signing in: a doc (kind doc) read only, or a project's board (kind project_board) with its columns, card titles, assignee initials, due dates and labels; never notes, comments, files or custom fields. expiresInDays 7 or 30, or leave it out for never. showWorkspaceName (default true) shows the workspace name on the page. The url is shown only this once. Writes one row.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | one of: doc, project_board | yes |  |
| `targetId` | string | yes | The doc id, or the project id for a board. |
| `expiresInDays` | number | no |  |
| `showWorkspaceName` | boolean | no |  |

Example call:

```json
{"name":"create_share_link","arguments":{"kind":"doc","targetId":"tar_8d7c6b5a"}}
```

### list_share_links

Active share links (not revoked, not expired), newest first, for one doc or project when kind and targetId are given. Links never show their token again.

Scope: `docs:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | one of: doc, project_board | no |  |
| `targetId` | string | no |  |

Example call:

```json
{"name":"list_share_links","arguments":{}}
```

### revoke_share_link

Stops a share link at once; its page then says the link is no longer active.

Scope: `docs:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | The link id (shl_...). |

Example call:

```json
{"name":"revoke_share_link","arguments":{"id":"id_8d7c6b5a"}}
```

## Calendar and meetings

### list_meetings

Video meetings, newest first, with their guest links.

Scope: `calendar:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `upcoming` | boolean | no |  |

Example call:

```json
{"name":"list_meetings","arguments":{"upcoming":true}}
```

### schedule_meeting

Schedule a video meeting, optionally from a thread, task or contact (which fills in the title and guests). With sendInvites the calendar invite is emailed as the agent; it may wait for a person to approve it, and the result says so.

Scope: `calendar:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | string | no |  |
| `startsAt` | string | no | ISO date and time. Default now. |
| `durationMin` | integer | no |  |
| `sourceType` | one of: thread, task, contact | no |  |
| `sourceId` | string | no |  |
| `invitees` | array of string | no |  |
| `sendInvites` | boolean | no |  |
| `agentId` | string | no | Workspace keys: the agent inbox the invite is sent from. |
| `repeats` | string | no | A weekly series as an RRULE, e.g. FREQ=WEEKLY;INTERVAL=1;BYDAY=MO;COUNT=10 (weekly only, interval 1 or 2). Kept in the workspace time zone. |

Example call:

```json
{"name":"schedule_meeting","arguments":{"title":"Invoice review with Ada","startsAt":"2026-11-04T23:00:00.000Z","durationMin":30,"invitees":["ada@example.com"],"sendInvites":false}}
```

### delete_meeting

Delete a meeting (a series goes as a whole). Its notes, action items and transcript go with it. Sends meeting.deleted. To keep it on record, set status cancelled with the REST PATCH instead.

Scope: `calendar:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |

Example call:

```json
{"name":"delete_meeting","arguments":{"id":"id_8d7c6b5a"}}
```

### get_meeting_notes

A meeting's title, time and attendees with its notes doc as plain structure: agenda lines, notes lines, and action items (each with title, assignee, due date and, once made, its task). doc is null when no notes were taken yet. summary is null unless a recording summary exists.

Scope: `calendar:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `meetingId` | string | yes |  |

Example call:

```json
{"name":"get_meeting_notes","arguments":{"meetingId":"mtg_8d7c6b5a"}}
```

### create_action_items

With no items: every unchecked action item in the meeting's notes that is not a task yet becomes a task (assignee and due date read from "@Name" and "due Fri" style text). With items: each is added to the notes' action items and made a task. Items already made into tasks are skipped, so calling twice creates nothing new. Each task links back to the meeting. Returns the tasks created.

Scope: `calendar:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `meetingId` | string | yes |  |
| `items` | array of object | no |  |
| `projectId` | string | no | Defaults to the meeting's source task's project, else the workspace's first project. |

Example call:

```json
{"name":"create_action_items","arguments":{"meetingId":"mtg_8d7c6b5a"}}
```

### get_meeting_transcript

The recordings of a meeting, newest first: status (recording, processing, done or failed), who recorded, duration in seconds, the summary, action items [{ text, assignee, due }] and the transcript text (capped at 200 KB; truncated says when it was cut). Calls are recorded and transcribed with the workspace's own speech to text key; Multies keeps the text, not the audio.

Scope: `calendar:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `meetingId` | string | yes |  |

Example call:

```json
{"name":"get_meeting_transcript","arguments":{"meetingId":"mtg_8d7c6b5a"}}
```

### get_call_status

Live status of calls: pass channelId for the calls started in a channel in the last 6 hours (live, waiting or ended, with who is in each), or meetingId for one meeting. enabled is false when video is off for the workspace. Keys can't open DMs or private channels.

Scope: `calendar:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `channelId` | string | no |  |
| `meetingId` | string | no |  |

Example call:

```json
{"name":"get_call_status","arguments":{}}
```

### get_call_minutes

The workspace's call participant-minutes this calendar month (two people for 30 minutes is 60) against its cap: { used, cap, remaining, percent, warn, period, resetsOn }. cap is null when there is no limit (paid plans). Free workspaces get 1,000; new calls are refused once it is used up, and a running call is never cut off.

Scope: `calendar:read` (read only)

Example call:

```json
{"name":"get_call_minutes","arguments":{}}
```

### meeting_summary_so_far

For a live call or meeting: who is in it and since when, minutes elapsed, the notes doc's headings and to-dos, and decisions said in the call's chat. A deterministic digest (no model call); text is the same as one plain block. transcript is always null.

Scope: `calendar:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `meetingId` | string | yes |  |

Example call:

```json
{"name":"meeting_summary_so_far","arguments":{"meetingId":"mtg_8d7c6b5a"}}
```

### meeting_lobby_list

The meeting's waiting room: guests from the guest link waiting for someone to let them in (id, name, askedAt), oldest first, and whether guests wait at all (guestsWait).

Scope: `calendar:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `meetingId` | string | yes |  |

Example call:

```json
{"name":"meeting_lobby_list","arguments":{"meetingId":"mtg_8d7c6b5a"}}
```

### meeting_lobby_decide

Admit or deny one waiting guest (lobbyId from meeting_lobby_list) or everyone waiting (all: true). decision is admit or deny. Recorded in the audit log.

Scope: `calendar:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `meetingId` | string | yes |  |
| `lobbyId` | string | no |  |
| `all` | boolean | no |  |
| `decision` | one of: admit, deny | yes |  |

Example call:

```json
{"name":"meeting_lobby_decide","arguments":{"meetingId":"mtg_8d7c6b5a","decision":"admit"}}
```

### list_calendar_events

Meetings (weekly series expanded) and task due dates between from and to, at most 100 days. Signed in as a person: your meetings, the due dates of tasks assigned to you, and your other calendars (kind external, read only, with sourceName). With an API key: every meeting and due date in the workspace. Each event: { id, kind, title, start, end, allDay, url }.

Scope: `calendar:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string | no | Start, e.g. 2026-11-01 or an ISO instant. Default: a week ago. |
| `to` | string | no | End (exclusive). Default: 5 weeks after from. |

Example call:

```json
{"name":"list_calendar_events","arguments":{"from":"2026-11-01","to":"2026-11-08"}}
```

## Contacts and deals

### search_contacts

People the workspace has emailed with, made from mail automatically. Search by name or email.

Scope: `contacts:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string | no |  |
| `limit` | integer | no |  Default 20. |

Example call:

```json
{"name":"search_contacts","arguments":{"q":"ada","limit":3}}
```

### contact_timeline

Everything with one person (by contact id or email): threads, tasks and deals, newest first.

Scope: `contacts:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Contact id or email address. |

Example call:

```json
{"name":"contact_timeline","arguments":{"id":"con_007ab32h"}}
```

### upsert_contact

Create a contact, or update it if the email is already known: name, phone, job title, notes.

Scope: `contacts:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | string | yes |  |
| `name` | string | no |  |
| `phone` | string | no |  |
| `title` | string | no |  |
| `notes` | string | no |  |

Example call:

```json
{"name":"upsert_contact","arguments":{"email":"ada@example.com","name":"Ada Lovelace","title":"Head of Finance"}}
```

## Workspace admin

### create_agent_inbox

Create a new agent with its own email address on the workspace's domain. Its sends need a person's approval unless approvalMode says otherwise. Returns the agent and a key for it, shown once.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `localPart` | string | no | The part before the @. |
| `approvalMode` | one of: always, external, never | no |  Default "always". |

Example call:

```json
{"name":"create_agent_inbox","arguments":{"name":"Support agent","localPart":"support","approvalMode":"external"}}
```

### set_mailbox_reply_to

Sets the Reply-To that every send from this mailbox carries when the send names none (for example no-reply@ sends with replies going to support@). Pass replyTo null to clear it. list_inboxes shows each mailbox's current one.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `mailboxId` | string | yes |  |
| `replyTo` | string | yes |  |

Example call:

```json
{"name":"set_mailbox_reply_to","arguments":{"mailboxId":"mbx_8d7c6b5a","replyTo":"ada@example.com"}}
```

### list_guests

Outside people (clients) invited to a project, with their status.

Scope: `admin:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |

Example call:

```json
{"name":"list_guests","arguments":{"projectId":"prj_8d7c6b5a"}}
```

### invite_guest

Invite an outside person by email to one project. Guests are free and see only that project's tasks, comments and docs. The invite email goes from this agent's inbox and follows its approval rules, so it may wait for a person to approve it.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | yes |  |
| `email` | string | yes |  |
| `name` | string | no |  |

Example call:

```json
{"name":"invite_guest","arguments":{"projectId":"prj_8d7c6b5a","email":"ada@example.com"}}
```

### list_integrations

The connector catalogue (Slack, Discord, Teams, Zapier, Make, n8n, Google Sheets, any URL), the connected integrations, and the incoming webhooks with their last calls.

Scope: `admin:read` (read only)

Example call:

```json
{"name":"list_integrations","arguments":{}}
```

### create_incoming_hook

Makes a secret URL that turns a JSON or form POST into a task (title, notes, due, assignee email), a chat message in a channel, or a contact. The URL is returned once.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `action` | one of: task, chat, contact | yes |  |
| `projectId` | string | no |  |
| `channelId` | string | no |  |
| `mapping` | object | no |  |

Example call:

```json
{"name":"create_incoming_hook","arguments":{"name":"Follow up with Ada","action":"task"}}
```

### list_agent_triggers

The workspace's triggers that queue runs for AI agent members (at most 20): kind schedule or webhook, the agent, the task or project, next run, last fired. Admin and workspace keys only.

Scope: `admin:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `agentUserId` | string | no |  |

Example call:

```json
{"name":"list_agent_triggers","arguments":{}}
```

### create_agent_trigger

Queues runs for an AI agent member on a schedule (everyHours of 1 or more, or dailyAt HH:MM in the workspace zone with optional days) or when a signed webhook arrives (the answer holds the URL and the secret, shown once). Name a task (taskId) or a project (projectId) with a titleTemplate ({trigger}, {date}, {datetime}) for a new task each time. instructions travel with each run. Limits: 20 triggers per workspace, 3 queued runs per agent.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `agentUserId` | string | yes |  |
| `kind` | one of: schedule, webhook | yes |  |
| `name` | string | yes |  |
| `taskId` | string | no |  |
| `projectId` | string | no |  |
| `titleTemplate` | string | no |  |
| `instructions` | string | no |  |
| `everyHours` | integer | no |  |
| `dailyAt` | string | no |  |
| `days` | array of one of | no |  |
| `timezone` | string | no |  |
| `enabled` | boolean | no |  |

Example call:

```json
{"name":"create_agent_trigger","arguments":{"agentUserId":"usr_8d7c6b5a","kind":"schedule","name":"Follow up with Ada"}}
```

### delete_agent_trigger

Deletes a trigger; its webhook stops at once. Runs it already queued stay.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `triggerId` | string | yes |  |

Example call:

```json
{"name":"delete_agent_trigger","arguments":{"triggerId":"tri_8d7c6b5a"}}
```

### agent_trigger_history

A trigger's recent fires and refusals, newest first: outcome (fired or refused), source (schedule, webhook or manual), reason and message on a refusal, the run it queued with its task, who fired it, and when. limit is 1 to 50 (default 20). Admin and workspace keys only.

Scope: `admin:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `triggerId` | string | yes |  |
| `limit` | integer | no |  |

Example call:

```json
{"name":"agent_trigger_history","arguments":{"triggerId":"tri_8d7c6b5a"}}
```

### export_workspace

Starts a full workspace export and answers downloadUrl, a ZIP link that works for 24 hours: JSON for every table, CSV for tasks, projects, comments, contacts, deals, time and chat, Markdown docs, an .ics calendar, a .vcf address book and mbox mail. One export every 10 minutes.

Scope: `admin:read` (read only)

Example call:

```json
{"name":"export_workspace","arguments":{}}
```

### list_data_moves

The last 50 imports and exports: kind, source, status, done of total, how many items each made and whether it can be undone.

Scope: `admin:read` (read only)

Example call:

```json
{"name":"list_data_moves","arguments":{}}
```

### import_file

Brings a file in. kind: tasks (CSV, Excel as xlsx-base64:, Trello JSON, or a Markdown and CSV zip as zip-base64:), calendar (.ics), contacts (.vcf or CSV), docs (Markdown, or a zip of pages) or workspace (an export zip). Runs about 15 seconds; while move.status is stopped, call again with the same content and moveId. Re-running a tasks file skips tasks already in.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | one of: tasks, calendar, contacts, docs, workspace | yes |  |
| `content` | string | yes |  |
| `fileName` | string | no |  |
| `projectId` | string | no |  |
| `projectName` | string | no |  |
| `moveId` | string | no |  |

Example call:

```json
{"name":"import_file","arguments":{"kind":"tasks","content":"Example"}}
```

### undo_import

Removes exactly what one import made (its tasks with their comments, the statuses and projects it added when nothing else uses them, and its meetings, contacts and docs). Take the id from list_data_moves.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |

Example call:

```json
{"name":"undo_import","arguments":{"id":"id_8d7c6b5a"}}
```

### list_automation_recipes

Ready made automation rules by category (Tasks, Mail, Chat, Meetings, Sprints): key, name, description, the rules each makes, the blanks to fill (channel, project, member, members or text) and whether it is on in this workspace. Pass category to narrow the list.

Scope: `admin:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `category` | one of: Tasks, Mail, Chat, Meetings, Sprints | no |  |

Example call:

```json
{"name":"list_automation_recipes","arguments":{}}
```

### enable_automation_recipe

Turns a recipe on: makes its rules as normal automations with the blanks filled in (for example { channelId } for a recipe that posts in a channel, or { projectId, memberIds } for sharing tasks in turn). Channels must be public channels of this workspace. Answers the rules made or switched on.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | yes |  |
| `blanks` | object | no |  Default {}. |

Example call:

```json
{"name":"enable_automation_recipe","arguments":{"key":"Example"}}
```

### update_auth_email_hook

Sets how a Supabase auth email hook's emails look: branding { logoUrl (https), brandColor (#RRGGBB), replyTo (email), footer, templates: { signup | invite | magiclink | recovery | email_change | email | reauthentication: { subject, intro, buttonLabel } }, secondaryLanguage: { lang (e.g. ne), templates (same shape), note } }. Plain text only; placeholders {appName}, {code}, {email}. Keys left out stay, null clears one, templates merge per type, branding null goes back to the default email. Also appName and from (another mailbox). Returns the hook, never its secret.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `hookId` | string | yes | The hook id (ahk_...). |
| `appName` | string | no |  |
| `from` | string | no |  |
| `branding` | object | no |  |

Example call:

```json
{"name":"update_auth_email_hook","arguments":{"hookId":"hoo_8d7c6b5a"}}
```

### list_agent_members

AI agent members of the workspace with title, bio, avatar colour and initials, whether they are paused, the agent inbox linked to them (mailbox is optional) and how many keys they have. Assign tasks to one with assignee member:<userId>.

Scope: `admin:read` (read only)

Example call:

```json
{"name":"list_agent_members","arguments":{}}
```

### create_agent_member

Adds an AI agent member (no seat, no mailbox needed) and returns its first API key, shown once. Needs a full workspace key. Counts against the plan's agent member limit.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `title` | string | no |  |
| `bio` | string | no |  |
| `scope` | one of: full, read | no | What its first key can do. Default "full". |
| `avatarColor` | string | no | Avatar colour as #rrggbb. |
| `inboxAgentId` | string | no | An existing agent inbox to link to it. |

Example call:

```json
{"name":"create_agent_member","arguments":{"name":"Follow up with Ada"}}
```

### update_agent_member

Changes an agent member's name, title, bio, avatar colour or linked inbox, or pauses it (disabled true: its keys are refused until resumed with disabled false). Needs a full workspace key. Recorded in the audit log.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `userId` | string | yes |  |
| `name` | string | no |  |
| `title` | string | no |  |
| `bio` | string | no |  |
| `avatarColor` | string | no | Avatar colour as #rrggbb. |
| `disabled` | boolean | no |  |
| `inboxAgentId` | string | no |  |

Example call:

```json
{"name":"update_agent_member","arguments":{"userId":"usr_8d7c6b5a"}}
```

### get_auth_email_settings

The workspace's Sign-up emails settings (the Supabase auth email hook): enabled, senderName, from, appName, supabaseUrl, branding, endpointUrl, secret { set, masked } (never the secret itself) and testSendsLeft this hour, plus the sender mailboxes on verified domains. settings is null before the first update. Owners, admins and full workspace keys only.

Scope: `admin:read` (read only)

Example call:

```json
{"name":"get_auth_email_settings","arguments":{}}
```

### update_auth_email_settings

Creates the settings (from and supabaseUrl needed the first time; that answer carries the signing secret once, as `secret`, in the form Supabase takes) or changes the fields sent: enabled (off: the hook answers 503 and sends nothing), senderName (the From name, null uses the mailbox's), from (a mailbox on a verified domain), appName, supabaseUrl, branding { logoUrl, brandColor, replyTo, footer, templates per type { subject, intro, buttonLabel }, secondaryLanguage { lang, templates, note } } merged, null clears. Same checks as PUT /api/v1/auth-email-settings. Audited.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `enabled` | boolean | no |  |
| `senderName` | string | no |  |
| `from` | string | no |  |
| `appName` | string | no |  |
| `supabaseUrl` | string | no |  |
| `branding` | object | no |  |

Example call:

```json
{"name":"update_auth_email_settings","arguments":{}}
```

### regenerate_auth_email_secret

Makes a new signing secret and returns it once, as `secret`; the old one stops working at once, so paste the new one into Supabase's Send Email Hook straight away. Later reads show it masked. Audited.

Scope: `admin:write`

Example call:

```json
{"name":"regenerate_auth_email_secret","arguments":{}}
```

### preview_auth_email

Renders one email type (signup, invite, magiclink, recovery, email_change, email, reauthentication; default signup) with a sample link and the code 123456: { preview: { type, to, subject, html, text, replyTo } }. Unsaved appName and branding can be tried; email sets the sample recipient. Nothing is sent or stored.

Scope: `admin:read` (read only)

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | string | no |  |
| `appName` | string | no |  |
| `email` | string | no |  |
| `branding` | object | no |  |

Example call:

```json
{"name":"preview_auth_email","arguments":{}}
```

### send_auth_email_test

Sends one email type (signup, invite, magiclink, recovery, email_change, email, reauthentication; default signup), as saved, to your own address with "Test:" before the subject. At most 5 an hour for a workspace (rate_limited after, with the minutes to wait). Answers { sent, to, type, testSendsLeft }.

Scope: `admin:write`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | string | no |  |

Example call:

```json
{"name":"send_auth_email_test","arguments":{}}
```

## Example calls with real results

These are real answers from a Multies server with example data (captured 2026-10-26). Ids are made stable, secrets are hidden and long lists are cut to 3 items. Your ids and data will differ.

### add_checklist_items

Call:

```json
{"name":"add_checklist_items","arguments":{"taskId":"tsk_007agkj7","items":[{"title":"Export the PDF"},{"title":"Email it to Ada"}]}}
```

Result:

```json
{
  "items": [
    {
      "id": "chk_007azrnq",
      "taskId": "tsk_007agkj7",
      "title": "Export the PDF",
      "done": false,
      "position": 1,
      "assignee": null,
      "due": null,
      "createdAt": "2026-10-26T17:42:05.173Z",
      "updatedAt": "2026-10-26T17:42:05.173Z"
    },
    {
      "id": "chk_007b2ie3",
      "taskId": "tsk_007agkj7",
      "title": "Email it to Ada",
      "done": false,
      "position": 2,
      "assignee": null,
      "due": null,
      "createdAt": "2026-10-26T17:42:05.173Z",
      "updatedAt": "2026-10-26T17:42:05.173Z"
    }
  ]
}
```

### add_thread_comment

Call:

```json
{"name":"add_thread_comment","arguments":{"threadId":"thr_0079meh8","body":"I'll take this one, the PDF is ready."}}
```

Result:

```json
{
  "comment": {
    "id": "tcm_007a0451",
    "threadId": "thr_0079meh8",
    "mailboxId": "mbx_0079gx0i",
    "author": {
      "type": "member",
      "id": "usr_0079xdeo",
      "name": "Sam Rivera"
    },
    "body": "I'll take this one, the PDF is ready.",
    "mentions": [],
    "editedAt": null,
    "createdAt": "2026-10-26T17:42:04.835Z",
    "canEdit": true,
    "canDelete": true
  }
}
```

### append_to_doc

Call:

```json
{"name":"append_to_doc","arguments":{"id":"doc_007bog8z","text":"Escalate to the account owner after 14 days."}}
```

Result:

```json
{
  "id": "doc_007bog8z",
  "version": 2
}
```

### assign_thread

Call:

```json
{"name":"assign_thread","arguments":{"threadId":"thr_0079meh8","userId":"usr_0079xdeo"}}
```

Result:

```json
{
  "state": {
    "threadId": "thr_0079meh8",
    "status": "waiting",
    "assignee": {
      "id": "usr_0079xdeo",
      "name": "Sam Rivera"
    },
    "assignedAt": "2026-10-26T17:42:04.820Z",
    "doneAt": null
  }
}
```

### catchup_get

Call:

```json
{"name":"catchup_get","arguments":{"type":"task","id":"tsk_007agkj7"}}
```

Result:

```json
{
  "catchup": {
    "type": "task",
    "id": "tsk_007agkj7",
    "since": null,
    "hasNew": false,
    "mode": "digest",
    "counts": {
      "messages": 0,
      "replies": 0,
      "comments": 0,
      "edits": 0,
      "statusChanges": 0,
      "assigneeChanges": 0,
      "mentions": 0
    },
    "actors": [],
    "decisions": [],
    "latest": [],
    "canSummarise": false
  }
}
```

### comment_on_task

Call:

```json
{"name":"comment_on_task","arguments":{"id":"TSK-1","body":"Sent the PDF, waiting on Ada."}}
```

Result:

```json
{
  "comment": {
    "id": "cmt_007ax0xd",
    "taskId": "tsk_007agkj7",
    "body": "Sent the PDF, waiting on Ada.",
    "author": {
      "type": "member",
      "id": "usr_0079xdeo",
      "name": "Acme"
    },
    "createdAt": "2026-10-26T17:42:05.143Z"
  }
}
```

### contact_timeline

Call:

```json
{"name":"contact_timeline","arguments":{"id":"con_007ab32h"}}
```

Result:

```json
{
  "contact": {
    "id": "con_007ab32h",
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "phone": null,
    "title": "Head of Finance",
    "notes": "",
    "source": "mail",
    "company": {
      "id": "cmp_007adtsu",
      "name": "Example",
      "domain": "example.com"
    },
    "companyId": "cmp_007adtsu",
    "messageCount": 1,
    "firstContactAt": "2026-10-26T17:42:04.636Z",
    "lastContactAt": "2026-10-26T17:42:04.636Z",
    "createdAt": "2026-10-26T17:42:04.648Z",
    "updatedAt": "2026-10-26T17:42:04.985Z",
    "version": 2
  },
  "threads": [
    {
      "threadId": "thr_0079meh8",
      "subject": "Invoice 1042",
      "lastAt": "2026-10-26T17:42:04.636Z",
      "firstAt": "2026-10-26T17:42:04.636Z",
      "count": 1,
      "lastDirection": "inbound",
      "snippet": "Hi, could you send invoice 1042 as a PDF? Thanks, Ada",
      "messageId": "msg_0079p5
... (cut)
```

### create_agent_inbox

Call:

```json
{"name":"create_agent_inbox","arguments":{"name":"Support agent","localPart":"support","approvalMode":"external"}}
```

Result:

```json
{
  "agent": {
    "id": "agt_0079e6a5",
    "name": "Support agent",
    "description": null,
    "address": "support@acme.io",
    "inboxId": "mbx_0079gx0i",
    "approvalMode": "external",
    "sendCapDaily": 100,
    "allowedRecipients": null,
    "status": "active",
    "mailboxIds": [
      "mbx_0079gx0i"
    ],
    "sentToday": 0,
    "pendingApprovals": 0,
    "createdAt": "2026-10-26T17:42:04.608Z"
  },
  "apiKey": {
    "id": "key_0079jnqv",
    "prefix": "mm_live_(hidden)",
    "secret": "(shown once, hidden here)"
  }
}
```

### create_dashboard

Call:

```json
{"name":"create_dashboard","arguments":{"name":"Billing","starter":"team"}}
```

Result:

```json
{
  "dashboard": {
    "id": "dsh_007bzf6f",
    "name": "Billing",
    "shared": true,
    "owner": "usr_0079xdeo",
    "mine": true,
    "widgets": [
      {
        "id": "wdg_007c25ws",
        "type": "breakdown",
        "title": "Tasks by status",
        "source": {},
        "groupBy": "status",
        "chart": "donut",
        "size": 1,
        "position": 0
      },
      {
        "id": "wdg_007c4wn5",
        "type": "breakdown",
        "title": "Open tasks by person",
        "source": {},
        "groupBy": "assignee",
        "chart": "bar",
        "size": 1,
        "position": 1
      },
      {
        "id": "wdg_007c7ndi",
        "type": "due",
        "title": "Due this week and overdue",
        "source": {},
        "groupBy": null,
        "chart": "table",
        "size": 1,
        "position": 2
      }
    ],
    "createdAt": "2026-10-26T17:42:05.648Z",
  
... (cut)
```

### create_doc

Call:

```json
{"name":"create_doc","arguments":{"title":"Billing playbook","text":"# Billing playbook\n\nSend invoices on the 1st. Follow up after 7 days."}}
```

Result:

```json
{
  "id": "doc_007bog8z",
  "title": "Billing playbook",
  "version": 1
}
```

### create_form

Call:

```json
{"name":"create_form","arguments":{"name":"Billing question","description":"Ask us anything about your invoice.","target":"task","fields":[{"label":"Email","type":"email","required":true},{"label":"Question","type":"textarea","required":true}]}}
```

Result:

```json
{
  "form": {
    "id": "frm_007br6zc",
    "name": "Billing question",
    "description": "Ask us anything about your invoice.",
    "slug": "cikn1twkpfqx",
    "url": "https://multies.si/f/cikn1twkpfqx",
    "target": "task",
    "projectId": null,
    "assigneeId": null,
    "fields": [
      {
        "id": "field_1",
        "label": "Email",
        "type": "email",
        "required": true
      },
      {
        "id": "field_2",
        "label": "Question",
        "type": "textarea",
        "required": true
      }
    ],
    "successMessage": "Thanks, we got it. We'll be in touch.",
    "enabled": true,
    "submitCount": 0,
    "lastSubmitAt": null,
    "triage": false,
    "routing": [],
    "createdAt": "2026-10-26T17:42:05.550Z",
    "updatedAt": "2026-10-26T17:42:05.550Z",
    "version": 1
  }
}
```

### create_goal

Call:

```json
{"name":"create_goal","arguments":{"name":"Get paid faster","description":"Cut the average days to payment.","due":"2026-12-31","keyResults":[{"name":"Average days to payment","kind":"number","start":30,"target":14,"current":21}]}}
```

Result:

```json
{
  "goal": {
    "id": "gol_007baql6",
    "name": "Get paid faster",
    "description": "Cut the average days to payment.",
    "owner": {
      "id": "usr_0079xdeo",
      "name": "Sam Rivera"
    },
    "parentId": null,
    "start": null,
    "due": "2026-12-31T00:00:00.000Z",
    "health": null,
    "suggestedHealth": "on_track",
    "archived": false,
    "progress": 56,
    "keyResults": [
      {
        "id": "kr_007bdhbj",
        "goalId": "gol_007baql6",
        "name": "Average days to payment",
        "kind": "number",
        "unit": "",
        "start": 30,
        "target": 14,
        "current": 21,
        "projectId": null,
        "taskIds": [],
        "tasks": null,
        "progress": 56,
        "updatedAt": "2026-10-26T17:42:05.345Z"
      }
    ],
    "children": [],
    "createdAt": "2026-10-26T17:42:05.345Z",
    "updatedAt": "2026-10-26T17:42:05.345Z"
  }

... (cut)
```

### create_snippet

Call:

```json
{"name":"create_snippet","arguments":{"name":"Invoice sent","body":"Hi {{first_name}}, your invoice is attached. Thanks!","shortcut":"inv","shared":true}}
```

Result:

```json
{
  "snippet": {
    "id": "snp_007a5llr",
    "name": "Invoice sent",
    "shortcut": "inv",
    "subject": null,
    "body": "Hi {{first_name}}, your invoice is attached. Thanks!",
    "shared": true,
    "createdBy": {
      "id": "usr_0079xdeo",
      "name": "Sam Rivera"
    },
    "createdAt": "2026-10-26T17:42:04.919Z",
    "updatedAt": "2026-10-26T17:42:04.919Z",
    "canEdit": true
  }
}
```

### create_sprint

Call:

```json
{"name":"create_sprint","arguments":{"projectId":"prj_007ajb9k","name":"Sprint 12","goal":"Close every open invoice","startAt":"2026-11-02","endAt":"2026-11-15"}}
```

Result:

```json
{
  "sprint": {
    "id": "spr_007bwog2",
    "projectId": "prj_007ajb9k",
    "name": "Sprint 12",
    "goal": "Close every open invoice",
    "status": "planned",
    "startAt": "2026-11-02T00:00:00.000Z",
    "endAt": "2026-11-15T23:59:59.999Z",
    "startedAt": null,
    "completedAt": null,
    "createdAt": "2026-10-26T17:42:05.620Z",
    "updatedAt": "2026-10-26T17:42:05.620Z",
    "path": "/app/tasks?project=prj_007ajb9k&view=sprints&sprint=spr_007bwog2"
  }
}
```

### create_task

Call:

```json
{"name":"create_task","arguments":{"title":"Follow up with Ada about invoice 1042","notes":"She asked for a PDF copy.","priority":"high","due":"2026-11-03","labels":["billing"]}}
```

Result:

```json
{
  "task": {
    "id": "tsk_007agkj7",
    "ref": "TSK-1",
    "projectId": "prj_007ajb9k",
    "number": 1,
    "title": "Follow up with Ada about invoice 1042",
    "notes": "She asked for a PDF copy.",
    "statusId": "sts_007am1zx",
    "statusName": "To do",
    "statusColor": "#8a8f98",
    "status": "todo",
    "assignee": null,
    "assigneeId": null,
    "priority": "high",
    "labels": [
      "billing"
    ],
    "type": "task",
    "start": null,
    "due": "2026-11-03T00:00:00.000Z",
    "parentId": null,
    "position": 1024,
    "source": null,
    "subtasks": {
      "total": 0,
      "done": 0
    },
    "checklist": {
      "total": 0,
      "done": 0
    },
    "commentCount": 0,
    "fields": {},
    "repeat": null,
    "completedAt": null,
    "sprintId": null,
    "points": null,
    "createdBy": {
      "type": "member",
      "id": "usr_0079xdeo"
    },
    "cre
... (cut)
```

### duplicate_task

Call:

```json
{"name":"duplicate_task","arguments":{"taskId":"tsk_007agkj7","title":"Follow up with Grace about invoice 1043"}}
```

Result:

```json
{
  "task": {
    "id": "tsk_007b594g",
    "ref": "TSK-3",
    "projectId": "prj_007ajb9k",
    "number": 3,
    "title": "Follow up with Grace about invoice 1043",
    "notes": "She asked for a PDF copy.",
    "statusId": "sts_007am1zx",
    "statusName": "To do",
    "statusColor": "#8a8f98",
    "status": "todo",
    "assignee": {
      "type": "member",
      "id": "usr_0079xdeo",
      "name": "Sam Rivera",
      "email": "sam@acme.io"
    },
    "assigneeId": "member:usr_0079xdeo",
    "priority": "high",
    "labels": [
      "billing"
    ],
    "type": "task",
    "start": null,
    "due": "2026-11-03T00:00:00.000Z",
    "parentId": null,
    "position": 3072,
    "source": null,
    "subtasks": {
      "total": 0,
      "done": 0
    },
    "checklist": {
      "total": 2,
      "done": 0
    },
    "commentCount": 0,
    "fields": {},
    "repeat": null,
    "completedAt": nu
... (cut)
```

### get_counts

Call:

```json
{"name":"get_counts","arguments":{"tz":"Australia/Sydney"}}
```

Result:

```json
{
  "mail": {
    "inbox": 0,
    "important": 0,
    "other": 0
  },
  "chat": {
    "unread": 0,
    "mentions": 0
  },
  "notifications": {
    "unread": 2
  },
  "triage": 0,
  "tasks": {
    "dueToday": 0,
    "overdue": 0
  },
  "at": "2026-10-26T17:42:05.316Z"
}
```

### get_doc_tree

Call:

```json
{"name":"get_doc_tree","arguments":{"flat":true}}
```

Result:

```json
{
  "pages": [
    {
      "id": "doc_007bog8z",
      "title": "Billing playbook",
      "parentId": null,
      "position": 1,
      "projectId": null,
      "updatedAt": "2026-10-26T17:42:05.498Z",
      "depth": 1
    }
  ],
  "count": 1,
  "truncated": false
}
```

### get_report

Call:

```json
{"name":"get_report","arguments":{"days":30}}
```

Result:

```json
{
  "range": {
    "days": 30,
    "from": "2026-09-26T17:42:05.375Z",
    "to": "2026-10-26T17:42:05.375Z"
  },
  "tasks": {
    "total": 3,
    "open": 3,
    "done": 0,
    "overdue": 0,
    "createdInRange": 3,
    "completedInRange": 0,
    "byCategory": {
      "todo": 2,
      "doing": 1,
      "done": 0
    },
    "byStatus": [
      {
        "name": "To do",
        "category": "todo",
        "color": "#8a8f98",
        "count": 2
      },
      {
        "name": "In progress",
        "category": "doing",
        "color": "#3b82f6",
        "count": 1
      }
    ],
    "byAssignee": [
      {
        "assigneeId": "member:usr_0079xdeo",
        "name": "Sam Rivera",
        "open": 2,
        "overdue": 0
      },
      {
        "assigneeId": null,
        "name": "Unassigned",
        "open": 1,
        "overdue": 0
      }
    ],
    "overdueList": [],
    "completedByDay
... (cut)
```

### get_task

Call:

```json
{"name":"get_task","arguments":{"id":"TSK-1"}}
```

Result:

```json
{
  "task": {
    "id": "tsk_007agkj7",
    "ref": "TSK-1",
    "projectId": "prj_007ajb9k",
    "number": 1,
    "title": "Follow up with Ada about invoice 1042",
    "notes": "She asked for a PDF copy.",
    "statusId": "sts_007am1zx",
    "statusName": "To do",
    "statusColor": "#8a8f98",
    "status": "todo",
    "assignee": null,
    "assigneeId": null,
    "priority": "high",
    "labels": [
      "billing"
    ],
    "type": "task",
    "start": null,
    "due": "2026-11-03T00:00:00.000Z",
    "parentId": null,
    "position": 1024,
    "source": null,
    "subtasks": {
      "total": 0,
      "done": 0
    },
    "checklist": {
      "total": 0,
      "done": 0
    },
    "commentCount": 0,
    "fields": {},
    "repeat": null,
    "completedAt": null,
    "sprintId": null,
    "points": null,
    "createdBy": {
      "type": "member",
      "id": "usr_0079xdeo"
    },
    "cre
... (cut)
```

### get_timesheet

Call:

```json
{"name":"get_timesheet","arguments":{"from":"2026-10-27","to":"2026-11-03"}}
```

Result:

```json
{
  "from": "2026-10-27T00:00:00.000Z",
  "to": "2026-11-04T00:00:00.000Z",
  "days": [
    "2026-10-27",
    "2026-10-28",
    "2026-10-29"
  ],
  "total": 1500,
  "rows": [
    {
      "person": "Sam Rivera",
      "project": "Tasks",
      "total": 1500,
      "days": {
        "2026-11-02": 1500
      }
    }
  ]
}
```

### list_calendar_events

Call:

```json
{"name":"list_calendar_events","arguments":{"from":"2026-11-01","to":"2026-11-08"}}
```

Result:

```json
{
  "from": "2026-11-01T00:00:00.000Z",
  "to": "2026-11-08T00:00:00.000Z",
  "timezone": "UTC",
  "events": [
    {
      "id": "task:tsk_007agkj7",
      "kind": "due",
      "title": "Due: Follow up with Ada about invoice 1042 (TSK-1)",
      "start": "2026-11-03",
      "end": "2026-11-04",
      "allDay": true,
      "url": "https://multies.si/app/tasks?task=tsk_007agkj7",
      "sourceId": null,
      "sourceName": null,
      "color": null,
      "readOnly": false
    },
    {
      "id": "task:tsk_007b594g",
      "kind": "due",
      "title": "Due: Follow up with Grace about invoice 1043 (TSK-3)",
      "start": "2026-11-03",
      "end": "2026-11-04",
      "allDay": true,
      "url": "https://multies.si/app/tasks?task=tsk_007b594g",
      "sourceId": null,
      "sourceName": null,
      "color": null,
      "readOnly": false
    },
    {
      "id": "mtg_007btxpp",
      "ki
... (cut)
```

### list_channels

Call:

```json
{"name":"list_channels","arguments":{}}
```

Result:

```json
{
  "channels": [
    {
      "id": "chn_007bg81w",
      "name": "general",
      "topic": "Everyone in the workspace",
      "lastMessage": null,
      "lastMessageAt": null
    }
  ]
}
```

### list_checklist

Call:

```json
{"name":"list_checklist","arguments":{"taskId":"tsk_007agkj7"}}
```

Result:

```json
{
  "taskId": "tsk_007agkj7",
  "items": [
    {
      "id": "chk_007azrnq",
      "taskId": "tsk_007agkj7",
      "title": "Export the PDF",
      "done": false,
      "position": 1,
      "assignee": null,
      "due": null,
      "createdAt": "2026-10-26T17:42:05.173Z",
      "updatedAt": "2026-10-26T17:42:05.173Z"
    },
    {
      "id": "chk_007b2ie3",
      "taskId": "tsk_007agkj7",
      "title": "Email it to Ada",
      "done": false,
      "position": 2,
      "assignee": null,
      "due": null,
      "createdAt": "2026-10-26T17:42:05.173Z",
      "updatedAt": "2026-10-26T17:42:05.173Z"
    }
  ],
  "total": 2,
  "done": 0
}
```

### list_dashboards

Call:

```json
{"name":"list_dashboards","arguments":{}}
```

Result:

```json
{
  "dashboards": [
    {
      "id": "dsh_007bzf6f",
      "name": "Billing",
      "shared": true,
      "mine": true,
      "widgetCount": 4,
      "updatedAt": "2026-10-26T17:42:05.648Z"
    }
  ]
}
```

### list_forms

Call:

```json
{"name":"list_forms","arguments":{}}
```

Result:

```json
{
  "forms": [
    {
      "id": "frm_007br6zc",
      "name": "Billing question",
      "url": "https://multies.si/f/cikn1twkpfqx",
      "target": "task",
      "enabled": true,
      "submitCount": 0,
      "fields": [
        {
          "id": "field_1",
          "label": "Email",
          "type": "email",
          "required": true
        },
        {
          "id": "field_2",
          "label": "Question",
          "type": "textarea",
          "required": true
        }
      ]
    }
  ]
}
```

### list_goals

Call:

```json
{"name":"list_goals","arguments":{}}
```

Result:

```json
{
  "goals": [
    {
      "id": "gol_007baql6",
      "name": "Get paid faster",
      "description": "Cut the average days to payment.",
      "owner": {
        "id": "usr_0079xdeo",
        "name": "Sam Rivera"
      },
      "parentId": null,
      "start": null,
      "due": "2026-12-31T00:00:00.000Z",
      "health": null,
      "suggestedHealth": "on_track",
      "archived": false,
      "progress": 56,
      "keyResults": [
        {
          "id": "kr_007bdhbj",
          "goalId": "gol_007baql6",
          "name": "Average days to payment",
          "kind": "number",
          "unit": "",
          "start": 30,
          "target": 14,
          "current": 21,
          "projectId": null,
          "taskIds": [],
          "tasks": null,
          "progress": 56,
          "updatedAt": "2026-10-26T17:42:05.345Z"
        }
      ],
      "children": [],
      "createdAt": "20
... (cut)
```

### list_inboxes

Call:

```json
{"name":"list_inboxes","arguments":{}}
```

Result:

```json
{
  "agents": [
    {
      "agentId": "agt_0079e6a5",
      "name": "Support agent",
      "address": "support@acme.io",
      "approvalMode": "external",
      "sentToday": 0,
      "sendCapDaily": 100,
      "status": "active",
      "mailboxIds": [
        "mbx_0079gx0i"
      ]
    }
  ],
  "mailboxes": []
}
```

### list_meetings

Call:

```json
{"name":"list_meetings","arguments":{"upcoming":true}}
```

Result:

```json
{
  "meetings": [
    {
      "id": "mtg_007btxpp",
      "title": "Invoice review with Ada",
      "startsAt": "2026-11-04T23:00:00.000Z",
      "durationMin": 30,
      "status": "scheduled",
      "guestUrl": "https://multies.si/m/56epdSkOtKgdnnQzwD1UQqI",
      "invitees": [
        "ada@example.com"
      ],
      "repeats": null
    }
  ]
}
```

### list_notifications

Call:

```json
{"name":"list_notifications","arguments":{"unread":true}}
```

Result:

```json
{
  "notifications": [
    {
      "id": "ntf_007cae3v",
      "type": "approval.requested",
      "category": "approval",
      "entityType": "approval",
      "entityId": "apr_0079umob",
      "title": "Support agent wants to send \"Re: Invoice 1042\" to ada@example.com",
      "actor": {
        "type": "member",
        "id": null,
        "name": "Support agent"
      },
      "read": false,
      "createdAt": "2026-10-26T17:42:04.786Z",
      "link": "/app/approvals",
      "doneAt": null,
      "snoozedUntil": null
    },
    {
      "id": "ntf_007cd4u8",
      "type": "approval.requested",
      "category": "approval",
      "entityType": "approval",
      "entityId": "apr_0079rvxy",
      "title": "Support agent wants to send \"Your invoice 1042\" to ada@example.com",
      "actor": {
        "type": "member",
        "id": null,
        "name": "Support agent"
      },
      "r
... (cut)
```

### list_people

Call:

```json
{"name":"list_people","arguments":{}}
```

Result:

```json
{
  "people": [
    {
      "id": "usr_0079xdeo",
      "type": "member",
      "kind": "human",
      "userId": "usr_0079xdeo",
      "agentId": null,
      "name": "Sam Rivera",
      "email": "sam@acme.io",
      "role": "owner",
      "title": null,
      "bio": null,
      "inbox": null,
      "joinedAt": "2026-10-26T17:42:04.250Z"
    },
    {
      "id": "agt_0079e6a5",
      "type": "mail_agent",
      "kind": "agent",
      "userId": null,
      "agentId": "agt_0079e6a5",
      "name": "Support agent",
      "email": null,
      "role": null,
      "title": "Mail agent",
      "bio": null,
      "inbox": "support@acme.io",
      "joinedAt": "2026-10-26T17:42:04.608Z"
    }
  ]
}
```

### list_projects

Call:

```json
{"name":"list_projects","arguments":{}}
```

Result:

```json
{
  "projects": [
    {
      "id": "prj_007ajb9k",
      "name": "Tasks",
      "description": "Tasks made from email land here first.",
      "key": "TSK",
      "color": "#ff5a36",
      "archived": false,
      "statuses": [
        {
          "id": "sts_007am1zx",
          "name": "To do",
          "category": "todo",
          "color": "#8a8f98",
          "position": 0
        },
        {
          "id": "sts_007aosqa",
          "name": "In progress",
          "category": "doing",
          "color": "#3b82f6",
          "position": 1
        },
        {
          "id": "sts_007arjgn",
          "name": "In review",
          "category": "doing",
          "color": "#f59e0b",
          "position": 2
        }
      ],
      "counts": {
        "todo": 1,
        "doing": 0,
        "done": 0
      },
      "health": null,
      "healthNote": "",
      "ownerId": null,
      
... (cut)
```

### list_scheduled

Call:

```json
{"name":"list_scheduled","arguments":{"view":"snoozed"}}
```

Result:

```json
{
  "items": [
    {
      "id": "msch_007a2uve",
      "kind": "snooze",
      "status": "pending",
      "mailboxId": "mbx_0079gx0i",
      "threadId": "thr_0079meh8",
      "messageId": "msg_0079p57l",
      "dueAt": "2026-10-27T08:00:00.000Z",
      "createdAt": "2026-10-26T17:42:04.885Z",
      "error": null,
      "message": {
        "id": "msg_0079p57l",
        "mailboxId": "mbx_0079gx0i",
        "folder": "inbox",
        "threadId": "thr_0079meh8",
        "from": {
          "address": "ada@example.com",
          "name": "Ada Lovelace"
        },
        "to": [
          {
            "address": "support@acme.io"
          }
        ],
        "subject": "Invoice 1042",
        "snippet": "Hi, could you send invoice 1042 as a PDF? Thanks, Ada",
        "date": "2026-10-26T17:42:04.636Z",
        "isRead": false,
        "isStarred": false,
        "hasAttachments": false,

... (cut)
```

### list_snippets

Call:

```json
{"name":"list_snippets","arguments":{}}
```

Result:

```json
{
  "snippets": [
    {
      "id": "snp_007a5llr",
      "name": "Invoice sent",
      "shortcut": "inv",
      "subject": null,
      "body": "Hi {{first_name}}, your invoice is attached. Thanks!",
      "shared": true,
      "createdBy": {
        "id": "usr_0079xdeo",
        "name": "Sam Rivera"
      },
      "createdAt": "2026-10-26T17:42:04.919Z",
      "updatedAt": "2026-10-26T17:42:04.919Z",
      "canEdit": true
    }
  ]
}
```

### list_sprints

Call:

```json
{"name":"list_sprints","arguments":{"projectId":"prj_007ajb9k"}}
```

Result:

```json
{
  "unit": "points",
  "sprints": [
    {
      "id": "spr_007bwog2",
      "projectId": "prj_007ajb9k",
      "name": "Sprint 12",
      "goal": "Close every open invoice",
      "status": "planned",
      "startAt": "2026-11-02T00:00:00.000Z",
      "endAt": "2026-11-15T23:59:59.999Z",
      "startedAt": null,
      "completedAt": null,
      "carriedOver": 0,
      "createdAt": "2026-10-26T17:42:05.620Z",
      "updatedAt": "2026-10-26T17:42:05.620Z",
      "version": 1,
      "path": "/app/tasks?project=prj_007ajb9k&view=sprints&sprint=spr_007bwog2",
      "counts": {
        "tasks": 0,
        "done": 0,
        "points": 0,
        "donePoints": 0
      }
    }
  ]
}
```

### list_task_comments

Call:

```json
{"name":"list_task_comments","arguments":{"taskId":"tsk_007agkj7"}}
```

Result:

```json
{
  "taskId": "tsk_007agkj7",
  "comments": [
    {
      "id": "cmt_007ax0xd",
      "taskId": "tsk_007agkj7",
      "body": "Sent the PDF, waiting on Ada.",
      "author": {
        "type": "member",
        "id": "usr_0079xdeo",
        "name": "Acme"
      },
      "editedAt": null,
      "createdAt": "2026-10-26T17:42:05.143Z"
    }
  ]
}
```

### list_tasks

Call:

```json
{"name":"list_tasks","arguments":{"limit":3}}
```

Result:

```json
{
  "tasks": [
    {
      "id": "tsk_007agkj7",
      "ref": "TSK-1",
      "title": "Follow up with Ada about invoice 1042",
      "type": "task",
      "status": "todo",
      "statusName": "To do",
      "priority": "high",
      "due": "2026-11-03T00:00:00.000Z",
      "assignee": null,
      "labels": [
        "billing"
      ],
      "threadId": null,
      "subtasks": {
        "total": 0,
        "done": 0
      }
    },
    {
      "id": "tsk_007aua70",
      "ref": "TSK-2",
      "title": "Send the November statements",
      "type": "task",
      "status": "todo",
      "statusName": "To do",
      "priority": "medium",
      "due": null,
      "assignee": null,
      "labels": [],
      "threadId": null,
      "subtasks": {
        "total": 0,
        "done": 0
      }
    }
  ]
}
```

### list_templates

Call:

```json
{"name":"list_templates","arguments":{}}
```

Result:

```json
{
  "templates": [
    {
      "id": "starter-client-onboarding",
      "kind": "project",
      "name": "Client onboarding",
      "description": "Welcome a new client: kick-off, access, first delivery and a check-in a month later.",
      "category": "Clients",
      "builtin": true,
      "taskCount": 6
    },
    {
      "id": "starter-content-calendar",
      "kind": "project",
      "name": "Content calendar",
      "description": "Plan, write, review and publish posts, with a weekly newsletter that repeats.",
      "category": "Marketing",
      "builtin": true,
      "taskCount": 4
    },
    {
      "id": "starter-sales-pipeline",
      "kind": "project",
      "name": "Sales pipeline",
      "description": "Track leads from first contact to won or lost, with deal value in AUD.",
      "category": "Sales",
      "builtin": true,
      "taskCount": 3
    }
  ]
}
```

### list_thread_comments

Call:

```json
{"name":"list_thread_comments","arguments":{"threadId":"thr_0079meh8"}}
```

Result:

```json
{
  "threadId": "thr_0079meh8",
  "comments": [
    {
      "id": "tcm_007a0451",
      "threadId": "thr_0079meh8",
      "mailboxId": "mbx_0079gx0i",
      "author": {
        "type": "member",
        "id": "usr_0079xdeo",
        "name": "Sam Rivera"
      },
      "body": "I'll take this one, the PDF is ready.",
      "mentions": [],
      "editedAt": null,
      "createdAt": "2026-10-26T17:42:04.835Z",
      "canEdit": true,
      "canDelete": true
    }
  ],
  "mentionable": [
    {
      "userId": "usr_0079xdeo",
      "name": "Sam Rivera",
      "email": "sam@acme.io"
    }
  ]
}
```

### list_threads

Call:

```json
{"name":"list_threads","arguments":{"limit":3}}
```

Result:

```json
{
  "data": [
    {
      "id": "thr_0079meh8",
      "mailboxId": "mbx_0079gx0i",
      "subject": "Invoice 1042",
      "snippet": "Hi, could you send invoice 1042 as a PDF? Thanks, Ada",
      "lastMessageAt": "2026-10-26T17:42:04.636Z",
      "messageCount": 1,
      "unreadCount": 1,
      "from": {
        "address": "ada@example.com",
        "name": "Ada Lovelace"
      },
      "lastSentBy": {
        "type": "external"
      },
      "agentsInvolved": [],
      "pendingApprovals": 0,
      "assignee": null,
      "status": "open",
      "lastInboundAt": "2026-10-26T17:42:04.636Z"
    }
  ],
  "nextCursor": null
}
```

### log_time

Call:

```json
{"name":"log_time","arguments":{"taskId":"tsk_007agkj7","minutes":25,"date":"2026-11-02","note":"Prepared the PDF","billable":true}}
```

Result:

```json
{
  "entry": {
    "id": "tim_007b7zut",
    "taskId": "tsk_007agkj7",
    "task": {
      "id": "tsk_007agkj7",
      "ref": "TSK-1",
      "title": "Follow up with Ada about invoice 1042"
    },
    "projectId": "prj_007ajb9k",
    "project": {
      "id": "prj_007ajb9k",
      "name": "Tasks",
      "key": "TSK",
      "color": "#ff5a36"
    },
    "person": {
      "type": "member",
      "id": "usr_0079xdeo",
      "name": "Sam Rivera"
    },
    "personId": "member:usr_0079xdeo",
    "startedAt": "2026-11-02T09:00:00.000Z",
    "endedAt": "2026-11-02T09:25:00.000Z",
    "running": false,
    "seconds": 1500,
    "note": "Prepared the PDF",
    "billable": true,
    "source": "manual",
    "createdAt": "2026-10-26T17:42:05.272Z",
    "version": 1
  }
}
```

### message_to_task

Call:

```json
{"name":"message_to_task","arguments":{"messageId":"chm_007biys9","title":"Check the 2 invoice follow ups"}}
```

Result:

```json
{
  "task": {
    "id": "tsk_007blpim",
    "ref": "TSK-4",
    "title": "Check the 2 invoice follow ups"
  }
}
```

### my_work

Call:

```json
{"name":"my_work","arguments":{"timeZone":"Australia/Sydney"}}
```

Result:

```json
{
  "date": "2026-10-27",
  "timeZone": "Australia/Sydney",
  "overdue": [],
  "dueToday": [],
  "mentions": [],
  "threads": [],
  "assignedThreads": [],
  "approvals": [
    {
      "id": "apr_0079umob",
      "title": "Re: Invoice 1042",
      "subtitle": "Support agent wants to send to ada@example.com",
      "url": "/app/approvals",
      "at": "2026-10-26T17:42:04.784Z"
    },
    {
      "id": "apr_0079rvxy",
      "title": "Your invoice 1042",
      "subtitle": "Support agent wants to send to ada@example.com",
      "url": "/app/approvals",
      "at": "2026-10-26T17:42:04.757Z"
    }
  ],
  "meetings": [],
  "snoozed": [
    {
      "id": "msch_007a2uve",
      "title": "Invoice 1042",
      "subtitle": "Ada Lovelace",
      "url": "/app/mail?mailbox=mbx_0079gx0i&folder=inbox&m=msg_0079p57l",
      "at": "2026-10-27T08:00:00.000Z"
    }
  ],
  "tookMs": 4
}
```

### pin_message

Call:

```json
{"name":"pin_message","arguments":{"messageId":"chm_007biys9","pinned":true}}
```

Result:

```json
{
  "message": {
    "id": "chm_007biys9",
    "channelId": "chn_007bg81w",
    "parentId": null,
    "author": {
      "type": "member",
      "id": "usr_0079xdeo",
      "name": "Acme",
      "title": null,
      "agent": false
    },
    "body": "Standup: invoices sent, 2 follow ups today, nothing blocked.",
    "mentions": [],
    "links": [],
    "attachments": [],
    "replyCount": 0,
    "lastReplyAt": null,
    "editedAt": null,
    "deleted": false,
    "pinnedAt": "2026-10-26T17:42:05.454Z",
    "pinnedBy": "Acme",
    "createdAt": "2026-10-26T17:42:05.405Z",
    "updatedAt": "2026-10-26T17:42:05.454Z",
    "reactions": [
      {
        "emoji": "👍",
        "count": 1,
        "reactors": [
          {
            "id": "member:usr_0079xdeo",
            "name": "Acme"
          }
        ]
      }
    ]
  }
}
```

### post_message

Call:

```json
{"name":"post_message","arguments":{"channelId":"chn_007bg81w","body":"Standup: invoices sent, 2 follow ups today, nothing blocked."}}
```

Result:

```json
{
  "message": {
    "id": "chm_007biys9",
    "channelId": "chn_007bg81w",
    "parentId": null,
    "author": {
      "type": "member",
      "id": "usr_0079xdeo",
      "name": "Acme",
      "title": null,
      "agent": false
    },
    "body": "Standup: invoices sent, 2 follow ups today, nothing blocked.",
    "mentions": [],
    "links": [],
    "attachments": [],
    "replyCount": 0,
    "lastReplyAt": null,
    "editedAt": null,
    "deleted": false,
    "pinnedAt": null,
    "pinnedBy": null,
    "createdAt": "2026-10-26T17:42:05.405Z",
    "updatedAt": "2026-10-26T17:42:05.405Z",
    "reactions": []
  }
}
```

### react_to_chat_message

Call:

```json
{"name":"react_to_chat_message","arguments":{"messageId":"chm_007biys9","emoji":"👍"}}
```

Result:

```json
{
  "messageId": "chm_007biys9",
  "emoji": "👍",
  "added": true,
  "reactions": [
    {
      "emoji": "👍",
      "count": 1,
      "reactors": [
        {
          "id": "member:usr_0079xdeo",
          "name": "Acme"
        }
      ]
    }
  ]
}
```

### read_channel

Call:

```json
{"name":"read_channel","arguments":{"channelId":"chn_007bg81w","limit":3}}
```

Result:

```json
{
  "messages": [
    {
      "id": "chm_007biys9",
      "channelId": "chn_007bg81w",
      "parentId": null,
      "author": {
        "type": "member",
        "id": "usr_0079xdeo",
        "name": "Acme",
        "title": null,
        "agent": false
      },
      "body": "Standup: invoices sent, 2 follow ups today, nothing blocked.",
      "mentions": [],
      "links": [],
      "attachments": [],
      "replyCount": 0,
      "lastReplyAt": null,
      "editedAt": null,
      "deleted": false,
      "pinnedAt": null,
      "pinnedBy": null,
      "createdAt": "2026-10-26T17:42:05.405Z",
      "updatedAt": "2026-10-26T17:42:05.405Z",
      "reactions": []
    }
  ],
  "hasMore": false
}
```

### read_doc

Call:

```json
{"name":"read_doc","arguments":{"id":"doc_007bog8z"}}
```

Result:

```json
{
  "id": "doc_007bog8z",
  "title": "Billing playbook",
  "text": "Billing playbook\nSend invoices on the 1st. Follow up after 7 days.\nEscalate to the account owner after 14 days.",
  "links": [],
  "version": 2,
  "updatedAt": "2026-10-26T17:42:05.498Z"
}
```

### read_thread

Call:

```json
{"name":"read_thread","arguments":{"threadId":"thr_0079meh8"}}
```

Result:

```json
{
  "id": "thr_0079meh8",
  "mailboxId": "mbx_0079gx0i",
  "subject": "Invoice 1042",
  "messageCount": 1,
  "messages": [
    {
      "id": "msg_0079p57l",
      "threadId": "thr_0079meh8",
      "mailboxId": "mbx_0079gx0i",
      "folder": "inbox",
      "direction": "inbound",
      "from": {
        "address": "ada@example.com",
        "name": "Ada Lovelace"
      },
      "to": [
        {
          "address": "support@acme.io"
        }
      ],
      "cc": [],
      "replyTo": null,
      "subject": "Invoice 1042",
      "date": "2026-10-26T17:42:04.636Z",
      "isRead": false,
      "text": "Hi, could you send invoice 1042 as a PDF? Thanks, Ada",
      "latestText": "Hi, could you send invoice 1042 as a PDF? Thanks, Ada",
      "html": null,
      "codes": [],
      "links": [],
      "attachments": [],
      "sentBy": {
        "type": "external"
      },
      "auth": {
     
... (cut)
```

### render_snippet

Call:

```json
{"name":"render_snippet","arguments":{"snippetId":"snp_007a5llr","threadId":"thr_0079meh8"}}
```

Result:

```json
{
  "id": "snp_007a5llr",
  "subject": "",
  "body": "Hi Ada, your invoice is attached. Thanks!",
  "variables": {
    "first_name": "Ada",
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "my_name": "Sam Rivera",
    "my_first_name": "Sam",
    "company": "Acme",
    "mailbox": "support@acme.io",
    "date": "26 October 2026"
  }
}
```

### reply

Call:

```json
{"name":"reply","arguments":{"threadId":"thr_0079meh8","agentId":"agt_0079e6a5","text":"Thanks Ada, the invoice is on its way."}}
```

Result:

```json
{
  "status": "pending_approval",
  "approval": {
    "id": "apr_0079umob",
    "agentId": "agt_0079e6a5",
    "mailboxId": "mbx_0079gx0i",
    "threadId": "thr_0079meh8",
    "status": "pending",
    "to": [
      "ada@example.com"
    ],
    "cc": [],
    "bcc": [],
    "subject": "Re: Invoice 1042",
    "text": "Thanks Ada, the invoice is on its way.",
    "html": null,
    "inReplyToId": "msg_0079p57l",
    "decidedBy": null,
    "decidedAt": null,
    "note": null,
    "messageId": null,
    "error": null,
    "expiresAt": "2026-11-02T17:42:04.784Z",
    "createdAt": "2026-10-26T17:42:04.784Z"
  }
}
```

### schedule_meeting

Call:

```json
{"name":"schedule_meeting","arguments":{"title":"Invoice review with Ada","startsAt":"2026-11-04T23:00:00.000Z","durationMin":30,"invitees":["ada@example.com"],"sendInvites":false}}
```

Result:

```json
{
  "meeting": {
    "id": "mtg_007btxpp",
    "title": "Invoice review with Ada",
    "startsAt": "2026-11-04T23:00:00.000Z",
    "guestUrl": "https://multies.si/m/56epdSkOtKgdnnQzwD1UQqI",
    "invitees": [
      "ada@example.com"
    ],
    "videoEnabled": false,
    "repeats": null
  },
  "invites": null
}
```

### schedule_send

Call:

```json
{"name":"schedule_send","arguments":{"agentId":"agt_0079e6a5","to":["ada@example.com"],"subject":"Friendly reminder","text":"Hi Ada, a quick reminder about invoice 1042.","preset":"tomorrow"}}
```

Result:

```json
{
  "id": "msch_007a8cc4",
  "dueAt": "2026-10-27T08:00:00.000Z"
}
```

### search

Call:

```json
{"name":"search","arguments":{"query":"invoice","limit":3}}
```

Result:

```json
{
  "results": [
    {
      "id": "msg_0079p57l",
      "threadId": "thr_0079meh8",
      "mailboxId": "mbx_0079gx0i",
      "folder": "inbox",
      "subject": "Invoice 1042",
      "snippet": "Hi, could you send invoice 1042 as a PDF? Thanks, Ada",
      "from": {
        "address": "ada@example.com",
        "name": "Ada Lovelace"
      },
      "date": "2026-10-26T17:42:04.636Z"
    }
  ]
}
```

### search_contacts

Call:

```json
{"name":"search_contacts","arguments":{"q":"ada","limit":3}}
```

Result:

```json
{
  "contacts": [
    {
      "id": "con_007ab32h",
      "name": "Ada Lovelace",
      "email": "ada@example.com",
      "phone": null,
      "title": "Head of Finance",
      "notes": "",
      "source": "mail",
      "company": {
        "id": "cmp_007adtsu",
        "name": "Example",
        "domain": "example.com"
      },
      "companyId": "cmp_007adtsu",
      "messageCount": 1,
      "firstContactAt": "2026-10-26T17:42:04.636Z",
      "lastContactAt": "2026-10-26T17:42:04.636Z",
      "createdAt": "2026-10-26T17:42:04.648Z",
      "updatedAt": "2026-10-26T17:42:04.985Z",
      "version": 2
    }
  ],
  "total": 1
}
```

### search_docs

Call:

```json
{"name":"search_docs","arguments":{"q":"billing"}}
```

Result:

```json
{
  "docs": [
    {
      "id": "doc_007bog8z",
      "title": "Billing playbook",
      "projectId": null,
      "parentId": null,
      "position": 1,
      "excerpt": "Send invoices on the 1st. Follow up after 7 days.\nEscalate to the account owner after 14 days.",
      "createdBy": {
        "type": "member",
        "id": "usr_0079xdeo"
      },
      "createdAt": "2026-10-26T17:42:05.486Z",
      "updatedAt": "2026-10-26T17:42:05.498Z",
      "version": 2
    }
  ]
}
```

### search_everything

Call:

```json
{"name":"search_everything","arguments":{"q":"invoice","limit":3}}
```

Result:

```json
{
  "query": "invoice",
  "groups": [
    {
      "type": "mail",
      "label": "Mail",
      "items": [
        {
          "type": "mail",
          "id": "msg_0079p57l",
          "title": "Invoice 1042",
          "subtitle": "Ada Lovelace <ada@example.com>",
          "snippet": "Hi, could you send invoice 1042 as a PDF? Thanks, Ada",
          "url": "/app/mail?mailbox=mbx_0079gx0i&folder=inbox&m=msg_0079p57l",
          "at": "2026-10-26T17:42:04.636Z"
        }
      ]
    }
  ],
  "tookMs": 4,
  "partial": false
}
```

### search_tasks

Call:

```json
{"name":"search_tasks","arguments":{"q":"invoice","limit":3}}
```

Result:

```json
{
  "count": 1,
  "tasks": [
    {
      "id": "tsk_007agkj7",
      "ref": "TSK-1",
      "title": "Follow up with Ada about invoice 1042",
      "status": "In progress",
      "assignee": "Sam Rivera",
      "priority": "high",
      "labels": [
        "billing"
      ],
      "due": "2026-11-03T00:00:00.000Z",
      "type": "task",
      "sprintId": null,
      "points": null,
      "checklist": {
        "total": 2,
        "done": 0
      }
    }
  ]
}
```

### send_email

Call:

```json
{"name":"send_email","arguments":{"agentId":"agt_0079e6a5","to":["ada@example.com"],"subject":"Your invoice 1042","text":"Hi Ada, here is invoice 1042. Thanks, Sam"}}
```

Result:

```json
{
  "status": "pending_approval",
  "approval": {
    "id": "apr_0079rvxy",
    "agentId": "agt_0079e6a5",
    "mailboxId": "mbx_0079gx0i",
    "threadId": null,
    "status": "pending",
    "to": [
      "ada@example.com"
    ],
    "cc": [],
    "bcc": [],
    "subject": "Your invoice 1042",
    "text": "Hi Ada, here is invoice 1042. Thanks, Sam",
    "html": null,
    "inReplyToId": null,
    "decidedBy": null,
    "decidedAt": null,
    "note": null,
    "messageId": null,
    "error": null,
    "expiresAt": "2026-11-02T17:42:04.756Z",
    "createdAt": "2026-10-26T17:42:04.757Z"
  }
}
```

### set_task_blocked_by

Call:

```json
{"name":"set_task_blocked_by","arguments":{"taskId":"tsk_007aua70","blockedBy":"tsk_007agkj7"}}
```

Result:

```json
{
  "blocked": true,
  "blockedBy": [
    {
      "ref": "TSK-1",
      "title": "Follow up with Ada about invoice 1042",
      "status": "doing"
    }
  ],
  "blocking": []
}
```

### set_thread_status

Call:

```json
{"name":"set_thread_status","arguments":{"threadId":"thr_0079meh8","status":"waiting"}}
```

Result:

```json
{
  "state": {
    "threadId": "thr_0079meh8",
    "status": "waiting",
    "assignee": null,
    "assignedAt": null,
    "doneAt": null
  }
}
```

### snooze_thread

Call:

```json
{"name":"snooze_thread","arguments":{"threadId":"thr_0079meh8","preset":"tomorrow"}}
```

Result:

```json
{
  "id": "msch_007a2uve",
  "threadId": "thr_0079meh8",
  "mailboxId": "mbx_0079gx0i",
  "dueAt": "2026-10-27T08:00:00.000Z"
}
```

### update_task

Call:

```json
{"name":"update_task","arguments":{"id":"TSK-1","status":"doing","assignee":"member:usr_0079xdeo"}}
```

Result:

```json
{
  "task": {
    "id": "tsk_007agkj7",
    "ref": "TSK-1",
    "projectId": "prj_007ajb9k",
    "number": 1,
    "title": "Follow up with Ada about invoice 1042",
    "notes": "She asked for a PDF copy.",
    "statusId": "sts_007aosqa",
    "statusName": "In progress",
    "statusColor": "#3b82f6",
    "status": "doing",
    "assignee": {
      "type": "member",
      "id": "usr_0079xdeo",
      "name": "Sam Rivera",
      "email": "sam@acme.io"
    },
    "assigneeId": "member:usr_0079xdeo",
    "priority": "high",
    "labels": [
      "billing"
    ],
    "type": "task",
    "start": null,
    "due": "2026-11-03T00:00:00.000Z",
    "parentId": null,
    "position": 1024,
    "source": null,
    "subtasks": {
      "total": 0,
      "done": 0
    },
    "checklist": {
      "total": 0,
      "done": 0
    },
    "commentCount": 0,
    "fields": {},
    "repeat": null,
    "completedAt
... (cut)
```

### upsert_contact

Call:

```json
{"name":"upsert_contact","arguments":{"email":"ada@example.com","name":"Ada Lovelace","title":"Head of Finance"}}
```

Result:

```json
{
  "contact": {
    "id": "con_007ab32h",
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "phone": null,
    "title": "Head of Finance",
    "notes": "",
    "source": "mail",
    "company": {
      "id": "cmp_007adtsu",
      "name": "Example",
      "domain": "example.com"
    },
    "companyId": "cmp_007adtsu",
    "messageCount": 1,
    "firstContactAt": "2026-10-26T17:42:04.636Z",
    "lastContactAt": "2026-10-26T17:42:04.636Z",
    "createdAt": "2026-10-26T17:42:04.648Z",
    "updatedAt": "2026-10-26T17:42:04.985Z",
    "version": 2
  }
}
```

### watch_task

Call:

```json
{"name":"watch_task","arguments":{"taskId":"tsk_007agkj7"}}
```

Result:

```json
{
  "taskId": "tsk_007agkj7",
  "watching": true,
  "count": 1,
  "watchers": [
    {
      "userId": "usr_0079xdeo",
      "name": "Sam Rivera",
      "email": "sam@acme.io",
      "source": "auto",
      "since": "2026-10-26T17:42:05.042Z"
    }
  ]
}
```

