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

# Mcp server

# MCP tools

Auto-generated from `src/mcp/**/*.tools.ts`. Do not edit by hand — run `/mcp-docs` to regenerate.

## board

### `search-boards-by-name`

Search for boards by name, optionally filtered by type

* **Scopes:** `boards:read`
* **Throttle:** `1`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `name` | `string` | no | — | The name of the board to search for |
| `aptletType` | `enum: ticket \| deal \| location \| adsource \| reviews \| screening \| answers` | no | — | Filter by board type |
| `limit` | `number` | no | `100` | Number of results to return |
| `offset` | `number` | no | `0` | Number of results to skip |

### `add-tab-view-to-board`

Create a page and attach it as a tab view to a board

* **Scopes:** `boards:write`
* **Throttle:** `5`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `aptletUuid` | `string` | yes | — | The UUID of the board to add the page to |
| `tabViewName` | `string` | yes | — | The name of tab view |
| `files` | `array<object>` | yes | — | List of files with name and content. Each: `{ name: string, content: string }` |

### `create-card`

Create a new card

* **Scopes:** `boards:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `aptletUuid` | `string` | yes | — | The UUID of the board to create a card of |
| `name` | `string` | yes | — | The name of the card |
| `description` | `string` | no | — | The description of the card |
| `assignee` | `string` | no | — | The assignee ID of the card |
| `createdConduit` | `string` | no | `"aptly-mcp"` | The conduit through which the card was created |

### `update-card-field`

Update a single field on a card

* **Scopes:** `boards:write`
* **Throttle:** `5`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `cardId` | `string` | yes | — | The ID of the card to update |
| `fieldName` | `string` | yes | — | The display name of the field to update, exactly as returned by search-cards (e.g. "Stage", "Assignee", or a custom field name). When two standard fields share a name, the board's own field takes precedence. |
| `value` | `unknown` | yes | — | The new value, in the same shape search-cards returns it: a string, number, boolean, ISO date string, or `{ amount, currency }` for money fields. |

### `create-card-comment`

Create a comment on a card

* **Scopes:** `boards:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `cardId` | `string` | yes | — | The ID of the card to comment on |
| `content` | `string` | yes | — | The comment content |
| `mentions` | `array<string>` | no | — | User IDs mentioned in the comment |

### `search-cards`

Search for cards by a search query, optionally filtered by board UUID

* **Scopes:** `boards:read`
* **Throttle:** `1`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `query` | `string` | no | — | Search term matched against the searchIndex field |
| `aptletUuid` | `string` | no | — | Filter cards by board UUID |
| `limit` | `number` | no | `1000` | Number of results to return |
| `offset` | `number` | no | `0` | Number of results to skip |

### `get-card-tasks`

Get tasks for a card

* **Scopes:** `boards:read`
* **Throttle:** `1`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `cardId` | `string` | yes | — | The ID of the card to get tasks for |
| `limit` | `number` | no | `100` | Number of results to return |
| `offset` | `number` | no | `0` | Number of results to skip |

### `create-card-task`

Create a task for a card

* **Scopes:** `boards:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `cardId` | `string` | yes | — | The ID of the card to create the task for |
| `title` | `string` | yes | — | The task title |
| `checked` | `boolean` | yes | — | Whether the task is completed |
| `dueAt` | `string` | no | — | Due date in ISO 8601 format |

### `assign-user-to-card-task`

Assign a user to a card task

* **Scopes:** `boards:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `taskId` | `string` | yes | — | The ID of the task to assign |
| `assigneeId` | `string` | yes | — | The ID of the user to assign to the task |

## calendar

### `get-user-calendars`

Get all calendars the authenticated user can access (owned + shared), without events.

* **Scopes:** `inboxes:read`
* **Throttle:** `1`

**Parameters**

*No parameters.*

### `get-user-calendars-with-events`

Get all calendars the authenticated user can access (owned + shared) along with their events. Optionally filter events by a date range and/or by a case-insensitive substring of the event title; recurring event instances overlapping the range are included.

