mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Preserve disabled MCP servers across runtime overlays (#27414)
## Why Recent MCP runtime overlay changes replace same-name configured server entries with compatibility or extension-provided configs. Those replacement configs default to enabled, so an MCP server explicitly configured with `enabled = false` could be initialized anyway. The connection manager still filters disabled servers correctly, but the configured disabled state was lost before initialization reached that filter. ## What changed - Remember MCP servers that are disabled in the configured view before applying runtime fallbacks and extension overlays. - Restore `enabled = false` for those servers after overlays, while leaving all other overlay fields and `Remove` precedence unchanged. - Add focused extension-backed regression coverage for a disabled `codex_apps` server. ## Testing - `just fmt` - `just test -p codex-mcp-extension` - `just fix -p codex-core` - `just fix -p codex-mcp-extension` The full workspace `just test` suite was not run.
This commit is contained in:
committed by
GitHub
Unverified
parent
7011044c1c
commit
980f60b664
@@ -45,6 +45,12 @@ impl McpManager {
|
||||
/// runtime-only extension overlays.
|
||||
pub async fn runtime_config(&self, config: &Config) -> McpConfig {
|
||||
let mut mcp_config = config.to_mcp_config(self.plugins_manager.as_ref()).await;
|
||||
let disabled_server_names = mcp_config
|
||||
.configured_mcp_servers
|
||||
.iter()
|
||||
.filter(|(_, server)| !server.enabled)
|
||||
.map(|(name, _)| name.clone())
|
||||
.collect::<Vec<_>>();
|
||||
if mcp_config.apps_enabled {
|
||||
mcp_config.configured_mcp_servers.insert(
|
||||
CODEX_APPS_MCP_SERVER_NAME.to_string(),
|
||||
@@ -60,6 +66,11 @@ impl McpManager {
|
||||
}
|
||||
let contributions = self.contributions(config).await;
|
||||
Self::apply_to_configured_servers(&contributions, &mut mcp_config.configured_mcp_servers);
|
||||
for name in disabled_server_names {
|
||||
if let Some(server) = mcp_config.configured_mcp_servers.get_mut(&name) {
|
||||
server.enabled = false;
|
||||
}
|
||||
}
|
||||
mcp_config
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,34 @@ async fn contributes_hosted_plugin_runtime_without_an_executor() -> TestResult {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn runtime_overlay_preserves_disabled_server() -> TestResult {
|
||||
let codex_home = tempfile::tempdir()?;
|
||||
let config = ConfigBuilder::default()
|
||||
.codex_home(codex_home.path().to_path_buf())
|
||||
.fallback_cwd(Some(codex_home.path().to_path_buf()))
|
||||
.cli_overrides(vec![
|
||||
("features.apps".to_string(), true.into()),
|
||||
(
|
||||
"mcp_servers.codex_apps.url".to_string(),
|
||||
"https://example.com/mcp".into(),
|
||||
),
|
||||
("mcp_servers.codex_apps.enabled".to_string(), false.into()),
|
||||
])
|
||||
.build()
|
||||
.await?;
|
||||
let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing();
|
||||
let manager = installed_manager(&config);
|
||||
|
||||
let servers = manager.effective_servers(&config, Some(&auth)).await;
|
||||
let server = servers
|
||||
.get(CODEX_APPS_MCP_SERVER_NAME)
|
||||
.ok_or("hosted plugin runtime should remain configured")?;
|
||||
|
||||
assert!(!server.enabled());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn legacy_fallback_overwrites_reserved_config_without_an_extension() -> TestResult {
|
||||
let codex_home = tempfile::tempdir()?;
|
||||
|
||||
Reference in New Issue
Block a user