> ## Documentation Index
> Fetch the complete documentation index at: https://docs.semicola.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Authenticate an interactive or headless client to the v3 MCP endpoint with OAuth or an API key.

Connect to `https://api.semicola.com/mcp/v3` with OAuth or an API key. The credential decides the home
account, the accounts you can reach and what you may do in each. The URL does not select buyer or
seller behavior.

| Use                      | When                                                                                                     |
| ------------------------ | -------------------------------------------------------------------------------------------------------- |
| **OAuth**                | A person is present: Codex, Claude Code, Claude, ChatGPT or any interactive MCP host.                    |
| **User API key**         | Headless automation. Keep it in a secret manager and send `Authorization: Bearer <key>`. It acts as you. |
| **Organization API key** | Shared service integrations owned by the organization rather than one person.                            |

Grant only what the integration needs. A tool can appear in `tools/list` and still refuse a write when
your role lacks the permission. After authenticating, call `get_status` to confirm the account.

<Warning>
  An agent must never ask for a key in chat and cannot read an existing key back. Direct the person
  to **Settings → API access** in the Semicola app. A new key's secret is shown once.
</Warning>

## How OAuth works here

Semicola follows the MCP authorization spec. A compliant client needs only the endpoint URL.

<Steps>
  <Step title="Challenge">
    An unauthenticated request gets `401` and a challenge that points at the discovery document:

    ```http theme={null}
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: Bearer error="unauthorized", error_description="Authorization needed",
      resource_metadata="https://api.semicola.com/.well-known/oauth-protected-resource/mcp/v3"
    ```
  </Step>

  <Step title="Discovery">
    The protected-resource document names the exact resource and its authorization server:

    ```json theme={null}
    {
      "resource": "https://api.semicola.com/mcp/v3",
      "authorization_servers": ["https://auth.semicola.com"],
      "bearer_methods_supported": ["header"],
      "scopes_supported": ["mcp:access"],
      "resource_name": "Semicola"
    }
    ```

    Follow the `resource_metadata` URL from the challenge rather than building it yourself, and read
    the authorization server from this document instead of hard-coding it. The
    authorization server's own metadata is also mirrored at
    `https://api.semicola.com/.well-known/oauth-authorization-server` for clients that look on the
    resource's origin.
  </Step>

  <Step title="Registration">
    Clients register themselves with dynamic client registration (RFC 7591) as public clients
    (`token_endpoint_auth_method: none`). Redirect URIs must use https; `localhost` is allowed.
  </Step>

  <Step title="Sign-in and consent">
    The client runs the authorization-code flow with PKCE (`S256`) and passes
    `resource=https://api.semicola.com/mcp/v3`. The person signs in on the Semicola login page, picks
    the account to connect if they have several, and approves the client. The browser then shows
    "Authentication complete" and hands control back to the client.
  </Step>

  <Step title="Tokens">
    The client receives a short-lived access token and a rotating refresh token, and sends
    `Authorization: Bearer <access token>` on every request.
  </Step>
</Steps>

## Resource binding

Tokens are bound to the exact MCP URL they were issued for. Semicola checks the signature, issuer,
expiry and that the token's audience equals the URL being called. A token issued for `/mcp/v3` is
refused on the REST API, on the v2 endpoints and on per-seller AdCP endpoints. Carry the `resource`
value through authorization, token exchange and refresh.

## Seeing and revoking connections

Every OAuth client you approve appears under **Settings → Connected apps** with its name, when it
first connected and when it last refreshed. **Disconnect** revokes its tokens immediately.

## Errors you may see

| Response                                  | Meaning                                                                  |
| ----------------------------------------- | ------------------------------------------------------------------------ |
| `401` with `WWW-Authenticate`             | No token, or it expired. Refresh, or run the OAuth flow again.           |
| `401` for a token from another resource   | The token was issued for a different URL. Request one for this endpoint. |
| Tool error `ACCESS_DENIED` or `FORBIDDEN` | Signed in, but the role or account cannot do this.                       |

<Card title="MCP client setup" icon="gear" href="/v3/client-setup">
  Host-specific configuration for Codex, Claude Code, Claude, ChatGPT and others.
</Card>
