mirror of
https://github.com/openai/codex.git
synced 2026-10-23 18:08:45 +00:00
## Summary - classify authentication-required RMCP startup failures, including errors nested inside `ClientInitializeError::TransportError` - let `codex-mcp` consume that classification so the existing `reauthenticationRequired` startup failure reason is emitted - add a regression test that performs real startup with an expired persisted OAuth token and no refresh token ## Why Follow-up to #29877. RMCP stores streamable HTTP initialization failures inside a dynamic transport error whose payload is not exposed through the standard Rust error source chain. The original `anyhow::Error::chain()` check therefore missed the nested `AuthError::AuthorizationRequired` seen during real MCP startup and emitted `failureReason: null`. The transport-specific inspection now lives in `codex-rmcp-client`, while `codex-mcp` consumes only the domain-level authentication-required result. This classifier does not distinguish first-time login from reauthentication; the existing auth-state logic remains responsible for that distinction. ## User impact When stored MCP OAuth credentials are expired and cannot be refreshed, app clients now receive `failureReason: "reauthenticationRequired"` on the failed startup update and can show the reconnect action. First-time login and unrelated startup failures remain unchanged. ## Validation - `just test -p codex-rmcp-client --test streamable_http_oauth_startup identifies_expired_unrefreshable_token_startup_error` - `just test -p codex-mcp startup_outcome_error_identifies_authentication_required` - `just test -p codex-mcp mcp_startup_failure_reason_requires_existing_oauth_and_auth_failure` - `cargo build -p codex-cli --bin codex` - local app-server probe emitted `failureReason: "reauthenticationRequired"` - manual end-to-end reconnect flow confirmed - `just fmt`
48 lines
1.8 KiB
Rust
48 lines
1.8 KiB
Rust
mod auth_status;
|
|
mod elicitation_client_service;
|
|
mod executor_process_transport;
|
|
mod http_client_adapter;
|
|
mod in_process_transport;
|
|
mod logging_client_handler;
|
|
mod oauth;
|
|
mod oauth_http_client;
|
|
mod perform_oauth_login;
|
|
mod program_resolver;
|
|
mod rmcp_client;
|
|
mod startup_error;
|
|
mod stdio_server_launcher;
|
|
mod utils;
|
|
|
|
pub use auth_status::McpAuthState;
|
|
pub use auth_status::McpLoginRequirement;
|
|
pub use auth_status::StreamableHttpOAuthDiscovery;
|
|
pub use auth_status::determine_streamable_http_auth_status;
|
|
pub use auth_status::determine_streamable_http_auth_status_with_http_client;
|
|
pub use auth_status::discover_streamable_http_oauth;
|
|
pub use auth_status::discover_streamable_http_oauth_with_http_client;
|
|
pub use auth_status::supports_oauth_login;
|
|
pub use codex_protocol::protocol::McpAuthStatus;
|
|
pub use in_process_transport::InProcessTransportFactory;
|
|
pub use oauth::StoredOAuthTokens;
|
|
pub use oauth::WrappedOAuthTokenResponse;
|
|
pub use oauth::delete_oauth_tokens;
|
|
pub(crate) use oauth::load_oauth_tokens;
|
|
pub use oauth::save_oauth_tokens;
|
|
pub use perform_oauth_login::OAuthProviderError;
|
|
pub use perform_oauth_login::OauthLoginHandle;
|
|
pub use perform_oauth_login::perform_oauth_login;
|
|
pub use perform_oauth_login::perform_oauth_login_return_url;
|
|
pub use perform_oauth_login::perform_oauth_login_return_url_with_http_client;
|
|
pub use perform_oauth_login::perform_oauth_login_silent;
|
|
pub use rmcp::model::ElicitationAction;
|
|
pub use rmcp_client::Elicitation;
|
|
pub use rmcp_client::ElicitationResponse;
|
|
pub use rmcp_client::ListToolsWithConnectorIdResult;
|
|
pub use rmcp_client::RmcpClient;
|
|
pub use rmcp_client::SendElicitation;
|
|
pub use rmcp_client::ToolWithConnectorId;
|
|
pub use startup_error::is_authentication_required_error;
|
|
pub use stdio_server_launcher::ExecutorStdioServerLauncher;
|
|
pub use stdio_server_launcher::LocalStdioServerLauncher;
|
|
pub use stdio_server_launcher::StdioServerLauncher;
|