Skip to main content

How it works

In OAuth 2.0 mode, MCPCore acts as an OAuth 2.0 resource server. You bring your own Authorization Server, so you do not configure usernames, passwords, or client credentials inside MCPCore. You provide MCPCore with a single URL: your Authorization Server’s RFC 8414 metadata endpoint (the .well-known document your auth provider exposes). MCPCore validates that URL, then automatically sets up the discovery infrastructure so that MCP clients can find your auth server and complete the OAuth flow on their own.
Everything in steps 2–5 is automatic once you configure the URL.

When to use it

  • User-facing tools: each user authenticates with their own identity, and tools act on their behalf
  • Enterprise integrations: your org already has Okta, Azure AD, or Auth0 and you want to reuse it
  • Fine-grained access control: OAuth scopes let you restrict what each client can do
  • Compliance: explicit user consent, auditable access grants, short-lived tokens

What you need

An RFC 8414-compliant Authorization Server that exposes a .well-known/oauth-authorization-server metadata document. Any of the following work out of the box:

What MCPCore validates

When you save the server, MCPCore fetches your metadata URL and checks: If any of these fields are missing or the URL is unreachable, the server is not saved.
The registration_endpoint is what enables zero-config client connections. MCP clients like Claude and Cursor register themselves dynamically the first time they connect, so no manual app registration in your provider’s dashboard is needed.

Configure

1

Find your Authorization Server metadata URL

Look up your provider’s RFC 8414 metadata endpoint. This is a public HTTPS URL your auth server exposes.Auth0:
Okta:
Keycloak:
Confirm the URL returns valid JSON before proceeding. Open it in a browser, you should see a JSON object with issuer, authorization_endpoint, token_endpoint, registration_endpoint, and jwks_uri.
2

Open Server Settings

Go to your server’s Settings tab in the MCPCore dashboard.
3

Select OAuth 2.0

Under Security mode, select OAuth 2.0.
4

Enter the metadata URL

Paste your Authorization Server metadata URL into the OAuth Server URL field.MCPCore will fetch and validate this URL when you save. You do not enter client IDs, secrets, scopes, or redirect URIs, those are handled automatically by the MCP client through Dynamic Client Registration.
5

Save

Click Save. MCPCore validates the metadata URL, and if all required fields are present, activates OAuth 2.0 mode for this server.

What MCPCore sets up automatically

After you save, MCPCore configures your subdomain to serve two discovery endpoints:

Protected Resource Metadata (RFC 9728)

This document tells MCP clients which authorization server governs your resource:

401 response with discovery pointer

When a client connects without a token, MCPCore responds:
This tells MCP clients exactly where to start discovery. Everything after this is handled by the client automatically.

The full client flow (automatic)

Once OAuth 2.0 mode is active, here is what happens when an MCP client connects for the first time:
1

Client attempts to connect

The MCP client sends a request to https://{your-subdomain}.mcpcore.io/mcp. MCPCore returns 401 with a WWW-Authenticate header pointing to the resource metadata endpoint.
2

Client discovers your authorization server

The client fetches /.well-known/oauth-protected-resource and reads the authorization_servers field to find your auth server’s issuer URL.
3

Client fetches authorization server metadata

The client fetches your metadata URL (the one you configured) to learn the authorization_endpoint, token_endpoint, registration_endpoint, and jwks_uri.
4

Client registers itself (Dynamic Client Registration)

The client sends a registration request to your registration_endpoint. Your auth server issues a client_id (and optionally a client_secret). This registration is cached, so it only happens once per client.
5

User completes the OAuth authorization flow

