oauth_cognito_dynamodb_mcp_server/
oauth_cognito_dynamodb_mcp_server.rs1use remote_mcp_kernel::{
52 config::{
53 get_bind_socket_addr, get_cognito_domain, get_cognito_oauth_provider_config,
54 get_cognito_region, get_cognito_user_pool_id, get_logging_level,
55 },
56 error::AppResult,
57 microkernel::create_full_cognito_microkernel_dynamodb,
58};
59use std::env;
60use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
61
62#[tokio::main]
63async fn main() -> AppResult<()> {
64 dotenv::dotenv().ok();
66
67 init_tracing()?;
69
70 tracing::info!("Starting MCP OAuth server with Cognito and DynamoDB storage...");
71
72 let cognito_config = get_cognito_oauth_provider_config()?;
74
75 let table_name =
77 env::var("DYNAMODB_TABLE_NAME").unwrap_or_else(|_| "oauth-storage".to_string());
78 let create_table = env::var("DYNAMODB_CREATE_TABLE")
79 .unwrap_or_else(|_| "true".to_string())
80 .parse::<bool>()
81 .unwrap_or(true);
82
83 log_startup_info(&table_name, create_table);
85
86 let microkernel = create_full_cognito_microkernel_dynamodb(
88 cognito_config,
89 get_cognito_domain()?,
90 get_cognito_region()?,
91 get_cognito_user_pool_id()?,
92 table_name,
93 create_table,
94 )
95 .await
96 .map_err(|e| {
97 remote_mcp_kernel::error::AppError::Internal(format!("Failed to create microkernel: {}", e))
98 })?;
99
100 let bind_address = get_bind_socket_addr()?;
102 microkernel.serve(bind_address).await?;
103
104 Ok(())
105}
106
107fn init_tracing() -> AppResult<()> {
108 tracing_subscriber::registry()
109 .with(
110 tracing_subscriber::EnvFilter::try_from_default_env()
111 .unwrap_or_else(|_| get_logging_level().as_str().into()),
112 )
113 .with(tracing_subscriber::fmt::layer())
114 .init();
115
116 Ok(())
117}
118
119fn log_startup_info(table_name: &str, create_table: bool) {
120 use remote_mcp_kernel::config::{
121 get_cognito_client_id, get_cognito_client_secret, get_cognito_domain, get_cognito_region,
122 get_cognito_scope, get_cognito_user_pool_id, get_server_host, get_server_port,
123 get_server_version,
124 };
125
126 println!("🚀 Starting MCP OAuth server with Cognito and DynamoDB storage...");
127 println!("📋 Configuration:");
128 println!(" - Architecture: Microkernel (independent handlers)");
129 println!(" - OAuth Provider: AWS Cognito");
130 println!(" - Storage Backend: DynamoDB");
131 println!(
132 " - Server: {}:{}",
133 get_server_host(),
134 get_server_port().unwrap_or(8080)
135 );
136 println!(" - Version: {}", get_server_version());
137 println!();
138
139 println!("🔐 AWS Cognito Configuration:");
140 println!(
141 " - Client ID: {}",
142 if get_cognito_client_id().is_ok() {
143 "Configured"
144 } else {
145 "Not configured"
146 }
147 );
148 println!(
149 " - Client Secret: {}",
150 match get_cognito_client_secret() {
151 Some(secret) if !secret.is_empty() => "Configured",
152 _ => "Not configured (Public Client)",
153 }
154 );
155 println!(
156 " - Domain: {}",
157 get_cognito_domain().unwrap_or_else(|_| "Not configured".to_string())
158 );
159 println!(
160 " - Region: {}",
161 get_cognito_region().unwrap_or_else(|_| "Not configured".to_string())
162 );
163 println!(
164 " - User Pool ID: {}",
165 get_cognito_user_pool_id().unwrap_or_else(|_| "Not configured".to_string())
166 );
167 println!(" - Scopes: {}", get_cognito_scope());
168 println!();
169
170 println!("🗄️ DynamoDB Storage Configuration:");
171 println!(" - Table Name: {}", table_name);
172 println!(" - Auto-create Table: {}", create_table);
173 println!(" - TTL Attribute: expires_at");
174 println!();
175
176 println!("🔧 Handlers:");
177 println!(" - OAuth Provider (Cognito authentication & authorization)");
178 println!(" - Streamable HTTP Handler (MCP over HTTP)");
179 println!(" - SSE Handler (MCP over SSE)");
180 println!();
181
182 println!("🔐 Required Environment Variables:");
183 println!(" ## Cognito Configuration");
184 println!(" - COGNITO_CLIENT_ID: Your Cognito app client ID");
185 println!(
186 " - COGNITO_CLIENT_SECRET: Your Cognito app client secret (optional for public clients)"
187 );
188 println!(
189 " - COGNITO_DOMAIN: Your Cognito domain (e.g., mydomain.auth.us-east-1.amazoncognito.com)"
190 );
191 println!(" - AWS_REGION: AWS region (e.g., us-east-1)");
192 println!(" - COGNITO_USER_POOL_ID: Your Cognito user pool ID (e.g., us-east-1_XXXXXXXXX)");
193 println!(" - COGNITO_SCOPE: OAuth scopes (default: 'openid email profile phone')");
194 println!();
195 println!(" ## AWS Configuration (for DynamoDB)");
196 println!(" - AWS_ACCESS_KEY_ID: Your AWS access key ID");
197 println!(" - AWS_SECRET_ACCESS_KEY: Your AWS secret access key");
198 println!(" - AWS_REGION: AWS region (should match AWS_REGION)");
199 println!();
200 println!(" ## Server Configuration");
201 println!(" - MCP_HOST: Server host (default: localhost)");
202 println!(" - MCP_PORT: Server port (default: 8080)");
203 println!(" - DYNAMODB_TABLE_NAME: DynamoDB table name (default: oauth-storage)");
204 println!(" - DYNAMODB_CREATE_TABLE: Whether to auto-create table (default: true)");
205 println!();
206
207 println!("🌐 OAuth 2.0 Endpoints:");
208 let cognito_domain = get_cognito_domain().unwrap_or_else(|_| "Not configured".to_string());
209 println!(
210 " - Authorization: https://{}/oauth2/authorize",
211 cognito_domain
212 );
213 println!(" - Token: https://{}/oauth2/token", cognito_domain);
214 println!(" - JWKS: https://{}/oauth2/jwks", cognito_domain);
215 println!(" - UserInfo: https://{}/oauth2/userInfo", cognito_domain);
216 println!();
217
218 println!("💾 DynamoDB Table Configuration:");
219 println!(" - Table Structure: Single table design with 'pk' primary key");
220 println!(" - TTL Support: Automatic cleanup using 'expires_at' attribute");
221 println!(" - Billing Mode: Pay-per-request (on-demand)");
222 println!(" - Encryption: Server-side encryption enabled");
223 println!();
224
225 println!("🏗️ Microkernel Architecture:");
226 println!(" - Independent handlers that can operate standalone");
227 println!(" - Runtime composition of services");
228 println!(" - Single responsibility per handler");
229 println!(" - Easy testing and maintenance");
230 println!();
231}