external-agent-migration: avoid mixed MCP transport configs (#26435)

## Why

MCP migration could recursively merge an imported server into an
existing same-named Codex server. When one definition used stdio and the
other used HTTP, this produced an invalid mixed configuration containing
both `command` and `url`.

## What changed

- Merge MCP configuration at the server level instead of field by field.
- Preserve an existing same-named Codex MCP server unchanged.
- Report only MCP servers that would actually be added during detection.
- Add regression coverage for mixed command/HTTP source configurations.
- Use neutral fixture names and reserved `example.com` URLs.

## Test plan

- `just test -p codex-app-server repo_mcp`
  - 5 tests passed.
- `just test -p codex-external-agent-migration
mcp_migration_prefers_command_transport_for_mixed_server_config`
  - 1 test passed.
This commit is contained in:
stefanstokic-oai
2026-06-04 14:16:03 -04:00
committed by GitHub
parent 881cf191d7
commit c8fdc74b42
3 changed files with 203 additions and 6 deletions
@@ -1451,6 +1451,49 @@ mod tests {
);
}
#[test]
fn mcp_migration_prefers_command_transport_for_mixed_server_config() {
let root = tempfile::TempDir::new().expect("tempdir");
fs::write(
root.path().join(".mcp.json"),
r#"{
"mcpServers": {
"mixedTransport": {
"command": "mcp-remote-proxy",
"args": [
"https://example.com/mixed-transport",
"--transport",
"http"
],
"url": "https://example.com/mixed-transport"
}
}
}"#,
)
.expect("write mcp");
assert_eq!(
build_mcp_config_from_external(
root.path(),
/*external_agent_home*/ None,
/*settings*/ None,
)
.unwrap(),
toml::from_str(
r#"
[mcp_servers.mixedTransport]
command = "mcp-remote-proxy"
args = [
"https://example.com/mixed-transport",
"--transport",
"http",
]
"#
)
.unwrap()
);
}
#[test]
fn mcp_migration_skips_unsupported_transports() {
let root = tempfile::TempDir::new().expect("tempdir");