mirror of
https://github.com/openai/codex.git
synced 2026-11-11 21:10:39 +00:00
Allow cached catalogs to satisfy MCP startup readiness (#47935)
## Why Required MCP servers can block startup while establishing a live connection even when a usable tool catalog is already cached. ## What changed - Add per-server `startup_readiness = "catalog"` to expose cached tools while the connection starts, retaining `"connection"` as the default. - Allow an eligible cached catalog to satisfy required-server startup validation and model binding capture. Explicit server or plugin requirements still wait for a live connection, and tool execution still requires the current connection. - Check tool filters and model visibility when accepting cached catalogs, and preserve cached catalog revisions for binding reuse. - Serialize the new setting, expose it in the configuration schema, and trace startup readiness at validation and model binding gates. GitOrigin-RevId: a1cbdf1757ebb5824cffe2cc56408be49711c422
This commit is contained in:
@@ -176,6 +176,7 @@ pub use mcp_types::McpServerEnvVar;
|
||||
pub use mcp_types::McpServerOAuthConfig;
|
||||
pub use mcp_types::McpServerToolConfig;
|
||||
pub use mcp_types::McpServerTransportConfig;
|
||||
pub use mcp_types::McpStartupReadiness;
|
||||
pub use mcp_types::RawMcpServerConfig;
|
||||
pub use merge::ShellEnvironmentPolicyFilterRepresentation;
|
||||
pub use merge::is_structured_feature_path;
|
||||
|
||||
@@ -17,6 +17,7 @@ fn stdio_server(command: &str, args: &[&str]) -> McpServerConfig {
|
||||
environment_id: crate::DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string(),
|
||||
enabled: true,
|
||||
required: false,
|
||||
startup_readiness: Default::default(),
|
||||
supports_parallel_tool_calls: false,
|
||||
omit_tools_from: None,
|
||||
disabled_reason: None,
|
||||
|
||||
@@ -213,10 +213,20 @@ pub enum McpServerAuth {
|
||||
EmaAuth,
|
||||
}
|
||||
|
||||
impl McpServerAuth {
|
||||
fn is_default(&self) -> bool {
|
||||
self == &Self::default()
|
||||
}
|
||||
/// Readiness needed before startup can expose this server's tools to the model.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Default, PartialEq, Eq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum McpStartupReadiness {
|
||||
/// Use the live connection to determine startup readiness.
|
||||
#[default]
|
||||
Connection,
|
||||
/// Allow a valid cached tool catalog while the live connection starts.
|
||||
/// Tool execution still requires the current connection.
|
||||
Catalog,
|
||||
}
|
||||
|
||||
fn is_default<T: Default + PartialEq>(value: &T) -> bool {
|
||||
value == &T::default()
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Clone, PartialEq)]
|
||||
@@ -225,7 +235,7 @@ pub struct McpServerConfig {
|
||||
pub transport: McpServerTransportConfig,
|
||||
|
||||
/// Authentication flow, including an explicit no-fallback EMA mode.
|
||||
#[serde(default, skip_serializing_if = "McpServerAuth::is_default")]
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub auth: McpServerAuth,
|
||||
|
||||
/// Effective environment id for where Codex should start this MCP server.
|
||||
@@ -236,9 +246,15 @@ pub struct McpServerConfig {
|
||||
pub enabled: bool,
|
||||
|
||||
/// When `true`, `codex exec` exits with an error if this MCP server fails to initialize.
|
||||
/// With `startup_readiness = "catalog"`, a valid cached catalog can satisfy startup;
|
||||
/// connection failures are then reported when a tool is invoked.
|
||||
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||
pub required: bool,
|
||||
|
||||
/// Whether startup requires a live connection or can use a valid cached tool catalog.
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub startup_readiness: McpStartupReadiness,
|
||||
|
||||
/// When `true`, every tool from this server is advertised as safe for parallel tool calls.
|
||||
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||
pub supports_parallel_tool_calls: bool,
|
||||
@@ -391,6 +407,9 @@ pub struct RawMcpServerConfig {
|
||||
pub enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub required: Option<bool>,
|
||||
/// Whether startup requires a live connection or can use a valid cached tool catalog.
|
||||
#[serde(default)]
|
||||
pub startup_readiness: Option<McpStartupReadiness>,
|
||||
#[serde(default)]
|
||||
pub supports_parallel_tool_calls: Option<bool>,
|
||||
#[serde(default)]
|
||||
@@ -437,6 +456,7 @@ impl TryFrom<RawMcpServerConfig> for McpServerConfig {
|
||||
tool_timeout_sec,
|
||||
enabled,
|
||||
required,
|
||||
startup_readiness,
|
||||
supports_parallel_tool_calls,
|
||||
omit_tools_from,
|
||||
default_tools_approval_mode,
|
||||
@@ -556,6 +576,7 @@ impl TryFrom<RawMcpServerConfig> for McpServerConfig {
|
||||
tool_timeout_sec,
|
||||
enabled: enabled.unwrap_or_else(default_enabled),
|
||||
required: required.unwrap_or_default(),
|
||||
startup_readiness: startup_readiness.unwrap_or_default(),
|
||||
supports_parallel_tool_calls: supports_parallel_tool_calls.unwrap_or_default(),
|
||||
omit_tools_from,
|
||||
disabled_reason: None,
|
||||
|
||||
@@ -640,6 +640,7 @@ fn deserialize_ignores_unknown_server_fields() {
|
||||
environment_id: crate::DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string(),
|
||||
enabled: true,
|
||||
required: false,
|
||||
startup_readiness: Default::default(),
|
||||
supports_parallel_tool_calls: false,
|
||||
omit_tools_from: None,
|
||||
disabled_reason: None,
|
||||
|
||||
@@ -13,6 +13,7 @@ pub use crate::mcp_types::McpServerEnvVar;
|
||||
pub use crate::mcp_types::McpServerOAuthConfig;
|
||||
pub use crate::mcp_types::McpServerToolConfig;
|
||||
pub use crate::mcp_types::McpServerTransportConfig;
|
||||
pub use crate::mcp_types::McpStartupReadiness;
|
||||
pub use crate::mcp_types::RawMcpServerConfig;
|
||||
pub use crate::shell_environment_policy::ShellEnvironmentPolicyToml;
|
||||
pub use codex_protocol::config_types::AltScreenMode;
|
||||
|
||||
Reference in New Issue
Block a user