# OAuth

> Configure browser-based OAuth authorization for the Directus MCP server.

MCP OAuth lets compatible AI clients connect to Directus through a browser authorization flow. Instead of copying a static token into the client, the user signs in to Directus, reviews the MCP client, and grants access from the consent page.

Use OAuth when your MCP client supports remote server OAuth discovery. Use [static access tokens](/guides/ai/mcp/installation) when your client only supports manual headers or query parameters.

<callout color="info" icon="i-lucide-info">

OAuth access is limited to the MCP endpoint. The issued token uses the `mcp:access` scope and the MCP server resource URL as its audience.

</callout>

## Enable MCP OAuth

MCP OAuth has separate controls for the OAuth server and the client registration modes. The environment variables control what the instance allows. The project settings control what each Directus project allows.

<steps level="3">

### Enable the OAuth Routes and a Registration Mode

For self-hosted projects, set `MCP_OAUTH_ENABLED` to `true`, enable at least one client registration mode, and restart Directus.

```bash [.env]
MCP_OAUTH_ENABLED=true
MCP_OAUTH_CIMD_ENABLED=true
PUBLIC_URL=https://directus.example.com
```

Use `MCP_OAUTH_CIMD_ENABLED=true` for [Client ID Metadata Document registration](#client-id-metadata-document), `MCP_OAUTH_DCR_ENABLED=true` for [Dynamic Client Registration](#dynamic-client-registration), or both if you intentionally support both onboarding paths.

`PUBLIC_URL` must be the public URL clients use to reach Directus. Directus uses it to build the OAuth issuer, protected resource, authorization, token, registration, and revocation URLs.

### Enable OAuth in the Data Studio

1. Log in to Directus as an administrator.
2. Go to **Settings** > **AI** > **Model Context Protocol**.
3. Enable **MCP Server**.
4. Enable **OAuth Enabled**.
5. Enable at least one client registration setting: [**Dynamic Client Registration**](#dynamic-client-registration) or [**Client ID Metadata Document**](#client-id-metadata-document).
6. Save the AI settings.

![MCP OAuth settings with OAuth, Dynamic Client Registration, and Client ID Metadata Document enabled](/img/mcp-oauth-settings-toggles.png)

### Connect from Your MCP Client

In the client, add the Directus MCP server URL:

```txt
https://directus.example.com/mcp
```

The client discovers OAuth support from the MCP endpoint and redirects the user to Directus when authorization is required.

</steps>

## Authorization Flow

When a compatible MCP client connects without a valid token, Directus returns an OAuth challenge for the `/mcp` endpoint. The client then discovers the OAuth endpoints, uses an enabled registration mode, and opens the Directus authorization page.

1. The client connects to `https://directus.example.com/mcp`.
2. Directus responds with a `WWW-Authenticate` header that points to the protected resource metadata.
3. The client reads `/.well-known/oauth-protected-resource/mcp`.
4. The client reads `/.well-known/oauth-authorization-server`.
5. The client registers with `/mcp-oauth/register` if [Dynamic Client Registration](#dynamic-client-registration) is enabled, or identifies itself with a [Client ID Metadata Document](#client-id-metadata-document) if CIMD is enabled.
6. The client opens `/mcp-oauth/authorize` in the user's browser.
7. The user signs in to Directus, reviews the consent page, and approves or denies access.
8. The client exchanges the authorization code at `/mcp-oauth/token`.
9. The client sends the issued bearer token when calling `/mcp`.

The consent page uses the user's Directus session. The token inherits that user's Directus permissions and can only be used against the MCP endpoint.

![MCP OAuth consent page asking the user to approve client access](/img/mcp-oauth-consent-page.png)

The `GET /mcp-oauth/authorize` endpoint uses the `RATE_LIMITER_MCP_OAUTH_*` rate limiter pool.

## Client Registration

Directus supports two registration methods for MCP OAuth clients. Both are disabled by default. A registration mode is advertised and accepted only when both the environment variable and the project setting are enabled.

<table>
<thead>
  <tr>
    <th>
      Method
    </th>
    
    <th>
      Setting
    </th>
    
    <th>
      Use When
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a href="#dynamic-client-registration">
        Dynamic Client Registration
      </a>
    </td>
    
    <td>
      <strong>
        Dynamic Client Registration
      </strong>
    </td>
    
    <td>
      The client registers itself by sending metadata to <code>
        /mcp-oauth/register
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="#client-id-metadata-document">
        Client ID Metadata Document
      </a>
    </td>
    
    <td>
      <strong>
        Client ID Metadata Document
      </strong>
    </td>
    
    <td>
      The client uses an HTTPS <code>
        client_id
      </code>
      
       URL that hosts its metadata.
    </td>
  </tr>
</tbody>
</table>

The [MCP authorization specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#client-registration-approaches) explains how MCP clients choose between pre-registration, Client ID Metadata Documents, and Dynamic Client Registration. For protocol details, see [OAuth 2.0 Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) and the [OAuth Client ID Metadata Document draft](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00).

Dynamic Client Registration is useful for clients that expect an OAuth registration endpoint. Because it exposes an unauthenticated registration write endpoint, enable it only when your clients need it.

### Dynamic Client Registration

Dynamic Client Registration accepts public and confidential clients:

<table>
<thead>
  <tr>
    <th>
      Client Type
    </th>
    
    <th>
      <code>
        token_endpoint_auth_method
      </code>
    </th>
    
    <th>
      Behavior
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Public client
    </td>
    
    <td>
      <code>
        none
      </code>
    </td>
    
    <td>
      Uses authorization code with PKCE and no client secret.
    </td>
  </tr>
  
  <tr>
    <td>
      Confidential client
    </td>
    
    <td>
      <code>
        client_secret_basic
      </code>
    </td>
    
    <td>
      Receives a generated <code>
        client_secret
      </code>
      
       and authenticates with HTTP Basic at token and revocation endpoints.
    </td>
  </tr>
  
  <tr>
    <td>
      Confidential client
    </td>
    
    <td>
      <code>
        client_secret_post
      </code>
    </td>
    
    <td>
      Receives a generated <code>
        client_secret
      </code>
      
       and authenticates with form parameters at token and revocation endpoints.
    </td>
  </tr>
</tbody>
</table>

The generated `client_secret` is returned once in the registration response. Directus stores only a hash of the secret.

Dynamic Client Registration uses the `RATE_LIMITER_MCP_OAUTH_REGISTRATION_*` rate limiter pool.

### Client ID Metadata Document

Client ID Metadata Document clients publish metadata at their `client_id` URL. Directus fetches and validates the metadata during authorization, then caches the client metadata according to the response cache headers.

Client ID Metadata Document registration can be a good onboarding model because it avoids unauthenticated local client creation. It is still opt-in because Directus must make an outbound metadata request.

Directus hardens CIMD metadata fetching by:

- Requiring HTTPS by default. `MCP_OAUTH_CIMD_ALLOW_HTTP` is available only for local development.
- Rejecting `client_id` URLs with query strings, fragments, credentials, root paths, dot segments, IP-address hosts, non-canonical forms, blocked TLDs, or more than 255 characters.
- Fetching metadata without redirects.
- Limiting metadata responses to JSON content types, 5 KB, and 3 seconds.
- Using Directus' shared outbound request IP deny list, `IMPORT_IP_DENY_LIST`, at connection and DNS lookup time.
- Supporting `MCP_OAUTH_CIMD_ALLOWED_DOMAINS` to restrict which metadata hosts can register.

For production projects, restrict which metadata hosts can register by setting `MCP_OAUTH_CIMD_ALLOWED_DOMAINS`. Leave `MCP_OAUTH_CIMD_ALLOW_HTTP` disabled outside local development.

## Redirect URI Controls

Use `MCP_OAUTH_ALLOWED_REDIRECT_DOMAINS` to restrict HTTPS OAuth redirect URIs to specific domains. Leave it empty to allow any valid HTTPS redirect URI. The allowlist supports exact domains like `cursor.com` and wildcard subdomains like `*.anthropic.com`.

Use `MCP_OAUTH_ALLOWED_CUSTOM_REDIRECTS` to control which custom URI-scheme OAuth redirect targets Directus accepts for desktop MCP clients. Directus allows `raycast://oauth` and `cursor://cursor.mcp` by default. Override this setting to replace those defaults, or set it to an empty value to disable custom-scheme redirects.

Loopback redirects for native clients and configured custom-scheme redirects are allowed separately from the HTTPS domain allowlist.

## Tested MCP Clients

MCP OAuth support depends on the MCP client, not the model provider. Record a client here only after testing it against Directus. Include the tested date and client version where available.

<table>
<thead>
  <tr>
    <th>
      Client
    </th>
    
    <th>
      Tested
    </th>
    
    <th>
      Registration Method
    </th>
    
    <th>
      Enable
    </th>
    
    <th>
      Notes
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ChatGPT
    </td>
    
    <td>
      2026-05-28
    </td>
    
    <td>
      DCR
    </td>
    
    <td>
      <code>
        MCP_OAUTH_DCR_ENABLED=true
      </code>
    </td>
    
    <td>
      Requires <strong>
        Advanced OAuth settings
      </strong>
      
       during connector setup.
    </td>
  </tr>
  
  <tr>
    <td>
      Claude Code
    </td>
    
    <td>
      2026-05-28
    </td>
    
    <td>
      CIMD preferred. DCR also works.
    </td>
    
    <td>
      <code>
        MCP_OAUTH_CIMD_ENABLED=true
      </code>
    </td>
    
    <td>
      Add the server with <code>
        claude mcp add --transport http
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      Claude Desktop
    </td>
    
    <td>
      2026-05-28
    </td>
    
    <td>
      CIMD preferred. DCR also works.
    </td>
    
    <td>
      <code>
        MCP_OAUTH_CIMD_ENABLED=true
      </code>
    </td>
    
    <td>
      -
    </td>
  </tr>
  
  <tr>
    <td>
      Claude.ai
    </td>
    
    <td>
      2026-05-28
    </td>
    
    <td>
      CIMD preferred. DCR also works.
    </td>
    
    <td>
      <code>
        MCP_OAUTH_CIMD_ENABLED=true
      </code>
    </td>
    
    <td>
      -
    </td>
  </tr>
  
  <tr>
    <td>
      Cursor
    </td>
    
    <td>
      2026-05-28
    </td>
    
    <td>
      DCR
    </td>
    
    <td>
      <code>
        MCP_OAUTH_DCR_ENABLED=true
      </code>
    </td>
    
    <td>
      Cursor install URL can prefill the MCP server URL.
    </td>
  </tr>
  
  <tr>
    <td>
      Figma Make
    </td>
    
    <td>
      2026-05-28
    </td>
    
    <td>
      DCR
    </td>
    
    <td>
      <code>
        MCP_OAUTH_DCR_ENABLED=true
      </code>
    </td>
    
    <td>
      -
    </td>
  </tr>
  
  <tr>
    <td>
      Raycast
    </td>
    
    <td>
      2026-05-28
    </td>
    
    <td>
      DCR
    </td>
    
    <td>
      <code>
        MCP_OAUTH_DCR_ENABLED=true
      </code>
    </td>
    
    <td>
      -
    </td>
  </tr>
  
  <tr>
    <td>
      v0
    </td>
    
    <td>
      2026-05-28
    </td>
    
    <td>
      CIMD
    </td>
    
    <td>
      <code>
        MCP_OAUTH_CIMD_ENABLED=true
      </code>
    </td>
    
    <td>
      -
    </td>
  </tr>
  
  <tr>
    <td>
      VS Code
    </td>
    
    <td>
      2026-05-28
    </td>
    
    <td>
      CIMD
    </td>
    
    <td>
      <code>
        MCP_OAUTH_CIMD_ENABLED=true
      </code>
    </td>
    
    <td>
      Does not fall back to DCR.
    </td>
  </tr>
</tbody>
</table>

## Manage Registered Clients

Administrators can review and revoke registered clients in **Settings** > **AI** > **Model Context Protocol** > **Manage Registered Clients**.

![MCP OAuth registered clients list in Directus](/img/mcp-oauth-manage-clients.png)

Revoking a client removes its OAuth grants and sessions. The user must authorize the client again before it can access the MCP server.

## Configuration Reference

See [AI Configuration](/configuration/ai#model-context-protocol-oauth) for MCP OAuth environment variables. See [Security & Limits](/configuration/security-limits#rate-limiting) for MCP OAuth rate limiter settings.
