Get started
This version supports the MCP authorization specification (version 2025-06-18).
MCP Auth is also available for Python! Check out the Python SDK repository for installation and usage.
Choose a compatible OAuth 2.1 or OpenID Connect provider
MCP specification has specific requirements for authorization. The authorization mechanism is based on established specifications, implementing a selected subset of their features to ensure security and interoperability while maintaining simplicity:
- OAuth 2.1 IETF DRAFT (draft-ietf-oauth-v2-1-13)
- OAuth 2.0 Authorization Server Metadata (RFC 8414)
- OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591)
- OAuth 2.0 Protected Resource Metadata (RFC 9728)
These specifications work together to provide a secure and standardized authorization framework for MCP implementations.
You can check the MCP-compatible provider list to see if your provider is supported.
Install MCP Auth SDK
- pnpm
- npm
- yarn
pnpm add mcp-authnpm install mcp-authyarn add mcp-authInit MCP Auth
The first step is to define your resource identifier and configure the authorization server that will be trusted for authentication. MCP Auth now operates in resource server mode, conforming to the updated MCP specification that requires OAuth 2.0 Protected Resource Metadata (RFC 9728).
If your provider conforms to:
You can use the built-in function to fetch the metadata and initialize the MCP Auth instance:
import { MCPAuth, fetchServerConfig } from 'mcp-auth';
// 1. Define your resource identifier and fetch the config for its trusted authorization server.
const resourceIdentifier = 'https://api.example.com/notes';
const authServerConfig = await fetchServerConfig('https://auth.logto.io/oidc', { type: 'oidc' });
// 2. Initialize MCPAuth in resource server mode.
// `protectedResources` can be a single object or an array for multiple resources.
const mcpAuth = new MCPAuth({
protectedResources: {
metadata: {
resource: resourceIdentifier,
authorizationServers: [authServerConfig],
scopesSupported: ['read:notes', 'write:notes'],
},
},
});
If you're using edge runtimes like Cloudflare Workers where top-level async fetch is not allowed, use on demand discovery instead:
const authServerConfig = { issuer: 'https://auth.logto.io/oidc', type: 'oidc' };
For other ways to configure authorization server metadata including custom metadata URLs, data transpilation, or manual metadata specification, check Other ways to configure MCP Auth.
Mount the protected resource metadata endpoint
To conform to the updated MCP specification, MCP Auth mounts the OAuth 2.0 Protected Resource Metadata endpoint (RFC 9728) to your MCP server. This endpoint allows clients to discover:
- Which authorization servers can issue valid tokens for your protected resources
- What scopes are supported for each resource
- Other metadata required for proper token validation
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
The MCP server now serves as a resource server that validates tokens and provides metadata about its protected resources, while relying entirely on external authorization servers for authentication and authorization.
You can use the SDK provided method to mount this endpoint:
import express from 'express';
const app = express();
// Mount the router to serve the Protected Resource Metadata.
// For resource "https://api.example.com" → endpoint: /.well-known/oauth-protected-resource
// For resource "https://api.example.com/notes" → endpoint: /.well-known/oauth-protected-resource/notes
app.use(mcpAuth.protectedResourceMetadataRouter());
Use the Bearer auth middleware
Once the MCP Auth instance is initialized, you can apply the Bearer auth middleware to protect your MCP routes. The middleware now requires specifying which resource the endpoint belongs to, enabling proper token validation:
The audience parameter is required by the OAuth 2.0 specification for secure token validation. However, it is currently optional to maintain compatibility with authorization servers that do not yet support resource identifiers. For security reasons, please always include the audience parameter when possible. Future versions will enforce audience validation as mandatory to fully comply with the specification.
In OAuth 2.0, scopes are the primary mechanism for permission control. A valid token with the correct audience does NOT guarantee the user has permission to perform an action — authorization servers may issue tokens with an empty or limited scope.
Always use requiredScopes to enforce that the token contains the necessary permissions for each operation. Never assume a valid token implies full access.
import express from 'express';
const app = express();
// Mount the router to serve the Protected Resource Metadata.
app.use(mcpAuth.protectedResourceMetadataRouter());
// Protect an API endpoint using the resource-specific policy.
app.get(
'/notes',
mcpAuth.bearerAuth('jwt', {
resource: resourceIdentifier,
audience: resourceIdentifier, // Enable audience validation for security
requiredScopes: ['read:notes'],
}),
(req, res) => {
// If the token is valid, `req.auth` is populated with its claims.
console.log('Auth info:', req.auth);
res.json({ notes: [] });
}
);
app.listen(3000);
In the examples above, we specify the jwt token type and the resource identifier. The middleware will automatically validate the JWT token against the trusted authorization servers configured for that specific resource and populate the authenticated user's information.
Didn't hear about JWT (JSON Web Token) before? Don't worry, you can keep reading the documentation and we'll explain it when needed. You can also check Auth Wiki for a quick introduction.
For more information on the Bearer auth configuration, check the Configure Bearer auth.
Retrieve the auth info in your MCP implementation
Once the Bearer auth middleware is applied, you can access the authenticated user's (or identity's) information in your MCP implementation:
The second argument of the tool handler will contain the authInfo object, which includes the authenticated user's information:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
const server = new McpServer(/* ... */);
// Initialize with MCP Auth as shown in previous examples
// ...
server.registerTool(
'add',
{
description: 'Add two numbers',
inputSchema: { a: z.number(), b: z.number() },
},
async ({ a, b }, { authInfo }) => {
// Now you can use the `authInfo` object to access the authenticated information
}
);
Next steps
Continue reading to learn an end-to-end example of how to integrate MCP Auth with your MCP server, and how to handle the auth flow in MCP clients.