mcp
POST /v1/mcp/connections
Create an MCP connection (Connect AI tool).
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. A scope that GET /v1/mcp/scopes does not offer to AI connections is also a 422: holding a permission is not enough to hand it to an assistant. 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 | — |
kind | string<token, oauth> | No | token = a pasted token; oauth = an AI app that signed in (docs/27 §3a). |
oauth_client_name | string | null | No | For kind: oauth, the app's own name as it registered. |
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 config for the connection's client, embedding the endpoint and token. The shape differs per client: Claude Code gets an http-typed server, Cursor a url +… |
config_file | object | Yes | Where that client reads config — e.g. .mcp.json. null when it has no file. |
command | object | Yes | A one-line alternative for a client with a command line (Claude Code), else null. It embeds the token, so treat it like the token. |
note | object | Yes | Set when the client cannot use a bearer token at all. chatgpt_needs_oauth: ChatGPT connects by OAuth sign-in only, so this token cannot reach it. |
Errors this endpoint can return
401 · 403 · 422 · 429