diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 23751d1b..2eb80cfa 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -426,13 +426,16 @@ impl Session { // Surface individual client start-up failures to the user. if !failed_clients.is_empty() { for (server_name, err) in failed_clients { + let auth_status = auth_statuses.get(&server_name); + let requires_login = match auth_status { + Some(McpAuthStatus::NotLoggedIn) => true, + Some(McpAuthStatus::OAuth) => is_mcp_client_auth_required_error(&err), + _ => false, + }; let log_message = format!("MCP client for `{server_name}` failed to start: {err:#}"); error!("{log_message}"); - let display_message = if matches!( - auth_statuses.get(&server_name), - Some(McpAuthStatus::NotLoggedIn) - ) { + let display_message = if requires_login { format!( "The {server_name} MCP server is not logged in. Run `codex mcp login {server_name}` to log in." ) @@ -2524,6 +2527,11 @@ pub(crate) async fn exit_review_mode( .await; } +fn is_mcp_client_auth_required_error(error: &anyhow::Error) -> bool { + // StreamableHttpError::AuthRequired from the MCP SDK. + error.to_string().contains("Auth required") +} + use crate::executor::errors::ExecError; use crate::executor::linkers::PreparedExec; use crate::tools::context::ApplyPatchCommandContext;