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

# OAuth

> Choose and configure OAuth authentication for MCP servers.

Configure an OAuth provider when an MCP server must identify callers or authorize access by user, organization, role, scope, or permission. `MCPServer` protects the transport, publishes discovery metadata, verifies bearer tokens, and exposes the verified identity on `ctx.auth`.

## Choose a provider

Pick the provider for your identity system. Most providers run an authorization server that supports Dynamic Client Registration (DCR), and your MCP server only verifies their tokens. For a provider without DCR, such as GitHub or Google, use the OAuth Proxy: your MCP server becomes the authorization server itself.

| Identity system | Provider |
| - | - |
| Auth0 | [Auth0](/v2/typescript/server/authentication/providers/auth0) |
| Better Auth | [Better Auth](/v2/typescript/server/authentication/providers/better-auth) |
| Clerk | [Clerk](/v2/typescript/server/authentication/providers/clerk) |
| Convex | [Convex](/v2/typescript/server/authentication/providers/convex) |
| Keycloak | [Keycloak](/v2/typescript/server/authentication/providers/keycloak) |
| Supabase | [Supabase](/v2/typescript/server/authentication/providers/supabase) |
| WorkOS | [WorkOS](/v2/typescript/server/authentication/providers/workos) |
| Scalekit | [Scalekit](/v2/typescript/server/authentication/providers/scalekit) |
| Another DCR-capable authorization server | [Custom Provider](/v2/typescript/server/authentication/providers/custom) |
| GitHub, Google, or another provider without DCR | [OAuth Proxy](/v2/typescript/server/authentication/providers/oauth-proxy) |

With a DCR provider, the MCP client registers and performs the authorization flow directly with the authorization server. Your MCP server does not handle authorization codes or exchange them for tokens. With the OAuth Proxy, your MCP server runs that flow: it shows a consent page, signs the user in upstream as one OAuth app, and issues its own tokens.

## Configure the server

Import the server from `mcp-use` and the provider from its dedicated OAuth entry point, then pass the provider's settings as options.

```typescript theme={null}
import { MCPServer } from "mcp-use";
import { oauthAuth0Provider } from "mcp-use/oauth/auth0";

const domain = process.env.AUTH0_DOMAIN;
if (!domain) throw new Error("AUTH0_DOMAIN is required");

const server = new MCPServer({
  name: "secure-server",
  version: "1.0.0",
  oauth: oauthAuth0Provider({ domain }),
});

export default server;
```

When you omit an option, each provider in the table below reads the matching `MCP_USE_OAUTH_*` environment variable instead. With the variables set, you can call the factory with no arguments, for example `oauthAuth0Provider()`. An option you pass always takes precedence over its variable.

| Provider | Environment variables (option they replace) |
| - | - |
| Auth0 | `MCP_USE_OAUTH_AUTH0_DOMAIN` (`domain`), `MCP_USE_OAUTH_AUTH0_AUDIENCE` (`resource`) |
| Better Auth | `MCP_USE_OAUTH_BETTER_AUTH_URL` (`authURL`) |
| Clerk | `MCP_USE_OAUTH_CLERK_FRONTEND_API_URL` (`frontendApiUrl`) |
| Convex | `MCP_USE_OAUTH_CONVEX_AUTH_URL` (`authURL`) |
| Keycloak | `MCP_USE_OAUTH_KEYCLOAK_SERVER_URL` (`serverUrl`), `MCP_USE_OAUTH_KEYCLOAK_REALM` (`realm`), `MCP_USE_OAUTH_KEYCLOAK_AUDIENCE` (`resource`) |
| Scalekit | `MCP_USE_OAUTH_SCALEKIT_ENVIRONMENT_URL` (`environmentUrl`), `MCP_USE_OAUTH_SCALEKIT_RESOURCE_ID` (`resourceId`) |
| Supabase | `MCP_USE_OAUTH_SUPABASE_PROJECT_ID` (`projectId`), `MCP_USE_OAUTH_SUPABASE_URL` (`supabaseUrl`), `MCP_USE_OAUTH_SUPABASE_JWT_SECRET` (`jwtSecret`) |
| WorkOS | `MCP_USE_OAUTH_WORKOS_SUBDOMAIN` (`subdomain`) |

The OAuth Proxy reads only `MCP_USE_OAUTH_SECRET`, for its `secret` option, and always needs `upstream`. See [OAuth Proxy](/v2/typescript/server/authentication/providers/oauth-proxy).

The Auth0 and Keycloak `*_AUDIENCE` variables become the provider's `resource` when you don't pass one, so they override `MCP_URL`. The value must be the full MCP endpoint URL, with a path equal to `basePath` (default `/mcp`), or the server throws at startup.

The provider binds token verification to the resolved MCP resource. Set `MCP_URL` to the public server origin in production, or pass the provider's `resource` option when you need an explicit canonical MCP endpoint.

## Authorize a tool

An OAuth-configured server gives tool callbacks a provider-specific `ctx.auth.user`. All built-in providers normalize the stable subject to `id`; additional fields depend on the provider. The OAuth Proxy exposes the upstream user as `{ subject, profile }` unless you reshape it with `mapUser`.

```typescript theme={null}
server.tool(
  {
    name: "get_profile",
    description: "Return the authenticated caller.",
  },
  async (_args, ctx) => {
    const profile = {
      id: ctx.auth.user.id,
      email: ctx.auth.user.email ?? null,
      scopes: ctx.auth.scopes,
      permissions: ctx.auth.permissions,
    };

    return {
      content: [{ type: "text", text: JSON.stringify(profile) }],
    };
  },
);
```

`scopes` come from the verified SDK auth information. `permissions` and `user` come from the provider's verified claim mapping. Use [User Context](/v2/typescript/server/authentication/user-context) for the complete shape and authorization patterns.

## What OAuth changes

When `oauth` is configured:

* protected-resource and authorization-server metadata are published for clients;
* MCP transport requests require a bearer token;
* invalid, expired, incorrectly resourced tokens, and tokens missing configured `requiredScopes` are rejected before tool code runs;
* callbacks receive the verified access token, identity, scopes, permissions, expiry, client ID when present, and resource.

To let clients connect and call some tools before signing in, add `mixedAuth: true` and declare `securitySchemes` with `{ type: "noauth" }` on each public or optional tool. See [Mixed Authentication](/v2/typescript/server/authentication/mixed-auth).

## Next steps

<CardGroup cols={2}>
  <Card title="User Context" icon="user" href="/v2/typescript/server/authentication/user-context">
    Use verified identity and authorization data inside callbacks.
  </Card>

  <Card title="Mixed Authentication" icon="door-open" href="/v2/typescript/server/authentication/mixed-auth">
    Serve public, optional, and sign-in tools from one endpoint.
  </Card>

  <Card title="Custom Provider" icon="code" href="/v2/typescript/server/authentication/providers/custom">
    Integrate another DCR-capable authorization server.
  </Card>

  <Card title="OAuth Proxy" icon="shuffle" href="/v2/typescript/server/authentication/providers/oauth-proxy">
    Sign users in with GitHub, Google, or another provider without DCR.
  </Card>

  <Card title="Client Authentication" icon="router" href="/v2/typescript/client/authentication">
    Connect a TypeScript MCP client to an OAuth-protected server.
  </Card>
</CardGroup>


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