remote_mcp_kernel/
config.rs

1//! Configuration management for MCP OAuth server
2//!
3//! This module provides environment variable loading functions following
4//! the principle of single responsibility and making configuration
5//! explicit and testable.
6
7use std::env;
8
9/// Server configuration values
10pub fn get_server_host() -> String {
11    env::var("MCP_HOST").unwrap_or_else(|_| "localhost".to_string())
12}
13
14pub fn get_server_port() -> Result<u16, ConfigError> {
15    env::var("MCP_PORT")
16        .unwrap_or_else(|_| "8080".to_string())
17        .parse::<u16>()
18        .map_err(|_| ConfigError::InvalidPort)
19}
20
21pub fn get_server_bind_address() -> Result<String, ConfigError> {
22    let port = get_server_port()?;
23    Ok(env::var("MCP_BIND_ADDRESS").unwrap_or_else(|_| format!("0.0.0.0:{}", port)))
24}
25
26pub fn get_server_name() -> String {
27    "MCP OAuth Server".to_string()
28}
29
30pub fn get_server_version() -> String {
31    env!("CARGO_PKG_VERSION").to_string()
32}
33
34pub fn get_server_description() -> String {
35    "MCP server with OAuth authentication capabilities".to_string()
36}
37
38/// GitHub OAuth configuration values
39pub fn get_github_client_id() -> Result<String, ConfigError> {
40    env::var("GITHUB_CLIENT_ID").map_err(|_| ConfigError::MissingGitHubClientId)
41}
42
43pub fn get_github_client_secret() -> Result<String, ConfigError> {
44    env::var("GITHUB_CLIENT_SECRET").map_err(|_| ConfigError::MissingGitHubClientSecret)
45}
46
47pub fn get_github_scope() -> String {
48    env::var("GITHUB_SCOPE").unwrap_or_else(|_| "read:user".to_string())
49}
50
51/// AWS Cognito OAuth configuration values
52pub fn get_cognito_client_id() -> Result<String, ConfigError> {
53    env::var("COGNITO_CLIENT_ID").map_err(|_| ConfigError::MissingCognitoClientId)
54}
55
56pub fn get_cognito_client_secret() -> Option<String> {
57    env::var("COGNITO_CLIENT_SECRET").ok()
58}
59
60pub fn get_cognito_scope() -> String {
61    env::var("COGNITO_SCOPE").unwrap_or_else(|_| "openid email profile phone".to_string())
62}
63
64pub fn get_cognito_domain() -> Result<String, ConfigError> {
65    env::var("COGNITO_DOMAIN").map_err(|_| ConfigError::MissingCognitoDomain)
66}
67
68pub fn get_cognito_region() -> Result<String, ConfigError> {
69    env::var("COGNITO_REGION").map_err(|_| ConfigError::MissingCognitoRegion)
70}
71
72pub fn get_cognito_user_pool_id() -> Result<String, ConfigError> {
73    env::var("COGNITO_USER_POOL_ID").map_err(|_| ConfigError::MissingCognitoUserPoolId)
74}
75
76/// Logging configuration values
77pub fn get_logging_level() -> String {
78    env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string())
79}
80
81pub fn get_logging_format() -> String {
82    env::var("LOG_FORMAT").unwrap_or_else(|_| "json".to_string())
83}
84
85/// OAuth provider configuration values
86pub fn get_oauth_provider_config() -> oauth_provider_rs::http_integration::config::OAuthProviderConfig {
87    oauth_provider_rs::http_integration::config::OAuthProviderConfig::default()
88}
89
90/// GitHub OAuth provider configuration
91pub fn get_github_oauth_provider_config() -> Result<oauth_provider_rs::providers::provider_trait::OAuthProviderConfig, ConfigError> {
92    Ok(oauth_provider_rs::providers::provider_trait::OAuthProviderConfig::with_oauth_config(
93        get_github_client_id()?,
94        get_github_client_secret()?,
95        // redirect_uri will be determined dynamically from request headers
96        "".to_string(),
97        "read:user".to_string(),
98        "github".to_string(),
99    ))
100}
101
102/// Cognito OAuth provider configuration
103pub fn get_cognito_oauth_provider_config() -> Result<oauth_provider_rs::providers::provider_trait::OAuthProviderConfig, ConfigError> {
104    Ok(oauth_provider_rs::providers::provider_trait::OAuthProviderConfig::with_oauth_config(
105        get_cognito_client_id()?,
106        get_cognito_client_secret().unwrap_or_default(),
107        // redirect_uri will be determined dynamically from request headers
108        "".to_string(),
109        get_cognito_scope(),
110        "cognito".to_string(),
111    ))
112}
113
114/// Get server bind address as SocketAddr
115pub fn get_bind_socket_addr() -> Result<std::net::SocketAddr, ConfigError> {
116    get_server_bind_address()?
117        .parse()
118        .map_err(|_| ConfigError::InvalidBindAddress)
119}
120
121/// Configuration errors
122#[derive(Debug, thiserror::Error)]
123pub enum ConfigError {
124    #[error("Missing GITHUB_CLIENT_ID environment variable")]
125    MissingGitHubClientId,
126    #[error("Missing GITHUB_CLIENT_SECRET environment variable")]
127    MissingGitHubClientSecret,
128    #[error("Missing COGNITO_CLIENT_ID environment variable")]
129    MissingCognitoClientId,
130    #[error("Missing COGNITO_DOMAIN environment variable")]
131    MissingCognitoDomain,
132    #[error("Missing COGNITO_REGION environment variable")]
133    MissingCognitoRegion,
134    #[error("Missing COGNITO_USER_POOL_ID environment variable")]
135    MissingCognitoUserPoolId,
136    #[error("Invalid port number")]
137    InvalidPort,
138    #[error("Invalid bind address")]
139    InvalidBindAddress,
140}
141
142#[cfg(test)]
143mod tests {
144    use super::*;
145
146    #[test]
147    fn test_server_defaults() {
148        // Test default server configuration
149        assert_eq!(get_server_name(), "MCP OAuth Server");
150        assert_eq!(get_server_description(), "MCP server with OAuth authentication capabilities");
151        assert_eq!(get_github_scope(), "read:user");
152        assert_eq!(get_cognito_scope(), "openid email profile phone");
153        assert_eq!(get_logging_level(), "info");
154    }
155
156    #[test]
157    fn test_missing_github_config() {
158        unsafe {
159            env::remove_var("GITHUB_CLIENT_ID");
160            env::remove_var("GITHUB_CLIENT_SECRET");
161        }
162
163        let result = get_github_oauth_provider_config();
164        assert!(result.is_err());
165    }
166
167    #[test]
168    fn test_missing_cognito_config() {
169        unsafe {
170            env::remove_var("COGNITO_CLIENT_ID");
171            env::remove_var("COGNITO_DOMAIN");
172            env::remove_var("COGNITO_REGION");
173            env::remove_var("COGNITO_USER_POOL_ID");
174        }
175
176        let result = get_cognito_oauth_provider_config();
177        assert!(result.is_err());
178    }
179}