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

# Authorization

> The OAuth 2.1 flow, discovery endpoints, client registration, and scopes used by the Auxilian MCP server.

The Auxilian MCP server is an OAuth 2.1 protected resource with its own authorization server. Clients discover it, register, and obtain tokens using the standard MCP authorization flow. Users sign in with Google and approve on a consent page.

<Info>
  Most people never need this page. Claude, Claude Code, Cursor, and VS Code handle the flow automatically. This page is for client developers and security reviewers.
</Info>

## Endpoints

| Purpose | Endpoint |
| - | - |
| Protected resource metadata | `https://mcp.auxilian.ai/.well-known/oauth-protected-resource` |
| Authorization server metadata | `https://mcp.auxilian.ai/.well-known/oauth-authorization-server` |
| Authorization | `https://mcp.auxilian.ai/authorize` |
| Token | `https://mcp.auxilian.ai/oauth/token` |
| Dynamic client registration | `https://mcp.auxilian.ai/oauth/register` |
| MCP resource | `https://mcp.auxilian.ai/mcp` |

## Scopes

| Scope | Grants |
| - | - |
| `mcp:read` | Read tools: `list_projects`, `list_tables`, `describe_table`, `list_rows` |
| `mcp:write` | Write and destructive tools |

How the granted scopes are derived from the request:

* No scope requested: both scopes.
* `mcp:write` requested without `mcp:read`: both scopes. A write-only grant couldn't list projects.
* Only unsupported scopes requested: `mcp:read`.

Calling a write tool with a read-only token returns `ACCESS_DENIED`. See [Responses and errors](/mcp/responses-and-errors).

## Flow

<Steps>
  <Step title="Discover">
    An unauthenticated request to `/mcp` returns `401` with a `WWW-Authenticate` header pointing at the protected resource metadata. The client reads it, then reads the authorization server metadata.
  </Step>

  <Step title="Register">
    The client identifies itself with a Client ID Metadata Document (preferred) or registers through dynamic client registration at `/oauth/register`. Registration is limited to 10 requests per minute per IP address.
  </Step>

  <Step title="Authorize">
    The client opens `/authorize` in a browser with PKCE (`S256`). The redirect URI must match one the client registered.

    If the user has no Auxilian session on `mcp.auxilian.ai`, they are sent to Auxilian's sign-in page and continue with Google. Auxilian then creates or updates their account, in the same way as a web sign-in.
  </Step>

  <Step title="Consent">
    The user sees the consent page with the client name, the redirect host, the scopes, and their email address. **Allow** issues an authorization code. **Cancel** redirects with `error=access_denied`.
  </Step>

  <Step title="Exchange">
    The client exchanges the code at `/oauth/token` with its PKCE verifier and sends the access token as a bearer token on every `/mcp` request.
  </Step>
</Steps>

## Consent page protections

* The consent form carries a single-use nonce that must match a cookie scoped to `/authorize` and a server-side record. The nonce expires after 10 minutes.
* The form submission is refused if the browser reports it as cross-site.
* The signed-in user must be the same when the page is shown and when it is submitted.
* The page sends `X-Frame-Options: DENY` and a Content Security Policy with `frame-ancestors 'none'`, so it can't be embedded.
* The policy's `form-action` allows only Auxilian and the validated redirect target.

## Token contents

A token carries the user's id, email address, and granted scopes. It doesn't carry workspace roles or project permissions. The server looks those up on every call, so revoked access takes effect immediately even for a token that is still valid.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.