The MCP server does not have a tool per feature. Through three general tools, an AI client reaches every operation of the REST API except file uploads, always as you and with your permissions. A fourth tool returns your own profile. When the API gains a feature, clients can use it straight away.
| Tool | Title clients show | What it does |
|---|---|---|
search_api | Search the API | Finds API operations and describes them |
api_read | Read from the API | Sends a GET to an API operation |
api_write | Write to the API | Sends a POST, PATCH or DELETE |
get-current-user-tool | Get current user | Returns your profile |
Three tools only read. Write to the API is marked as a tool that can change data, so clients ask you to approve it by default. Most clients let you allow it for one conversation or permanently. Permissions and safety explains what a client may do.
How a client uses the tools
Every client also receives a short set of instructions from the server. They describe three steps: find the operation with search_api, read what it accepts, then call it with api_read or api_write. They also tell the client that:
- work item paths accept issue keys such as
ACM-12 - user filters accept
me - deleting needs
confirm: true, sent only after you agreed, and only works when your organisation allows it - text is added to a Drive document with
mode: append, because without it the whole document is replaced
search_api
Finds API operations and describes them. It only returns the API's own documentation, never data from your organisation.
| Input | Type | Required | Description |
|---|---|---|---|
query | string | no | Keywords, such as link or log . |
operation_id | string | no | An id from a search result, such as work-items.links.store. |
- With
query, it returns at most 12 matches as{id, method, path, summary}, plus ahintfor the next step. - With
operation_id, it describes that operation: its description, the permission it needs, path parameters, query parameters, filters, sorts, includes, body fields, the feature it belongs to, and one or two examples. The id works with or without theapi.v2.prefix. - Without either input, it lists every operation id, grouped by area.
Operations your organisation cannot use are left out: those of areas your organisation does not use, deletes while Allow destructive actions is off, and file uploads.
api_read
Sends a GET to any API operation.
| Input | Type | Required | Description |
|---|---|---|---|
path | string | yes | The path below /api, with its placeholders filled, such as work-items. |
query | object | no | Query parameters, such as {"filter": . |
Paths and query
- An empty path lists the resources the API offers.
- The path may start with
/api/v2; the prefix is ignored. - The whole path is at most 256 characters. Its segments use only letters, digits,
-and_, and every placeholder must be filled in. - Work item paths accept issue keys, such as
work-items/ACM-12. User filters acceptme. - Query objects nest at most three levels deep, such as
filter[due_date][gte], with at most 60 parameters in all. - Null values are left out. Lists become comma-separated values.
Lists and paging
Lists come back in pages of 10 in the summary view, unless the call asks for something else. To get the next page, pass the previous answer's meta.page.next_cursor as cursor. When next_cursor is null, there are no more pages.
Some lists also accept a page number. Their meta.page always has current_page and last_page, which are null unless the call sends page. A call that sends page always gets next_cursor: null. The last page is the one where current_page reaches last_page.
api_write
Sends a POST, PATCH or DELETE to any API operation.
| Input | Type | Required | Description |
|---|---|---|---|
method | string | yes | POST, PATCH or DELETE. |
path | string | yes | The path below /api, such as work-items. |
query | object | no | Query parameters, such as {"view": . |
body | object | no | The JSON body, such as {"link_type": . |
confirm | boolean | no | true for a delete or an overwrite, and only after you agreed to it. |
The path and query rules of api_read apply here too. The body is checked exactly as the REST API checks it: a field the operation does not accept is refused by name, never ignored.
Deleting needs two things: Allow destructive actions must be on for your organisation, and the call must carry confirm: true. Without either, nothing is deleted. What counts as deleting lists the operations this covers. On DELETE /projects/{project}, the query {"force": true} deletes the project permanently, instead of a delete that can be undone.
Replacing the whole text of a Drive document also needs confirm: true, because it discards formatting and anything others typed since the client read it. Adding text with {"mode": "append"} in the body needs no confirmation.
api_write refuses these calls before anything runs:
| Refusal | Problem type |
|---|---|
| A delete while Allow destructive actions is off | forbidden-by-policy |
A delete or overwrite without confirm: | validation-failed |
| A file upload | endpoint-not-found |
| A method the operation does not accept | method-not-allowed |
Neither of the first two reads the record before refusing, so a refusal never tells whether the record exists.
Writes over MCP are not protected against duplicates. An Idempotency-Key is neither needed nor used, so a client that is unsure whether a write went through should read before it tries again.
If an app's sign-in also asked for REST API scopes, it is held to those scopes over MCP as well. Sign-in scopes never include deleting, so such an app cannot delete over MCP.
get-current-user-tool
Returns your own profile. It takes no input.
{
"id": 34,
"name": "Jamie Doe",
"email": "jamie@acme.example",
"email_verified_at": "2026-02-03T09:15:00+00:00",
"timezone": "Europe/Amsterdam",
"locale": "en",
"job_title": "Project manager",
"date_employed": "2025-09-01",
"roles": ["Project manager"],
"created_at": "2025-08-28T14:02:11+00:00"
}
The timestamps include a time zone offset. date_employed is a date (YYYY-MM-DD). Fields with no value are null.
Responses
A successful answer is the API's own response body with two changes:
- A
statuskey comes first, with the HTTP status the API answered, such as200or201. - Every
linksmap is removed. A client continues a list withmeta.page.next_cursor, and calls other records by path.
A delete answers without a body, so the tool returns {"status": 204}.
An answer may hold about 30,000 characters. The limit counts bytes, so text with accents or emoji fits a little less. A longer answer is shortened, never silently: meta.mcp_truncated says what was cut. When rows were left out of a list, next_cursor is cleared, because following it would skip them. The hint says how to page on without gaps. This is the meta object of a shortened list:
{
"page": {
"per_page": 10,
"next_cursor": null,
"prev_cursor": null,
"total": null
},
"mcp_truncated": {
"reason": "response_budget",
"returned": 6,
"omitted": 4,
"hint": "Only the first 6 of 10 rows fit. Repeat this request with per_page=6 (and the same cursor, if any) to page through without gaps."
}
}
When a single long text is the problem, mcp_truncated lists the shortened fields instead, each with its pointer, the characters kept and the original length.
Errors
A refused call comes back as a tool error that carries the same problem document the REST API returns, with the same status and type. Something you may not see answers 404, exactly as over HTTP.
{
"type": "https://developers.plnnrly.com/api/v2/problems/forbidden-by-policy",
"title": "Forbidden by policy",
"status": 403,
"detail": "This organisation does not allow AI clients to delete data. An administrator can turn on Allow destructive actions under Settings › Administration › MCP & API.",
"instance": "/api/v2/work-items/ACM-12",
"request_id": "01M4WVYY50K7T2B9QH3D6N8RXP"
}
A path or query the tools cannot use answers malformed-request. Its errors[].code is invalid (a path or value that is not allowed), too_many (more than 60 query parameters) or too_deep (nested more than three levels).
Limits
- Each user may send 60 MCP requests a minute. This counts every request the client sends to the server, including the ones that set up the connection and list the tools, not only tool calls. A client over the limit gets
429. - The REST API's own rate limits and rate units do not apply to calls made over MCP.
- An answer holds about 30,000 characters.
- The client renews its sign-in every hour. A client unused for 30 days has to sign in again.
Limits at a glance lists every limit of the REST API.
What MCP cannot do
- Upload files. Adding an attachment or a Drive file needs a byte upload that MCP clients cannot make. Use the REST API with an API token; see Files: upload and download.
- Delete while the switch is off. Deletes only work while your organisation allows destructive actions.