English
Scopes and tools
An API key carries scopes of the form <domain>:<verb>, with read, write or * as the verb, and write covers read. The grammar and the full list of domains are in API scopes. This page says how the MCP server reads them.
A scope never grants more than the member who owns the key: an ordinary member's key with tables:write still cannot create a table, because that member cannot.
The domain of each tool
The server derives the required scope from the tool's name and effect: the prefix of the internal name gives the domain, the effect gives the verb.
| Tool prefix | Domain | Tools |
|---|---|---|
catalog., docs., workflow. | workflows | catalog_describe, catalog_node, docs_search, docs_read, workflow_list, workflow_read, workflow_describe, workflow_validate, workflow_compile, workflow_propose_new, workflow_propose_changes (read); workflow_create_draft, workflow_update_draft, workflow_publish (write) |
execution. | executions | execution_list, execution_read (read) |
workflow.test_run (exception) | executions | workflow_test_run (write) |
mailbox., journal., coverage. | mailboxes | mailbox_list, mailbox_stats, mailbox_cluster, mailbox_search, journal_unmatched, coverage_simulate (read) |
connections. | connections | connections_list (read) |
tables. | tables | tables_list (read); tables_create (write) |
A read tool requires <domain>:read; a write tool requires <domain>:write. One exception: workflow_test_run writes nothing outside, but it creates an execution and makes the AI nodes call their model, which costs money. It requires executions:write, the scope of the matching REST route POST /workflows/{id}/test, so a read-only key cannot spend. A key satisfies a requirement when it holds the exact scope, the write scope of the domain for a read requirement, or the domain's *. The other domains of the API (messages, contacts, admin…) have no MCP tool today.
Each tool's description in tools/list ends with the scope it needs, for example "Requires scope workflows:write.", so an assistant can explain a refusal to you.
How tools/list is filtered
tools/list returns only the tools the key may call. A key with workflows:read lists the eleven read tools of the workflows domain and nothing else: no workflow_publish, no mailbox_list. Announcing a tool that would then be refused would send the assistant in circles.
Through a browser session instead of a key, the member has every scope their role allows, and the full list appears.
The shape of a refusal
A client can call a tool without listing it, so tools/call checks the scope again. A refusal is not a protocol error: it is a tool result with isError: true, so that the assistant reads it and reacts.
json
{
"isError": true,
"content": [
{ "type": "text", "text": "{\"error\":{\"code\":\"api_key.scope_missing\",\"message\":\"this key lacks the scope workflows:write required by workflow.publish\"}}" }
],
"structuredContent": {
"error": {
"code": "api_key.scope_missing",
"message": "this key lacks the scope workflows:write required by workflow.publish"
}
}
}The same shape carries the other refusals. code is stable and meant for programs:
| Code | Meaning |
|---|---|
api_key.scope_missing | the key lacks the scope the tool requires |
tool.not_found | no tool has this name |
tool.invalid_input | the arguments do not match the tool's inputSchema (unknown field, wrong type, bound exceeded) |
tool.resource_not_found | the workflow, mailbox, execution, node type or page does not exist or belongs to another member |
workflow.archived, workflow.invalid_graph, and other workflow.… codes | a business refusal: an archived workflow cannot be edited, a stored graph is unreadable, a draft cannot be test-run because it is invalid |
Two outcomes are not refusals: workflow_publish answering ok: false with the blocking errors, and workflow_propose_changes answering ok: false with a rejected operation. Both are normal results that describe what to fix.
Without a valid key, the request never reaches MCP: the endpoint answers 401 with auth.unauthenticated in the error format of the API. An expired or revoked key gets the same answer.
Example keys
A read-only analyst. An assistant that explains a mailbox, proposes automations and diagnoses failed runs, without ever changing anything:
text
workflows:read executions:read mailboxes:read connections:read tables:readIt can describe the catalog, read every workflow, compile and propose, read executions, search and group emails, and see which connections and tables exist. It cannot run a test run (that takes executions:write), nor create, update or publish a workflow, nor create a table.
A builder. An assistant that builds workflows end to end, with publication:
text
workflows:write executions:write mailboxes:read connections:read tables:readworkflows:write covers the read tools of the domain: read, propose, create the draft, update it, publish it. executions:write adds the test runs on real emails. Keep tables:read unless the member is an administrator who wants the assistant to create tables, in which case give tables:write.
A key for one job. Scopes are per domain, so a key can be narrower still: mailboxes:read alone for an assistant that only reports on mailboxes, or workflows:read plus executions:read for one that only investigates failed runs.
Give a key an expiry when you create it if it serves a one-off task, and revoke it afterwards: the next call is refused.