MCP OAuth2.1 with AWS Cognito Example
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP OAuth2.1 with AWS Cognito Exampleauthenticate with OAuth2.1"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP + OAuth2.1 + AWS Cognito Example
Overview
This repository demonstrates how to secure a Model Context Protocol (MCP) server using OAuth 2.1 authorization flows, implemented entirely with Node.js and Express.js. While this example uses AWS Cognito as the backing authorization server, the implementation is provider-agnostic and can work with any OAuth 2.1 compliant authorization server.
Based on the MCP Authorization Specification (version 2025-11-25), this project showcases:
MCP server acting as a Resource Server (RS) with generic OAuth endpoints
Provider-agnostic OAuth 2.1 implementation (example uses AWS Cognito)
OAuth 2.1 Authorization Code Flow with PKCE and RFC 8707 Resource Indicators
Protected Resource Metadata (PRM) document discovery
Fully dynamic authorization server metadata discovery
Dynamic Client Registration (DCR) support
Client ID Metadata Documents (CIMD) support
Enhanced security features from MCP 2025-11-25 specification
Three client implementations:
Static client with pre-configured credentials
Auto-discovery client with dynamic registration (DCR)
Metadata client using Client ID Metadata Documents (CIMD)
Provider-Agnostic Design
This implementation follows OAuth 2.1 standards to ensure compatibility with any compliant authorization server:
MCP Server: Exposes standard OAuth metadata endpoints and proxies to the backing authorization server
Clients: Discover authorization servers dynamically without hardcoded provider-specific logic
Token Validation: Uses discovered JWKS URIs and issuer information from authorization server metadata
Flexible Backend: While Cognito is used as an example, any OAuth 2.1 server can be substituted
Understanding the New MCP Authorization Spec
The new MCP Authorization Specification introduces a clean separation between Resource Servers and Authorization Servers, making it easier to integrate with existing identity providers like AWS Cognito, Okta, Auth0, and others.
Key components of the specification:
Protected Resource Metadata (PRM) document
The MCP server serves this document at
/.well-known/oauth-protected-resourceContains information about authorization servers, supported scopes, etc.
Follows RFC9728 (OAuth 2.0 Protected Resource Metadata)
Discovery Process
When a client receives a 401 Unauthorized response, the WWW-Authenticate header contains a pointer to the PRM document
Client fetches the PRM document to discover the authorization server URL
Client fetches authorization server metadata dynamically from the discovered URL (no hardcoded endpoints)
OAuth 2.1 Authorization
Authorization Code flow with PKCE
Bearer token usage for authenticated requests
Dynamic token validation using discovered JWKS URIs and issuer information
Client Registration Priority (MCP 2025-11-25)
Pre-registered client credentials (if available for the server)
Client ID Metadata Documents (if authorization server advertises
client_id_metadata_document_supported: true)Dynamic Client Registration (RFC7591 fallback)
Prompt user for manual configuration (last resort)
Dynamic Client Registration (DCR)
Allows clients to automatically register with new MCP servers
Eliminates the need for manual client registration processes
Follows RFC7591 (OAuth 2.0 Dynamic Client Registration Protocol)
Client ID Metadata Documents (CIMD)
Client publishes its OAuth metadata at an HTTPS URL
The URL itself becomes the
client_idAuthorization server fetches and validates the metadata document
No pre-registration or database storage required
This implementation showcases how to apply these concepts in a provider-agnostic way. The example uses AWS Cognito with custom Dynamic Client Registration through API Gateway endpoints and Lambda functions, but the core OAuth flow works with any compliant authorization server.
Architecture
Client → MCP Server → Authorization Server (e.g., AWS Cognito)
(Resource Server) (OAuth 2.1 Provider)Client sends a request without a token.
MCP server responds with 401 Unauthorized + WWW-Authenticate header pointing to PRM metadata.
Client retrieves PRM, discovers the Authorization Server URL dynamically.
Client fetches authorization server metadata and performs OAuth 2.1 Authorization Code flow (with PKCE).
Client obtains an access token and retries request to MCP server.
MCP server validates token using dynamically discovered JWKS and grants access to the protected resource.
For detailed overview, see the Architecture Overview.
Diagrams:
Dynamic Client Registration (DCR)
This implementation includes support for OAuth 2.1 Dynamic Client Registration, allowing clients to:
Dynamically discover the MCP server and authorization endpoints
Register themselves with the authorization server
Obtain credentials for the OAuth flow
The DCR flow works as follows:
Client discovers the MCP server's protected resource metadata
Client discovers the authorization server (Cognito)
Client registers with the DCR endpoint in API Gateway
Registration creates a Cognito app client and returns credentials
Client uses these credentials for the standard OAuth 2.1 flow
Implementation Note: AWS Cognito does not natively support Dynamic Client Registration as specified in OAuth 2.0 DCR (RFC7591). This implementation bridges this gap by using:
API Gateway endpoints to provide the DCR API interface
Lambda functions to create Cognito app clients programmatically
DynamoDB to store the registration data
This approach allows us to maintain compliance with the MCP specification's DCR recommendation while leveraging AWS Cognito for robust authentication and authorization.
Security Note: This implementation uses anonymous DCR without additional authentication. For production environments, consider adding:
Rate limiting on registration requests
Client authentication (mTLS, initial access tokens)
Approval workflow for new clients
Limited scope access for dynamically registered clients
See our DCR Security Recommendations to enhance the security of the registration process.
Client ID Metadata Documents (CIMD)
The MCP Authorization Specification (2025-11-25) introduced Client ID Metadata Documents as the recommended client registration method. CIMD allows a client to use an HTTPS URL as its client_id, with the URL hosting a JSON document describing the client's OAuth metadata.
How CIMD Works
Client publishes a metadata document at a URL (e.g.,
http://localhost:3003/client-metadata.json)During OAuth authorization, the client uses this URL as its
client_idThe authorization server fetches the metadata document from the URL
The server validates the document structure and redirect URIs
The client proceeds with a standard OAuth 2.1 flow
CIMD Metadata Document Example
{
"client_id": "http://localhost:3003/client-metadata.json",
"redirect_uris": ["http://localhost:3003/callback"],
"client_name": "MCP CIMD Demo Client",
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}CIMD Authorization Proxy
AWS Cognito does not natively support Client ID Metadata Documents, just as it doesn't natively support DCR. This implementation bridges CIMD transparently through the MCP server's authorization proxy:
The MCP server advertises
client_id_metadata_document_supported: truein authorization server metadataThe MCP server overrides
authorization_endpointandtoken_endpointin metadata to point to itselfWhen a client presents a URL-based
client_id:The proxy fetches and validates the client's metadata document
Transparently creates a Cognito app client via the existing DCR infrastructure
Forwards the request to Cognito with the mapped credentials
When a client presents a standard
client_id(pre-registered or DCR): requests are passed through to Cognito unchanged
The metadata-client has zero custom code for CIMD — it simply uses its metadata URL as client_id with standard OAuth endpoints, just like any spec-compliant client. All bridging is handled server-side.
CIMD Security
The authorization proxy includes:
SSRF protection (blocks private IP ranges, enforces HTTPS in production)
Strict
client_idvalidation (must match the metadata URL exactly)Redirect URI validation
Response size limits (64KB) and fetch timeouts (5s)
In-memory caching to prevent redundant fetches
Note: In development, http://localhost URLs are permitted. Production deployments must use HTTPS.
Quick Start
Prerequisites
Node.js 18+ installed
AWS test account with access to:
Cognito for Authorization Server (1 user pool, 2 app clients)
API Gateway / Lambda / DynamoDB for DCR and CIMD bridge (2 resources, 2 functions, 1 table)
CloudFormation for deploy (1 stack)
Basic knowledge of OAuth 2.1 flows
Setup
Clone the repository
git clone https://github.com/empires-security/mcp-oauth2-aws-cognito.git cd mcp-oauth2-aws-cognitoInstall dependencies for clients and server
npm run install:allDeploy AWS resources
npm run deployReview generated
.envfiles in:src/client/.envsrc/auto-client/.envsrc/metadata-client/.envsrc/mcp-server/.envCompare with
.env.examplefilesManually verify/update CLIENT_SECRET if needed
Running the Application
Start all services (server + 3 clients)
npm run devVisit http://localhost:3000 to test the pre-registered client OAuth flow
Sign Up for a New User
Click the "Log in" button
Select "Sign up" in the Cognito hosted UI
Create a new user account
Verify your account by entering the confirmation code sent to your email
After successful verification, you'll be redirected back to the application
Click the "Fetch MCP Data" button to make an authenticated request to the MCP server
Visit http://localhost:3002 to test the DCR flow (auto-discovery client with Dynamic Client Registration)
Visit http://localhost:3003 to test the CIMD flow (Client ID Metadata Document client)
Cleanup
Cleanup AWS resources
npm run cleanup
For detailed setup instructions, see the Setup Guide.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Fork the repository
Create your feature branch (
git checkout -b feature/amazing-feature)Commit your changes (
git commit -m 'Add some amazing feature')Push to the branch (
git push origin feature/amazing-feature)Open a Pull Request
References
License
This project is licensed under the MIT License - see the LICENSE file for details.
Authors
Empires Security Labs 🚀
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/empires-security/mcp-oauth2-aws-cognito'
If you have feedback or need assistance with the MCP directory API, please join our Discord server