* **Scopes:** `inboxes:read`
* **Throttle:** `2`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `dateFrom` | `string (ISO 8601 datetime)` | no | — | Only include events ending on or after this ISO 8601 datetime (e.g. 2026-04-01T00:00:00Z). Required together with dateTo. |
| `dateTo` | `string (ISO 8601 datetime)` | no | — | Only include events starting on or before this ISO 8601 datetime (e.g. 2026-05-01T00:00:00Z). Required together with dateFrom. |
| `name` | `string` | no | — | Case-insensitive substring match against the event title (e.g. "standup") |

### `create-calendar-event`

Create a new calendar event in one of the user’s calendars

* **Scopes:** `inboxes:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `calendarId` | `string` | yes | — | ID of the calendar to create the event in (from get-user-calendars-with-events) |
| `cardId` | `string` | no | — | ID of the card to associate the event with |
| `title` | `string` | yes | — | Event title |
| `description` | `string` | no | — | Event description |
| `location` | `string` | no | — | Event location (formatted address or free-form text) |
| `start` | `string (ISO 8601 datetime)` | yes | — | Event start ISO 8601 datetime (e.g. 2026-05-12T15:00:00Z) |
| `end` | `string (ISO 8601 datetime)` | yes | — | Event end ISO 8601 datetime (e.g. 2026-05-12T16:00:00Z) |
| `allDay` | `boolean` | no | `false` | Whether the event spans the entire day |
| `attendees` | `array<object>` | no | — | Event attendees. Each: `{ email: string (email), name?: string, response?: unknown \| needsAction \| accepted \| declined \| tentative (default needsAction) }` |

## files

### `create-file-upload-url`

Step 1 of attaching a file to an entity (e.g. a channel). Uploading a file is a three-step flow:

1. Call this tool to create a pre-signed S3 upload URL. It returns `{ fileId, url, fields }`.
2. Upload the file bytes by sending an HTTP POST to `url` as multipart/form-data, including every key/value from `fields` first, then a `file` field containing the file contents (the `file` field must be last). S3 responds with 204 No Content on success.
3. Call `complete-file-upload` with the returned `fileId` to finalize the upload and attach the file to the entity.
   The URL expires after 5 minutes, so perform step 2 promptly.

* **Throttle:** `1`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `name` | `string` | yes | — | The file name, including its extension |
| `extension` | `enum: vcf \| docx \| csv \| xml \| doc \| pdf \| png \| jpg \| svg \| jpeg \| wav \| mpg \| mp4 \| gif \| xls \| xlsx \| numbers \| zip \| txt \| md \| ppt \| pptx \| tiff \| tar \| rar \| ics \| mp3 \| heic \| heif` | yes | — | Lowercase file extension without the leading dot |
| `contentType` | `enum: audio/wav \| audio/x-wav \| audio/basic \| audio/L24 \| audio/mp4 \| audio/mpeg \| audio/ogg \| audio/vorbis \| audio/vnd.rn-realaudio \| audio/3gpp \| audio/3gpp2 \| audio/ac3 \| audio/vnd.wave \| audio/webm \| audio/amr-nb \| audio/amr \| video/mpeg \| video/mp4 \| video/quicktime \| video/webm \| video/3gpp \| video/3gpp2 \| video/3gpp-tt \| video/H261 \| video/H263 \| video/H263-1998 \| video/H263-2000 \| video/H264 \| image/jpg \| image/jpeg \| image/gif \| image/png \| image/bmp \| image/heic \| image/heif \| text/vcard \| text/csv \| text/xml \| text/rtf \| text/richtext \| text/calendar \| text/directory \| text/x-markdown \| application/pdf \| application/xls \| application/xlsx \| application/vnd.openxmlformats-officedocument.spreadsheetml.sheet \| application/vnd.openxmlformats-officedocument.wordprocessingml.document \| application/numbers \| application/zip \| application/x-zip-compressed \| application/zip-compressed` | yes | — | The MIME type of the file |
| `size` | `number` | yes | — | File size in bytes (max 50 MB) (max 52428800) |
| `attachEntityType` | `enum: channel` | yes | — | Type of entity to attach the file to. Currently only 'channel'. |
| `attachEntityId` | `string` | yes | — | ID of the entity named by attachEntityType. For 'channel' this is the channel's account id; it must reference an existing channel. |

### `complete-file-upload`

Step 3 (final) of attaching a file to an entity. Call this only after `create-file-upload-url` (step 1) and successfully POSTing the file bytes to the returned url (step 2), passing the `fileId` from step 1. Marks the upload complete, finalizes the file record, and returns the `fileId` and its download `url`.

* **Throttle:** `1`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `fileId` | `string` | yes | — | The fileId returned by create-file-upload-url |

## inbox

### `get-user-email-inboxes`

Get the email inboxes the authenticated user selected on the connect page

* **Scopes:** `inboxes:read`
* **Throttle:** `1`

**Parameters**

*No parameters.*

### `get-user-phone-inboxes`

Get all phone (SMS/voice) inboxes available for the authenticated user

* **Scopes:** `inboxes:read`
* **Throttle:** `1`

**Parameters**

*No parameters.*

### `get-inbox-history`

Get inbox history (status changes, assignments, folder moves, topic edits, email sends, email opens, automation runs) for an inbox. Optionally narrow to a specific thread (streamId) or to entries performed by a specific user (userId). When filtered by userId, only user-driven entries are returned — email-open and automation events have no user actor and are excluded.

* **Scopes:** `inboxes:read`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `channelId` | `string` | yes | — | ID of the inbox (email or phone) to fetch history from (from get-user-email-inboxes or get-user-phone-inboxes) |
| `streamId` | `string` | no | — | Filter to history on a specific thread within the inbox (from search-emails or search-phone-messages results) |
| `userId` | `string` | no | — | Filter to history entries performed by a specific user (from get-company-users) |
| `limit` | `number` | no | `1000` | Maximum number of entries to return |

### `search-emails`

Search emails across From/To names and email addresses, subject, body, and attachment content. Optionally filter by inbox and date range.

* **Scopes:** `inboxes:read`
* **Throttle:** `2`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `query` | `string` | no | — | Search by From name/email, To name/email, subject, email body, or attachment content |
| `channelId` | `string` | no | — | Filter emails by inbox id |
| `from` | `array<string>` | no | — | Filter to emails sent from any of these email addresses (matched against From) |
| `to` | `array<string>` | no | — | Filter to emails sent to any of these email addresses (matched against To) |
| `assigneeId` | `string` | no | — | Filter to email threads assigned to this user id |
| `personTypeId` | `string` | no | — | Filter to email threads tagged with this person type id (from get-person-types) |
| `topicId` | `string` | no | — | Filter to email threads tagged with this topic id (from get-topics) |
| `direction` | `enum: in \| out` | no | — | Filter by direction: "in" for received/inbound emails, "out" for sent/outbound emails |
| `dateFrom` | `string (ISO 8601 datetime)` | no | — | Filter emails published on or after this ISO 8601 datetime (e.g. 2026-04-01T00:00:00Z) |
| `dateTo` | `string (ISO 8601 datetime)` | no | — | Filter emails published on or before this ISO 8601 datetime (e.g. 2026-04-17T23:59:59Z) |
| `limit` | `number` | no | `1000` | Number of results to return |
| `offset` | `number` | no | `0` | Number of results to skip |

### `send-email`

Send a new email message from one of the user's email inboxes. To include files, upload them first via create-file-upload-url + complete-file-upload, then either pass their fileIds as attachmentIds (regular attachments) or embed an image inline by adding an `<img>` tag in the HTML body whose src is the file's download url.

* **Scopes:** `inboxes:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `channelId` | `string` | yes | — | ID of the email inbox to send from |
| `to` | `array<object>` | yes | — | Recipients (at least 1). Each: `{ email: string (email), name?: string }` |
| `cc` | `array<object>` | no | — | CC recipients. Each: `{ email: string (email), name?: string }` |
| `bcc` | `array<object>` | no | — | BCC recipients. Each: `{ email: string (email), name?: string }` |
| `subject` | `string` | yes | — | Email subject |
| `body` | `string` | yes | — | Email body. Plain text or HTML. To embed an uploaded image inline, put an `<img>` tag whose src is the download url returned by complete-file-upload (.../cdn/storage/AptlyFiles/`<fileId>`/original/...). Inline images are auto-detected from these urls, tagged with a data-inline-image-id attribute, and registered on the draft; do not also list them in attachmentIds. |
| `attachmentIds` | `array<string>` | no | — | IDs of files/images to attach. To obtain an id, upload each file first: (1) call create-file-upload-url with attachEntityType "channel" and the same channelId to get `{ fileId, url, fields }`; (2) HTTP POST the file bytes to `url` as multipart/form-data (all `fields` first, then a `file` field); (3) call complete-file-upload with the `fileId`. Then pass the resulting fileIds here. Each must reference a finished upload. |
| `streamId` | `string` | no | — | If provided, send the email as a reply into this existing thread instead of starting a new one (from search-emails results) |

