[codex] Make MCP connection startup fallible (#27261)

## Why

Required MCP server startup was enforced in `Session::new` after
`McpConnectionManager` had already created the clients. That split let
other manager construction paths bypass the same requirement and exposed
manager internals solely so the session could validate them. Keeping
required-server readiness in the constructor gives every caller one
consistent startup contract.

## What changed

- make `McpConnectionManager::new` return `anyhow::Result<Self>` and
fail when an enabled, required server cannot initialize
- pass the startup cancellation token into the constructor so
required-server waits remain cancellable
- propagate constructor failures through resource reads, connector
discovery, and MCP status collection
- preserve the active manager and cancellation token when a refreshed
replacement fails
- keep required-startup failure collection private and cover the
constructor error contract directly

## Validation

- updated the focused connection-manager test to assert the complete
required-server startup error
- local tests not run; relying on CI
This commit is contained in:
Ahmed Ibrahim authored and GitHub committed 2026-06-10 00:17:58 -07:00
1 parent 00a25e1e0c
commit a7b6baecc6
8 files changed
+129 -107

No files matched your search

+7 -2
View File
@@ -35,6 +35,7 @@ use rmcp::model::ElicitationCapability;
use rmcp::model::ReadResourceRequestParams;
use rmcp::model::ReadResourceResult;
use serde_json::Value;
use tokio_util::sync::CancellationToken;
use crate::codex_apps::codex_apps_tools_cache_key;
use crate::connection_manager::McpConnectionManager;
@@ -293,13 +294,15 @@ pub async fn read_mcp_resource(
.await;
let (tx_event, rx_event) = unbounded();
drop(rx_event);
let (manager, cancel_token) = McpConnectionManager::new(
let cancel_token = CancellationToken::new();
let manager = McpConnectionManager::new(
&mcp_servers,
config.mcp_oauth_credentials_store_mode,
auth_statuses,
&config.approval_policy,
String::new(),
tx_event,
cancel_token.clone(),
PermissionProfile::default(),
runtime_context,
config.codex_home.clone(),
@@ -363,13 +366,15 @@ pub async fn collect_mcp_server_status_snapshot_with_detail(
let (tx_event, rx_event) = unbounded();
drop(rx_event);
let (mcp_connection_manager, cancel_token) = McpConnectionManager::new(
let cancel_token = CancellationToken::new();
let mcp_connection_manager = McpConnectionManager::new(
&mcp_servers,
config.mcp_oauth_credentials_store_mode,
auth_status_entries.clone(),
&config.approval_policy,
submit_id,
tx_event,
cancel_token.clone(),
PermissionProfile::default(),
runtime_context,
config.codex_home.clone(),