loading
Preparing LoginRadius developer resources
Mission: Help enterprises accelerate digital transformation with our fully-managed Customer IAM technology.
Skip to main content

MCP Auth

LoginRadius provides a complete OAuth 2.1 Authorization Server implementation for securing MCP (Model Context Protocol) servers. Tool calls in MCP can carry user-delegated permissions — any MCP server exposed without authentication has no identity boundary, no scope enforcement, and no revocation surface. Securing MCP with a proper authorization layer ensures that every tool call is tied to a verified identity, operates within granted scopes, and can be audited or revoked at any time.

LoginRadius handles token issuance, client registration, and PKCE enforcement for your MCP-connected applications. At a high level, the flow works as follows: the MCP Client registers with LoginRadius (via CIMD or DCR), then initiates an OAuth 2.1 authorization code flow with PKCE — the User Agent completes interactive authentication in the browser, the client exchanges the authorization code for a short-lived access token, and all subsequent tool calls to the MCP Server carry that token as a Bearer credential. The MCP Server validates the token (directly or via introspection) before executing any tool.

Actor Relationship

Participants

These four actors are canonical across all MCP auth flows. Use these terms verbatim when reading the CIMD and DCR flow pages.

ActorRole
MCP ClientThe AI agent or host initiating tool calls (e.g., Claude Desktop, a custom agent)
MCP ServerThe service exposing tools; acts as the OAuth resource server
Authorization ServerThe OAuth 2.1 / OIDC provider; LoginRadius in this context
User AgentThe browser that completes the interactive authorization step

Protocol Requirements

  • OAuth 2.1 — MCP mandates OAuth 2.1. Authorization code flow only; implicit grant forbidden. → MCP Authorization spec
  • PKCE (RFC 7636) — S256 code challenge required on every authorization request. → RFC 7636
  • Bearer tokens (RFC 6750) — Short-lived access tokens; refresh token rotation; no long-lived credentials. → RFC 6750
  • Resource indicators (RFC 8707) — The client declares the target resource server in the authorization request. → LoginRadius resource indicators docs

Auth Server Discovery

Before a client can request tokens, it must locate the Authorization Server's endpoints. MCP defines a structured discovery sequence:

  1. Attempt an unauthenticated tool call. The MCP Client sends an initial request to the MCP Server without a token.

    The MCP Server responds with 401 Unauthorized and a WWW-Authenticate header containing a resource_metadata URL pointing to the server's protected resource metadata document.

    Header: WWW-Authenticate: Bearer realm="mcp", resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"
  2. Fetch the resource metadata. The MCP Client GETs the resource metadata URL — typically at {server-origin}/.well-known/oauth-protected-resource.

    The response identifies the Authorization Server's issuer URI:

    Finding Your Issuer

    Your issuer URL is displayed in the LoginRadius Dashboard under your app's Endpoints tab in the OIDC Endpoint URLs section. Copy it directly from there.

    {
    "resource": "https://mcp.example.com/mcp",
    "authorization_servers": ["https://<tenant>.hub.loginradius.com/service/oidc/{app}"]
    }
  3. Fetch the Authorization Server metadata. Using the issuer URI from step 2, the MCP Client GETs:

    https://<tenant>.hub.loginradius.com/.well-known/oauth-authorization-server/service/oidc/{app}

    If this returns no result, the client falls back to /.well-known/openid-configuration per spec.

    LoginRadius metadata URL pattern:

    {issuer}/.well-known/oauth-authorization-server

    The response contains all endpoints and capability flags needed to proceed. The four fields most critical to MCP auth:

    {
    "registration_endpoint": "https://<tenant>.hub.loginradius.com/service/oidc/{app}/register",
    "code_challenge_methods_supported": ["S256"],
    "client_id_metadata_document_supported": true,
    "authorization_response_iss_parameter_supported": true
    }
    Important Considerations
    • Entry point for both DCR client registration. All clients must register here before requesting tokens.
    • Confirms PKCE enforcement. Only S256 is accepted — plain challenge method is rejected.
    • Signals that this Authorization Server supports CIMD. When true, a public client can use an HTTPS URL as its client_id instead of registering inline.
    • Mix-up attack protection per RFC 9207. The iss parameter in the authorization response lets the client verify the response came from the expected Authorization Server.
  4. Proceed to client registration. With registration_endpoint in hand, the client registers using DCR or directly present the Metadata Document URL during authorize call in case of CIMD - see Client Registration below.