### `create-email-draft`

Create a draft email in one of the user's email inboxes. To include files, upload them first via create-file-upload-url + complete-file-upload, then either pass their fileIds as attachmentIds (regular attachments) or embed an image inline by adding an `<img>` tag in the HTML body whose src is the file's download url.

* **Scopes:** `inboxes:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `channelId` | `string` | yes | — | ID of the email inbox to send from |
| `to` | `array<object>` | yes | — | Recipients (at least 1). Each: `{ email: string (email), name?: string }` |
| `cc` | `array<object>` | no | — | CC recipients. Each: `{ email: string (email), name?: string }` |
| `bcc` | `array<object>` | no | — | BCC recipients. Each: `{ email: string (email), name?: string }` |
| `subject` | `string` | yes | — | Email subject |
| `body` | `string` | yes | — | Email body. Plain text or HTML. To embed an uploaded image inline, put an `<img>` tag whose src is the download url returned by complete-file-upload (.../cdn/storage/AptlyFiles/`<fileId>`/original/...). Inline images are auto-detected from these urls, tagged with a data-inline-image-id attribute, and registered on the draft; do not also list them in attachmentIds. |
| `attachmentIds` | `array<string>` | no | — | IDs of files/images to attach. To obtain an id, upload each file first: (1) call create-file-upload-url with attachEntityType "channel" and the same channelId to get `{ fileId, url, fields }`; (2) HTTP POST the file bytes to `url` as multipart/form-data (all `fields` first, then a `file` field); (3) call complete-file-upload with the `fileId`. Then pass the resulting fileIds here. Each must reference a finished upload. |
| `streamId` | `string` | no | — | If provided, append the draft to this existing email thread instead of creating a new stream (from search-emails results) |

### `send-sms`

Send an SMS from one of the user's phone inboxes

* **Scopes:** `inboxes:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `channelId` | `string` | yes | — | ID of the phone inbox to send from |
| `to` | `array<object>` | yes | — | SMS recipients (at least 1). Each: `{ number: string, name?: string }` |
| `body` | `string` | yes | — | SMS message text |

