mcp-oauth2-aws-cognito
This project demonstrates securing a Model Context Protocol (MCP) server using OAuth 2.1 with AWS Cognito, showcasing features like Dynamic Client Registration and dynamic discovery of authorization server metadata.
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 with AWS Cognito, implemented entirely with Node.js and Express.js.
Based on the new MCP Authorization Specification published in April 2025, this project showcases:
- MCP server acting as a Resource Server (RS)
- AWS Cognito acting as an Authorization Server (AS)
- OAuth 2.1 Authorization Code Flow with PKCE
- Protected Resource Metadata (PRM) document discovery
- Dynamic discovery of Authorization Server metadata
- Dynamic Client Registration (DCR) support
- Two client implementations:
- Static client with pre-configured credentials
- Auto-discovery client with dynamic registration
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-resource
- Contains information about authorization servers, supported scopes, etc.
- Follows RFC9728 (OAuth 2.0 Protected Resource Metadata)
- The MCP server serves this document at
-
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
- Client then fetches the authorization server metadata to discover the endpoints
-
OAuth 2.1 Authorization
- Authorization Code flow with PKCE
- Bearer token usage for authenticated requests
- Token validation on the server side
-
Dynamic Client Registration (DCR)
- Allows clients to automatically register with new MCP servers
- Eliminates the need for manual client registration processes
- Enables seamless discovery and connection to new services
- MCP specification strongly recommends implementing DCR since "clients do not know the set of MCP servers in advance"
- Provides a standardized way to obtain OAuth client credentials
- Follows RFC7591 (OAuth 2.0 Dynamic Client Registration Protocol)
This implementation showcases how to apply these concepts with AWS Cognito, including implementing Dynamic Client Registration through custom API Gateway endpoints and Lambda functions.
Architecture
Client → MCP Server → AWS Cognito
(Resource Server) (Authorization Server)
- 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.
- Client performs OAuth 2.1 Authorization Code flow (with PKCE) against AWS Cognito.
- Client obtains an access token and retries request to MCP server.
- MCP server validates token and grants access to the protected resource.
For detailed overview, see the .
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 to enhance the security of the registration process.
Quick Start
Prerequisites
- Node.js installed
- AWS test account with access to:
- Cognito for Authorization Server (1 user pool, 2 app clients)
- API Gateway / Lambda / DynamoDB for DCR (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-cognito
-
Install dependencies for clients and server
npm run install:all
-
Deploy AWS resources
npm run deploy
-
Review generated
.env
files in:src/client/.env
src/auto-client/.env
src/mcp-server/.env
- Compare with
.env.example
files - Manually verify/update CLIENT_SECRET if needed
Running the Application
-
Start both clients and server
npm run dev
-
Visit http://localhost:3000 to test the 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.
Cleanup
- Cleanup AWS resources
npm run cleanup
For detailed setup instructions, see the .
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
- Model Context Protocol Official Specification
- OAuth 2.1 Draft
- OAuth 2.0 Protected Resource Metadata
- OAuth 2.0 Dynamic Client Registration Protocol
- AWS Cognito Developer Guide
License
This project is licensed under the MIT License - see the LICENSE file for details.
Authors
- Empires Security Labs 🚀