Client Registration

Before a client can request tokens, it must register with the Authorization Server. LoginRadius supports two registration methods — Client Initiated Metadata Document (CIMD) for public clients and Dynamic Client Registration (DCR) for confidential clients — which can be independently toggled per OIDC application.


Configure MCP Auth on LoginRadius

Setting up MCP Auth on your LoginRadius tenant requires four steps: creating an OIDC application with MCP features enabled, registering an API resource that represents your MCP server, and linking the two together with the appropriate scopes, Implement OAuth server discovery and Protected Resource Metadata endpoint on your MCP server.

Step 1: Create an App

  1. In the LoginRadius Dashboard, navigate to Applications and click Create App. Enter a name for your application.

  2. Inside the app, open the General tab. Under Credentials and Security, set Token Endpoint Auth Method to Client Secret Post.

  3. In the Grant Settings section, confirm that Authorization Code is enabled as a grant type. This is the only grant type permitted under OAuth 2.1 for MCP.

Enable MCP Features

Before proceeding, you will need to enable MCP feature on your LoginRadius tenant. Contact Loginradius Support

  1. Under MCP Registration, enable CIMD, DCR, or both depending on which client registration method(s) your MCP server will support. See Client Registration for guidance on choosing between them.

Step 2: Create an API Resource

An API resource represents your MCP server as a protected resource in LoginRadius. The identifier you configure here is what clients pass as the resource parameter in their authorization requests.

  1. Navigate to Authorization → APIs and click Add API.

  2. Enter a Name for your API resource. This is for your reference only and does not appear in tokens.

  3. Enter the Identifier URL — the exact URL of your MCP server (e.g., https://mcp.example.com/mcp). This value is used as the resource parameter in the authorization request: step 7 of the CIMD flow and step 9 of the DCR flow.

  4. Configure additional API settings as needed such as scopes, user access policies and token lifetime. refer to Configure API Settings documentation.

With the app and API resource created, attach them so the Authorization Server knows which resources your app is permitted to request tokens for.

  1. Open your app and attach the API resource created in Step 2 and optionally define scopes on your API resource. → Attach an API Resource to Your App

  2. To understand how Scope intersection work with RBAC disbaled or enabled on API resources, refer to Scope Resolution documentation

Step 4: Configure the Protected Resource Metadata Endpoint

Your MCP server must expose the Protected Resource Metadata document at a well-known endpoint so that clients can discover your Authorization Server during the Auth Server Discovery phase. This metadata tells clients where to find the Authorization Server and what scopes are available.

Metadata Endpoint Location

The Protected Resource Metadata endpoint must be accessible at one of these locations on your MCP server:

  • At the root: https://mcp.example.com/.well-known/oauth-protected-resource
  • At the endpoint path: https://mcp.example.com/mcp/.well-known/oauth-protected-resource/mcp
MCP Specification Reference

See RFC 9728 Section 5 (OAuth 2.0 Protected Resource Metadata) for full details on the well-known endpoint structure. The MCP protocol mandates this discovery mechanism — see the MCP Authorization specification: Protected Resource Metadata Discovery Requirements.

Construct the Metadata Document

Configure your MCP server to return a JSON document at the endpoint above with the following required and recommended fields:

Required fields:

{
"resource": "https://mcp.example.com/mcp",
"authorization_servers": [
"https://<tenant>.hub.loginradius.com/service/oidc/{app}"
]
}
FieldDescriptionExample
resourceThe canonical URI of your MCP server. Must exactly match the Identifier URL configured in Step 2. Used by clients as the resource parameter in authorization requests per RFC 8707.https://mcp.example.com/mcp
authorization_serversArray of issuer URIs pointing to your LoginRadius Authorization Server(s). At minimum, include one issuer URL.["https://<tenant>.hub.loginradius.com/service/oidc/{app}"]

Recommended fields:

{
"resource": "https://mcp.example.com/mcp",
"authorization_servers": [
"https://<tenant>.hub.loginradius.com/service/oidc/{app}"
],
"scopes_supported": [
"openid",
"profile",
"email",
"custom:read",
"custom:write"
]
}
FieldDescriptionExample
scopes_supportedArray of scopes available for this resource. Clients use this list during the scope selection strategy when requesting authorization. Include all scopes defined on your API resource in Step 2.["openid", "profile", "email", "files:read", "files:write"]
Scope Values

The scopes_supported array must include scopes you've defined on your API resource in LoginRadius. These scopes are what clients request during authorization and what the Authorization Server enforces on tool calls. Refer to Configure API Settings to see how to define scopes on your resource.

Authorization Server Issuer URL Format

Replace the placeholders in your issuer URL:

  • {tenant} — Your LoginRadius tenant subdomain (e.g., mycompany-prod)
  • {app} — Your OIDC application ID from Step 1

LoginRadius issuer URL pattern:

https://{tenant}.hub.loginradius.com/service/oidc/{app}

Example:

https://acme-prod.hub.loginradius.com/service/oidc/mcp-app-12345

Implementation Example

Here's a minimal server implementation that serves the Protected Resource Metadata endpoint:

const express = require('express');
const app = express();

// Serve Protected Resource Metadata at /.well-known/oauth-protected-resource
app.get('/.well-known/oauth-protected-resource', (req, res) => {
res.json({
resource: "https://mcp.example.com/mcp",
authorization_servers: [
"https://<tenant>.hub.loginradius.com/service/oidc/<app>"
],
scopes_supported: [
"openid",
"profile",
"email",
"tools:execute"
]
});
});

// Your MCP tool endpoint
app.post('/mcp', (req, res) => {
// Validate bearer token here
// Execute tools
res.json({ result: "..." });
});

Verify the Endpoint

Test that your endpoint is accessible and returns valid JSON:

curl -i https://mcp.example.com/.well-known/oauth-protected-resource

You should see:

HTTP/1.1 200 OK
Content-Type: application/json

{
"resource": "https://mcp.example.com/mcp",
"authorization_servers": ["https://<tenant>.hub.loginradius.com/service/oidc/<app>"],
"scopes_supported": ["openid", "profile", "email", "tools:execute"]
}
HTTPS Required

The endpoint must be served over HTTPS per OAuth 2.1 Section 1.5 (Communication Security).

When a client makes an unauthenticated request to your MCP server (step 1 of Auth Server Discovery), return a 401 Unauthorized response with a WWW-Authenticate header pointing to your metadata endpoint:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="mcp", resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource", scope="tools:execute"
ParameterDescription
realmIdentifies the protection space (e.g., "mcp")
resource_metadataURL to your Protected Resource Metadata endpoint
scope(Optional) Space-separated list of scopes required for the current request. Guides clients on what to request.
Specification Reference

The WWW-Authenticate header mechanism is defined in RFC 9728 Section 5.1 and the MCP spec: Protected Resource Metadata Discovery Requirements.

Node.js/Express example with WWW-Authenticate:

app.post('/mcp', (req, res) => {
const authHeader = req.headers.authorization;

if (!authHeader) {
return res
.status(401)
.set('WWW-Authenticate', 'Bearer realm="mcp", resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource", scope="tools:execute"')
.json({ error: "unauthorized" });
}

// Validate token and execute tools
res.json({ result: "..." });
});

CIMD vs DCR

CIMDDCR
Client typePublicConfidential
Metadata locationHosted at client URLInline in POST body
Hosted URL requiredYesNo
Client secret issuedNoOptional (client_secret_post / client_secret_basic)
Best forOpen/distributed clientsServer-side / enterprise clients

Best Practices

  • In your MCP server, make sure you include WWW-Authenticate headers for all 401 responses with the URL where you host the PRM.
  • Make sure you serve metadata (PRM) at a publicly accessible URL.
  • When configuring Resource Indicator for your MCP server, make sure the identifier matches your MCP server URI exactly.
  • Ensure the access token audience (aud) claim matches your MCP server URI exactly.