Configure MCP Auth in MCP server
With the latest MCP Specification (2025-06-18), your MCP server acts as a Resource Server that validates access tokens issued by external authorization servers.
To configure MCP Auth, you need two main steps:
- Configure Authorization Server Metadata - Define which authorization servers can issue valid tokens for your MCP server and guide MCP clients on where to obtain access tokens
- Configure Protected Resource Metadata - Define your MCP server as a protected resource with supported scopes
Step 1: Configure Authorization Server Metadata
Automatic metadata fetching
The easiest way to configure authorization server metadata is by using the built-in functions that fetch the metadata from well-known URLs. If your provider conforms to one of the following standards:
You can use the fetchServerConfig to automatically retrieve the metadata by providing the issuer URL:
import { fetchServerConfig } from 'mcp-auth';
// Fetch authorization server metadata
const authServerConfig = await fetchServerConfig('https://auth.logto.io/oidc', { type: 'oidc' }); // or 'oauth'
If your issuer includes a path, the behavior differs slightly between OAuth 2.0 and OpenID Connect:
- OAuth 2.0: The well-known URL is appended to the domain of the issuer. For example, if your issuer is
https://my-project.logto.app/oauth, the well-known URL will behttps://auth.logto.io/.well-known/oauth-authorization-server/oauth. - OpenID Connect: The well-known URL is appended directly to the issuer. For example, if your issuer is
https://my-project.logto.app/oidc, the well-known URL will behttps://auth.logto.io/oidc/.well-known/openid-configuration.
On demand discovery
If you're using edge runtimes like Cloudflare Workers where top-level async fetch is not allowed, you can use on demand discovery instead. Just provide the issuer and type, and the metadata will be fetched automatically when first needed:
const authServerConfig = { issuer: '<issuer-url>', type: 'oidc' }; // or 'oauth'
Other ways to configure authorization server metadata
Custom data transpilation
In some cases, the metadata returned by the provider may not conform to the expected format. If you are confident that the provider is compliant, you can use the transpileData option to modify the metadata before it is used:
import { fetchServerConfig } from 'mcp-auth';
const authServerConfig = await fetchServerConfig('<auth-server-issuer>', {
type: 'oidc',
transpileData: (data) => ({ ...data, response_types_supported: ['code'] }),
});
This allows you to modify the metadata object before it is used by MCP Auth. For example, you can add or remove fields, change their values, or convert them to a different format.
Fetch metadata from a specific URL
If your provider has a specific metadata URL rather than the standard ones, you can use it similarly:
import { fetchServerConfigByWellKnownUrl } from 'mcp-auth';
const authServerConfig = await fetchServerConfigByWellKnownUrl('<metadata-url>', { type: 'oidc' }); // or 'oauth'
Fetch metadata from a specific URL with custom data transpilation
In some cases, the provider response may be malformed or not conforming to the expected metadata format. If you are confident that the provider is compliant, you can transpile the metadata via the config option:
const authServerConfig = await fetchServerConfigByWellKnownUrl('<metadata-url>', {
type: 'oidc',
transpileData: (data) => ({ ...data, response_types_supported: ['code'] }),
});
Manually provide metadata
If your provider does not support metadata fetching, you can manually provide the metadata object:
const authServerConfig = {
metadata: {
issuer: '<issuer-url>',
// Metadata fields should be camelCase
authorizationEndpoint: '<authorization-endpoint-url>',
// ... other metadata fields
},
type: 'oidc', // or 'oauth'
};
Step 2: Configure Protected Resource Metadata
After configuring the authorization server metadata, you need to initialize MCPAuth as a Resource Server by defining your protected resources metadata.
This step follows the RFC 9728 (OAuth 2.0 Protected Resource Metadata) specification to describe your MCP server as a protected resource:
import { MCPAuth } from 'mcp-auth';
// Define your resource identifier
const resourceIdentifier = 'https://api.example.com/notes';
// Initialize MCPAuth in resource server mode
const mcpAuth = new MCPAuth({
protectedResources: {
metadata: {
resource: resourceIdentifier,
authorizationServers: [authServerConfig], // Using the config from Step 1
scopesSupported: ['read:notes', 'write:notes'],
},
},
});
For multiple resources, you can provide an array of protected resource configs, each with their own metadata configuration.
The configuration shown above covers the basic setup. For more advanced metadata parameters, see RFC 9728.
Step 3: Mount the protected resource metadata endpoint
Mount the router to serve the protected resource metadata endpoint. The endpoint path is automatically determined by the path component of your resource identifier:
- No path:
https://api.example.com→/.well-known/oauth-protected-resource - With path:
https://api.example.com/notes→/.well-known/oauth-protected-resource/notes
import express from 'express';
const app = express();
const mcpAuth = new MCPAuth({
/* ... */
});
app.use(mcpAuth.protectedResourceMetadataRouter());