Get started
This version supports the MCP authorization specification (version 2025-06-18).
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
MCP Auth is available for both Python and TypeScript. Let us know if you need support for another language or framework!
- Python
- Node.js
pip install mcpauth
Or any other package manager you prefer, such as pipenv or poetry.
npm install mcp-auth
Or any other package manager you prefer, such as pnpm or yarn.
Init 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:
- Python
- Node.js
from mcpauth import MCPAuth
from mcpauth.config import AuthServerType, ResourceServerConfig, ResourceServerMetadata
from mcpauth.utils import fetch_server_config
# 1. Define your resource identifier and fetch the config for its trusted authorization server.
resource_id = "https://api.example.com/notes"
auth_server_config = fetch_server_config("https://auth.logto.io/oidc", AuthServerType.OIDC)
# 2. Initialize MCPAuth in resource server mode.
# `protected_resources` can be a single object or a list for multiple resources.
mcp_auth = MCPAuth(
protected_resources=ResourceServerConfig(
metadata=ResourceServerMetadata(
resource=resource_id,
authorization_servers=[auth_server_config],
scopes_supported=[
"read:notes",
"write:notes",
],
)
)
)
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'],
},
},
],
});
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:
- Python
- Node.js
from starlette.applications import Starlette
# 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 = Starlette(routes=[
*mcp_auth.resource_metadata_router().routes,
])
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.
- Python
- Node.js
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.routing import Mount
# Create the middleware to protect your MCP server with the resource-specific policy.
bearer_auth = Middleware(mcp_auth.bearer_auth_middleware('jwt',
resource=resource_id,
audience=resource_id, # Enable audience validation for security
required_scopes=['read:notes']
))
# Mount the router to serve the Protected Resource Metadata and protect the MCP server.
app = Starlette(
routes=[
*mcp_auth.resource_metadata_router().routes,
# Protect the MCP server with the Bearer auth middleware.
Mount("/", app=mcp.sse_app(), middleware=[bearer_auth]),
],
)
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:
- Python
- Node.js
MCP Auth will store the authenticated user's information in a context variable after successful authentication once the Bearer auth middleware is applied. You can access it in your MCP tool handlers like this:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP()
# Initialize with MCP Auth as shown in previous examples
# ...
@mcp.tool()
def add(a: int, b: int):
"""
A tool that adds two numbers.
The authenticated user's information will be available in the context.
"""
auth_info = mcp_auth.auth_info # Access the auth info in the current context
if auth_info:
print(f"Authenticated user: {auth_info.claims}")
return a + b
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.tool('add', { 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.