mirror of
https://github.com/openai/codex.git
synced 2026-10-28 16:06:15 +00:00
Avoid blocking thread startup on MCP OAuth discovery (#32825)
## Why OAuth metadata discovery for an optional HTTP MCP server can stall, delaying `thread/start` even though that server is not required. ## What changed - Remove eager MCP authentication-status discovery from session and connection manager startup. - When an MCP connection reports an authentication error, inspect configured and stored credentials locally to preserve login and reauthentication failure reasons without making another discovery request. - Continue using server configuration directly for startup error messages and timeout hints. ## Testing Add an app-server regression test with an optional HTTP MCP endpoint that accepts a connection but never responds, and verify that `thread/start` completes without waiting for its configured startup timeout. GitOrigin-RevId: 56fe0188cc1ceaf746b0b65e8b7dd1fd2e13420d
This commit is contained in:
@@ -38,7 +38,6 @@ use codex_mcp::McpConnectionManager;
|
||||
use codex_mcp::McpRuntimeContext;
|
||||
use codex_mcp::ToolInfo;
|
||||
use codex_mcp::ToolPluginProvenance;
|
||||
use codex_mcp::compute_auth_statuses;
|
||||
use codex_mcp::effective_mcp_servers;
|
||||
use codex_mcp::tool_plugin_provenance;
|
||||
|
||||
@@ -235,14 +234,6 @@ pub async fn list_accessible_connectors_from_mcp_tools_with_mcp_manager(
|
||||
|
||||
let runtime_context =
|
||||
McpRuntimeContext::new(Arc::clone(&environment_manager), config.cwd.to_path_buf());
|
||||
let auth_status_entries = compute_auth_statuses(
|
||||
mcp_servers.iter(),
|
||||
config.mcp_oauth_credentials_store_mode,
|
||||
config.auth_keyring_backend_kind(),
|
||||
auth.as_ref(),
|
||||
&runtime_context,
|
||||
)
|
||||
.await;
|
||||
|
||||
let (tx_event, rx_event) = unbounded();
|
||||
drop(rx_event);
|
||||
@@ -255,7 +246,6 @@ pub async fn list_accessible_connectors_from_mcp_tools_with_mcp_manager(
|
||||
&mcp_servers,
|
||||
config.mcp_oauth_credentials_store_mode,
|
||||
config.auth_keyring_backend_kind(),
|
||||
auth_status_entries,
|
||||
&config.permissions.approval_policy,
|
||||
INITIAL_SUBMIT_ID.to_owned(),
|
||||
tx_event,
|
||||
|
||||
@@ -1439,7 +1439,6 @@ async fn host_owned_codex_apps_manager(
|
||||
&mcp_servers,
|
||||
turn_context.config.mcp_oauth_credentials_store_mode,
|
||||
turn_context.config.auth_keyring_backend_kind(),
|
||||
HashMap::new(),
|
||||
&turn_context.approval_policy,
|
||||
turn_context.sub_id.clone(),
|
||||
tx_event,
|
||||
|
||||
@@ -347,14 +347,6 @@ impl Session {
|
||||
turn_context.cwd.to_path_buf()
|
||||
});
|
||||
let mcp_runtime_context = McpRuntimeContext::new(environment_manager, cwd);
|
||||
let auth_statuses = compute_auth_statuses(
|
||||
mcp_servers.iter(),
|
||||
mcp_config.mcp_oauth_credentials_store_mode,
|
||||
mcp_config.auth_keyring_backend_kind,
|
||||
auth.as_ref(),
|
||||
&mcp_runtime_context,
|
||||
)
|
||||
.await;
|
||||
let mcp_startup_cancellation_token = {
|
||||
let mut guard = self.services.mcp_startup_cancellation_token.lock().await;
|
||||
// The previous runtime owns the old token and may still be serving an in-flight step.
|
||||
@@ -371,7 +363,6 @@ impl Session {
|
||||
&mcp_servers,
|
||||
mcp_config.mcp_oauth_credentials_store_mode,
|
||||
mcp_config.auth_keyring_backend_kind,
|
||||
auth_statuses,
|
||||
&turn_context.approval_policy,
|
||||
turn_context.sub_id.clone(),
|
||||
self.get_tx_event(),
|
||||
|
||||
@@ -332,7 +332,6 @@ use codex_core_plugins::PluginsManager;
|
||||
use codex_core_plugins::RecommendedPluginCandidatesInput;
|
||||
use codex_git_utils::get_git_repo_root;
|
||||
use codex_mcp::McpConfig;
|
||||
use codex_mcp::compute_auth_statuses;
|
||||
use codex_mcp::effective_mcp_servers;
|
||||
use codex_otel::SessionTelemetry;
|
||||
use codex_otel::THREAD_STARTED_METRIC;
|
||||
|
||||
@@ -681,7 +681,6 @@ impl Session {
|
||||
.unwrap_or_else(|| session_configuration.cwd().to_path_buf());
|
||||
let mcp_runtime_context =
|
||||
McpRuntimeContext::new(Arc::clone(&environment_manager), mcp_runtime_cwd);
|
||||
let mcp_runtime_context_for_auth = mcp_runtime_context.clone();
|
||||
let auth_and_mcp_fut = async move {
|
||||
let auth = auth_manager_clone.auth().await;
|
||||
let mcp_projection = mcp_manager_for_mcp
|
||||
@@ -696,21 +695,7 @@ impl Session {
|
||||
let mcp_config = &mcp_projection.config;
|
||||
let mcp_servers = codex_mcp::effective_mcp_servers(mcp_config, auth.as_ref());
|
||||
let tool_plugin_provenance = codex_mcp::tool_plugin_provenance(mcp_config);
|
||||
let auth_statuses = compute_auth_statuses(
|
||||
mcp_servers.iter(),
|
||||
config_for_mcp.mcp_oauth_credentials_store_mode,
|
||||
config_for_mcp.auth_keyring_backend_kind(),
|
||||
auth.as_ref(),
|
||||
&mcp_runtime_context_for_auth,
|
||||
)
|
||||
.await;
|
||||
(
|
||||
auth,
|
||||
mcp_projection,
|
||||
mcp_servers,
|
||||
auth_statuses,
|
||||
tool_plugin_provenance,
|
||||
)
|
||||
(auth, mcp_projection, mcp_servers, tool_plugin_provenance)
|
||||
}
|
||||
.instrument(info_span!(
|
||||
"session_init.auth_mcp",
|
||||
@@ -721,7 +706,7 @@ impl Session {
|
||||
let (
|
||||
thread_persistence_result,
|
||||
state_db_ctx,
|
||||
(auth, mcp_projection, mcp_servers, auth_statuses, tool_plugin_provenance),
|
||||
(auth, mcp_projection, mcp_servers, tool_plugin_provenance),
|
||||
) = tokio::join!(thread_persistence_fut, state_db_fut, auth_and_mcp_fut);
|
||||
|
||||
let mut live_thread_init =
|
||||
@@ -1212,7 +1197,6 @@ impl Session {
|
||||
&mcp_servers,
|
||||
config.mcp_oauth_credentials_store_mode,
|
||||
config.auth_keyring_backend_kind(),
|
||||
auth_statuses,
|
||||
&session_configuration.approval_policy,
|
||||
INITIAL_SUBMIT_ID.to_owned(),
|
||||
tx_event.clone(),
|
||||
|
||||
Reference in New Issue
Block a user