1.add oauth2 server and client example 2.add oauth2 impl in sse 3.add auth doc Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
4.4 KiB
4.4 KiB
Model Context Protocol OAuth Authorization
This document describes the OAuth 2.1 authorization implementation for Model Context Protocol (MCP), following the MCP 2025-03-26 Authorization Specification.
Features
- Full support for OAuth 2.1 authorization flow
- PKCE support for enhanced security
- Authorization server metadata discovery
- Dynamic client registration
- Automatic token refresh
- Authorized SSE transport implementation
- Authorized HTTP Client implementation
Usage Guide
1. Enable Features
Enable the auth feature in Cargo.toml:
[dependencies]
rmcp = { version = "0.1", features = ["auth", "transport-sse"] }
2. Use OAuthState
// Initialize oauth state machine
let mut oauth_state = OAuthState::new(&server_url, None)
.await
.context("Failed to initialize oauth state machine")?;
oauth_state
.start_authorization(&["mcp", "profile", "email"], MCP_REDIRECT_URI)
.await
.context("Failed to start authorization")?;
3. Get authorization url and do callback
// Get authorization URL and guide user to open it
let auth_url = oauth_state.get_authorization_url().await?;
println!("Please open the following URL in your browser for authorization:\n{}", auth_url);
// Handle callback - In real applications, this is typically done in a callback server
let auth_code = "Authorization code obtained from browser after user authorization";
let credentials = oauth_state.handle_callback(auth_code).await?;
println!("Authorization successful, access token: {}", credentials.access_token);
4. Use Authorized SSE Transport and create client
let transport =
match create_authorized_transport(MCP_SSE_URL.to_string(), oauth_state, Some(retry_config))
.await
{
Ok(t) => t,
Err(e) => {
tracing::error!("Failed to create authorized transport: {}", e);
return Err(anyhow::anyhow!("Connection failed: {}", e));
}
};
// Create client and connect to MCP server
let client_service = ClientInfo::default();
let client = client_service.serve(transport).await?;
5. May you can use Authorized HTTP Client after authorized
let client = oauth_state.to_authorized_http_client().await?;
Complete Example
client: Please refer to examples/clients/src/oauth_client.rs for a complete usage example.
server: Please refer to examples/servers/src/mcp_oauth_server.rs for a complete usage example.
Running the Example in server
# Run example
cargo run --example mcp_oauth_server
Running the Example in client
# Run example
cargo run --example oauth-client
Authorization Flow Description
- Metadata Discovery: Client attempts to get authorization server metadata from
/.well-known/oauth-authorization-server - Client Registration: If supported, client dynamically registers itself
- Authorization Request: Build authorization URL with PKCE and guide user to access
- Authorization Code Exchange: After user authorization, exchange authorization code for access token
- Token Usage: Use access token for API calls
- Token Refresh: Automatically use refresh token to get new access token when current one expires
Security Considerations
- All tokens are securely stored in memory
- PKCE implementation prevents authorization code interception attacks
- Automatic token refresh support reduces user intervention
- Only accepts HTTPS connections or secure local callback URIs
Troubleshooting
If you encounter authorization issues, check the following:
- Ensure server supports OAuth 2.1 authorization
- Verify callback URI matches server's allowed redirect URIs
- Check network connection and firewall settings
- Verify server supports metadata discovery or dynamic client registration