The client opens a browser and directs the user to your authorization_endpoint, adding a resource parameter set to your MCPCore endpoint (https://{your-subdomain}.mcpcore.io/mcp), per RFC 8707. The user authenticates with your provider. After consent, your auth server redirects back to the client with an authorization code.The client exchanges the code for a JWT access token at your token_endpoint, sending the same resource value again, and using PKCE (Proof Key for Code Exchange) throughout to prevent code interception.
6

Client presents the access token

The client includes the JWT in all subsequent requests:
7

MCPCore validates the token

MCPCore fetches your server’s public keys from the jwks_uri in your metadata, verifies the JWT signature, checks expiry, checks that the aud claim matches your MCPCore resource URL exactly, and validates the issuer. If the token is valid, the request proceeds to your tool code.
On reconnection, the client presents its stored token (or refreshes it), and the user does not have to log in again unless the session has expired.

Resource indicators and token audience (current standard)

This is the part of the setup that causes the most connection failures, so read it closely if you are configuring your own authorization server (or an enterprise SSO provider) for the first time. MCP clients follow RFC 8707 (Resource Indicators for OAuth 2.0). When a client starts the authorization flow against your auth server, it sends a resource parameter identifying exactly which MCPCore endpoint it wants to call:
This value is sent on both the authorization request and the token request. Your authorization server is expected to copy it into the aud (audience) claim of the JWT it issues. That is the whole contract:
MCPCore validates every incoming token by checking that aud matches its own resource URL for your server. If it does not match, the request is rejected with 401 Unauthorized, and MCP Inspector (or any other client) usually surfaces this as a generic authentication error rather than the specific audience mismatch, since the failure happens before your tool code runs.
A resource identifier is scoped to one MCPCore server. If you run five MCPCore servers behind the same authorization server, each one has its own resource URL, and your auth server must issue a distinct aud for each, matching whatever resource value the client sent for that connection.

Quick reference by provider

Legacy audience mode (deprecated)

Older authorization servers, and some minimal or hand-rolled OAuth implementations, ignore the resource parameter entirely and always issue tokens with aud set to the issuer itself, instead of the resource being accessed. MCPCore has a compatibility fallback for this, exposed as Legacy token audience in your server’s OAuth settings.
Enabling legacy token audience makes MCPCore accept a token whose aud equals the issuer, in addition to the resource URL. Because the issuer is shared across every MCPCore server that points at the same authorization server, a token minted for one tenant becomes technically valid for any other tenant using that same authorization server. Every request accepted this way is written to your error logs as a legacy_token_audience warning so you can track how often it happens.Treat this as a temporary bridge while you fix resource indicator support on your authorization server, not as a permanent setting.
Once your authorization server correctly echoes resource into aud, turn Legacy token audience back off. Audience validation will then match exactly, with no fallback and no cross-tenant exposure.

Running your own authorization server

If you are not using Okta, Auth0, Keycloak, or Azure AD, and instead run a small custom OAuth server (for internal tools, a proof of concept, or a self-hosted identity provider), it must expose the following to work with MCPCore correctly, including resource indicator support.

1. Authorization server metadata

resource_indicators_supported: true is not required for MCPCore to accept the document, but it tells MCP clients you honor RFC 8707, so include it once you have implemented the behavior below.

2. JWKS endpoint

A standard JWK Set containing the public half of the RS256 (or ES256) key you sign tokens with. MCPCore refetches this on a short cache TTL, so key rotation does not require redeploying MCPCore.

3. Authorization endpoint must carry resource through

Your /oauth/authorize handler receives a resource query parameter alongside the usual client_id, redirect_uri, code_challenge, and scope. It must survive the login step and be stored with the authorization code, the same way redirect_uri and code_challenge already are:

4. Token endpoint must set aud to the stored resource

The aud: authCode.resource || BASE_URL line is the entire fix. Falling back to BASE_URL (your issuer) when no resource was sent keeps older clients working, but only MCPCore’s legacy audience mode will accept that fallback value, so treat the fallback as best-effort compatibility, not the target state. With this in place, leave Legacy token audience off in MCPCore. The token’s aud will already equal the resource MCPCore expects, with no compatibility fallback needed.

Provider-specific setup

These are the minimum steps to get connected. Each provider also needs its audience/resource identifier configured to match your MCPCore resource URL exactly, covered in depth on the dedicated page linked from each entry.
  1. Log in to manage.auth0.com and open your tenant.
  2. Go to Applications → APIs and create a new API representing your MCPCore server, with Identifier set to https://{your-subdomain}.mcpcore.io/mcp.
  3. Enable Allow Offline Access if you want refresh tokens.
  4. Confirm Dynamic Client Registration is enabled (it is on by default for Auth0 management API).
  5. Your metadata URL:
Verify it returns a JSON document with all five required fields before pasting it into MCPCore, then see the full Auth0 guide to enable resource indicators so issued tokens carry the correct aud.
  1. Log in to your Okta admin console.
  2. Go to Security → API → Authorization Servers.
  3. Create a custom authorization server (or reuse one) with Audience set to https://{your-subdomain}.mcpcore.io/mcp.
  4. Under Settings, confirm Dynamic Client Registration is enabled.
  5. Your metadata URL:
Replace {authServerId} with default or your custom server ID, then see the full Okta guide for the audience and one-server-per-resource details.
  1. Open your Keycloak admin console.
  2. Select your realm and go to Realm settings → General.
  3. Confirm Client registration → Open is enabled (allows Dynamic Client Registration without an initial access token).
  4. Add an Audience protocol mapper so issued tokens carry https://{your-subdomain}.mcpcore.io/mcp as an audience.
  5. Your metadata URL:
See the full Keycloak guide for the protocol mapper walkthrough.
  1. Register an application in the Azure portal for your tenant.
  2. Set the Application ID URI (Expose an API) to https://{your-subdomain}.mcpcore.io/mcp so tokens are minted with that value as aud.
  3. Enable the authorization_code flow. Azure does not enable open Dynamic Client Registration by default, see the note below.
  4. Your metadata URL:
Azure exposes OpenID Connect discovery (the RFC 8414 fallback). MCPCore accepts this format. See the full Azure AD / Entra ID guide for the Application ID URI and client registration policy details.
Azure does not enable open Dynamic Client Registration by default. You may need to pre-register the MCP client or configure a registration policy in your tenant.
Any RFC 8414-compliant server works as long as it exposes a public HTTPS metadata endpoint containing all five required fields. Libraries like node-oidc-provider, Spring Authorization Server, and Ory Hydra support this out of the box.Your server must:
  • Be reachable over public HTTPS
  • Include registration_endpoint in its metadata (Dynamic Client Registration)
  • Include jwks_uri pointing to your public key set
  • Issue short-lived JWTs signed with an RS256 or ES256 key
  • Read the resource parameter and echo it into the aud claim, see Running your own authorization server above

Client compatibility

MCP clients that implement the MCP Authorization specification handle the OAuth flow automatically, so no manual configuration is required. For clients using mcp-remote as a proxy, the proxy handles the OAuth flow locally and forwards a session token to MCPCore. The user is prompted once in their browser; subsequent connections are silent.
When connecting via mcp-remote, the proxy caches tokens in local storage. If you revoke a user’s session at your authorization server, the token in the proxy cache remains valid until it expires naturally. Use short token lifetimes (15–60 minutes) to limit this window.

Token lifetime recommendations

Short-lived access tokens limit exposure if a token is leaked. Refresh token rotation ensures a stolen refresh token is invalidated after a single use.