### `archive-email`

Archive an email thread

* **Scopes:** `inboxes:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `streamId` | `string` | yes | — | The streamId of the email thread to archive (from search-emails results) |

### `reopen-email`

Reopen an archived email thread

* **Scopes:** `inboxes:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `streamId` | `string` | yes | — | The streamId of the email thread to reopen (from search-emails results) |

### `archive-phone-message`

Archive a phone message thread

* **Scopes:** `inboxes:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `streamId` | `string` | yes | — | The streamId of the phone message thread to archive (from search-phone-messages results) |

### `reopen-phone-message`

Reopen an archived phone message thread

* **Scopes:** `inboxes:write`
* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `streamId` | `string` | yes | — | The streamId of the phone message thread to reopen (from search-phone-messages results) |

### `search-phone-messages`

Search SMS and voice messages across From/To names and phone numbers, and message content. Optionally filter by inbox and date range.

* **Scopes:** `inboxes:read`
* **Throttle:** `2`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `query` | `string` | no | — | Search by From name/number, To name/number, or SMS message content |
| `channelId` | `string` | no | — | Filter messages by phone inbox id |
| `from` | `array<string>` | no | — | Filter to messages sent from any of these phone numbers (matched against From) |
| `to` | `array<string>` | no | — | Filter to messages sent to any of these phone numbers (matched against To) |
| `assigneeId` | `string` | no | — | Filter to phone message threads assigned to this user id |
| `personTypeId` | `string` | no | — | Filter to phone message threads tagged with this person type id (from get-person-types) |
| `topicId` | `string` | no | — | Filter to phone message threads tagged with this topic id (from get-topics) |
| `direction` | `enum: in \| out` | no | — | Filter by direction: "in" for received/inbound messages, "out" for sent/outbound messages |
| `dateFrom` | `string (ISO 8601 datetime)` | no | — | Filter message published on or after this ISO 8601 datetime (e.g. 2026-04-01T00:00:00Z) |
| `dateTo` | `string (ISO 8601 datetime)` | no | — | Filter message published on or before this ISO 8601 datetime (e.g. 2026-04-17T23:59:59Z) |
| `limit` | `number` | no | `1000` | Number of results to return |
| `offset` | `number` | no | `0` | Number of results to skip |

### `get-topics`

Get all inbox topics defined for the company

* **Scopes:** `inboxes:read`
* **Throttle:** `1`

**Parameters**

*No parameters.*

## knowledge

### `retrieve-knowledge-documents`

Retrieve relevant knowledge documents from the knowledge base using a search query

* **Throttle:** `2`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `query` | `string` | yes | — | The search query to retrieve knowledge documents |
| `limit` | `number` | no | `10` | Number of documents to return (min 5, max 20) |

### `create-knowledge-document`

Create a new knowledge document with optional HTML content. Can be linked to a board, card, or parent document.

* **Throttle:** `2`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `name` | `string` | yes | — | Title of the knowledge document |
| `markdown` | `string` | no | — | Initial markdown content of the document. Defaults to empty. |
| `aptletUuid` | `string` | no | — | Board UUID to associate the document with |
| `aptletInstanceId` | `string` | no | — | Card ID to link the document to |
| `parentId` | `string` | no | — | Parent knowledge document ID for nested pages |
| `accessType` | `enum: public \| private` | no | `"public"` | Access level. Defaults to public. |

### `update-knowledge-document`

Update the title, content, or access level of an existing knowledge document. When html is provided, it replaces the entire document body.

* **Throttle:** `3`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `id` | `string` | yes | — | ID of the knowledge document to update |
| `name` | `string` | no | — | New title for the document |
| `markdown` | `string` | no | — | New markdown content — replaces the existing content entirely when provided |
| `accessType` | `enum: public \| private` | no | — | New access level for the document |

## person

### `search-persons`

Search persons by full name, email, phone number or address, and/or filter by person type. All parameters are optional.

* **Scopes:** `contacts:read`
* **Throttle:** `1`

**Parameters**

| Name | Type | Required | Default | Description |
| - | - | - | - | - |
| `query` | `string` | no | — | Search by full name, email, phone number, or address |
| `typeId` | `string` | no | — | Filter to persons of this person type id (from get-person-types) |
| `limit` | `number` | no | `100` | Number of results to return |
| `offset` | `number` | no | `0` | Number of results to skip |

### `get-person-types`

Get all person types (contact categories) defined for the company

* **Scopes:** `contacts:read`
* **Throttle:** `1`

**Parameters**

*No parameters.*

## user

### `get-company-users`

Get all users in the authenticated user’s company. Returns each user’s id and full name.

* **Scopes:** `contacts:read`
* **Throttle:** `1`

**Parameters**

*No parameters.*


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.