use std::collections::HashMap; use anyhow::Result; use codex_protocol::protocol::McpAuthStatus; use codex_rmcp_client::OAuthCredentialsStoreMode; use codex_rmcp_client::determine_streamable_http_auth_status; use futures::future::join_all; use tracing::warn; use crate::config_types::McpServerConfig; use crate::config_types::McpServerTransportConfig; #[derive(Debug, Clone)] pub struct McpAuthStatusEntry { pub config: McpServerConfig, pub auth_status: McpAuthStatus, } pub async fn compute_auth_statuses<'a, I>( servers: I, store_mode: OAuthCredentialsStoreMode, ) -> HashMap where I: IntoIterator, { let futures = servers.into_iter().map(|(name, config)| { let name = name.clone(); let config = config.clone(); async move { let auth_status = match compute_auth_status(&name, &config, store_mode).await { Ok(status) => status, Err(error) => { warn!("failed to determine auth status for MCP server `{name}`: {error:?}"); McpAuthStatus::Unsupported } }; let entry = McpAuthStatusEntry { config, auth_status, }; (name, entry) } }); join_all(futures).await.into_iter().collect() } async fn compute_auth_status( server_name: &str, config: &McpServerConfig, store_mode: OAuthCredentialsStoreMode, ) -> Result { match &config.transport { McpServerTransportConfig::Stdio { .. } => Ok(McpAuthStatus::Unsupported), McpServerTransportConfig::StreamableHttp { url, bearer_token_env_var, http_headers, env_http_headers, } => { determine_streamable_http_auth_status( server_name, url, bearer_token_env_var.as_deref(), http_headers.clone(), env_http_headers.clone(), store_mode, ) .await } } }