---
title: "Begin an OAuth connect for a chat-requested MCP server"
method: POST
path: "/v1/mcp-setup/oauth/start"
tags: ["mcp-setup"]
---

# Begin an OAuth connect for a chat-requested MCP server

`POST /v1/mcp-setup/oauth/start`

## Request

- Base URL: `https://api.patricia.app` (the document declares no server; this is the origin it was published from)
- URL: `https://api.patricia.app/v1/mcp-setup/oauth/start`
- Auth: HTTP bearer

Redeems the single-use setup link, then discovers the frozen server's authorization service and returns the URL to send the person to. Nothing is connected until the ceremony completes.

## Headers

- `X-Tenant-Id` string, nullable

## Request body

- McpSetupOAuthStartBody: The one-time setup token, and a client credential only if the server demanded one. **There is no address, no audience and no label here, and their absence is the design.** Those three were frozen when Patricia minted the link, under the requester's authority and, for a team server, under an approval bound to them. The console's own start accepts an address and an audience from the browser and defaults a new connection to team, so a body that carried them would let a personal request come back as a team connection with every console rule satisfied. ``client_id`` and ``client_secret`` are the same pair the console's credentials step collects, INHERITED from :class:`services.mcp_oauth.PastedClientCredentialFields` rather than restated, so a secret never arriving without an id, a blank id being refused, and an id being trimmed while a secret keeps every byte are one rule with one implementation. ``OAuthStartBody`` inherits the same base. They are the SECOND call of one connect, sent after this route answered that the server's sign-in service will not register Patricia on its own.
  - `client_id` string, nullable
  - `client_secret` string, nullable
  - `setup_token` string, password, required

## Response `200`

Successful Response

- McpSetupOAuthStartResponse: Where to send the person, and what the ceremony they are leaving for will come back as.
  - `authorize_url` string, required
  - `attempt_id` string, uuid, required
  - `expires_at` string, date-time, required

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden. Inspect response body `code` for the specific reason (for example: PERMISSION_DENIED, EMAIL_NOT_VERIFIED, TENANT_ACCESS_REQUIRED, ROLE_UNRESOLVED)
- `404`: Not found
- `409`: Conflict
- `422`: Validation error

---

[API](https://skmtc.dev/patricia/apis/patricia-api.md) · [All operations](https://skmtc.dev/patricia/apis/patricia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/patricia/apis/patricia-api/revisions/0dfb44495ea1?raw)
