Authentication
Send an API key as a bearer token. The key must carry the mcp.manage permission; a key without it is refused with 403, not 404.
Where your organisation id goes
This endpoint takes org_id as a field in the JSON body.
Your organisation id is on the API keys screen in your dashboard, beside the key itself. It is the same id in every call you make.
Try it
Replace anything in angle brackets with your own values, and the key placeholder with a key from your dashboard.
curl -X POST https://api.zinndigital.com/v1/mcp/connections \
-H "Authorization: Bearer zdk_live_…" \
-H "Content-Type: application/json" \
-d '{ "name": <string>, "scopes": <string[]> }'Signed in? The API console in your dashboard fills in your real organisation id and your own key, and runs the request against the live API so you can see the actual response. Open this endpoint in the API console
Details
Mints a per-tool MCP connection and returns the full `zmcp_…` token **once** (only its hash is stored) plus a paste-ready client config snippet. The requested `scopes` must be permissions the caller already holds in the target org — an unheld scope is a `403` (a connection can never out-scope its creator), an unknown one a `422`. An optional spend cap bounds AI-triggered paid actions. Requires `mcp.manage`.
Request body
| Name | Type | Required | What it is |
|---|---|---|---|
name | string | Yes | — |
client | McpClient | No | The AI client a connection is for (informational). |
scopes | string[] | Yes | RBAC permission keys to grant the token. Each must be a permission the caller holds in the target org (a connection can never out-scope its creator); an unheld scope is a `403`,… |
sandbox | boolean | No | — |
org_id | Uuid | null | No | The org the connection belongs to. Defaults to the caller's sole managed org. |
spend_cap_minor | integer | null | No | Optional per-window paid-action budget (integer minor units). Null = no cap. |
spend_currency | CurrencyCode | No | ISO 4217 currency code (money is minor units + this code — CLAUDE.md §2.8). |
spend_window_seconds | integer | No | — |
Response
| Name | Type | Required | What it is |
|---|---|---|---|
id | Uuid | Yes | UUIDv7 identifier — sortable by creation time (docs/02 §8). |
name | string | Yes | — |
client | McpClient | Yes | The AI client a connection is for (informational). |
prefix | string | Yes | The token's public lookup prefix (not a secret). |
scopes | string[] | Yes | The RBAC permission keys this connection's token may exercise. |
sandbox | boolean | Yes | — |
spend_cap_minor | integer | null | No | Optional per-window budget (integer minor units, CLAUDE.md §2.8) for AI-triggered paid actions. Null = no cap. |
spend_currency | CurrencyCode | No | ISO 4217 currency code (money is minor units + this code — CLAUDE.md §2.8). |
spend_window_seconds | integer | Yes | The rolling window the spend cap applies over. |
last_used_at | string | null | No | — |
revoked_at | string | null | No | — |
created_at | string | Yes | — |
token | string | Yes | The full `zmcp_…` token, shown exactly once. |
endpoint | string | Yes | The MCP protocol endpoint URL to configure in the AI client. |
config | object | Yes | A paste-ready MCP client config snippet embedding the endpoint + token. |
Errors this endpoint can return
401 · 403 · 422 · 429