{"record":{"id":"95c8618dfc6f0a8e","repo":"openai/codex","slug":"exactly-one-of-command-or-url-must-be-provided","errorCode":null,"errorMessage":"exactly one of --command or --url must be provided","messagePattern":"exactly one of --command or --url must be provided","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"codex-rs/cli/src/mcp_cmd.rs","lineNumber":405,"sourceCode":"                    oauth_client_registration,\n                    oauth_resource,\n                }),\n            ..\n        } => (\n            McpServerTransportConfig::StreamableHttp {\n                url,\n                bearer_token_env_var,\n                http_headers: None,\n                env_http_headers: None,\n                http_headers_helper: None,\n            },\n            oauth_client_id,\n            oauth_client_registration\n                .map(McpOAuthClientRegistration::from)\n                .unwrap_or_default(),\n            oauth_resource,\n        ),\n        AddMcpTransportArgs { .. } => bail!(\"exactly one of --command or --url must be provided\"),\n    };\n\n    let new_entry = McpServerConfig {\n        auth: Default::default(),\n        transport: transport.clone(),\n        environment_id: codex_config::DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string(),\n        enabled: true,\n        required: false,\n        supports_parallel_tool_calls: false,\n        omit_tools_from: None,\n        disabled_reason: None,\n        startup_timeout_sec: None,\n        tool_timeout_sec: None,\n        default_tools_approval_mode: None,\n        enabled_tools: None,\n        disabled_tools: None,\n        scopes: None,\n        oauth: oauth_client_id","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/cli/src/mcp_cmd.rs#L387-L423","documentation":"run_add selects the transport by matching the parsed arguments: a stdio arm (Some(stdio)), a streamable-HTTP arm (Some(streamable_http)), and a catch-all arm that bails `exactly one of --command or --url must be provided`. The catch-all is reached when neither transport flag made it into the parsed arguments, so no McpServerConfig transport can be constructed.","triggerScenarios":"`codex mcp add my-server` with neither --command nor --url; flag-name typos (--cmd, --uri) so clap binds neither real flag and both transport fields stay None.","commonSituations":"Assuming `codex mcp add` prompts interactively for the transport; scripts where both flag branches are conditional and neither condition held; renamed flags across codex versions.","solutions":["Pass exactly one transport: `--command <program> [args...]` for stdio, or `--url https://host/mcp` for streamable HTTP.","Check `codex mcp add --help` for the exact flag names in your codex version.","If you prefer hand-editing, write the [mcp_servers.<name>] table in config.toml directly instead of using mcp add."],"exampleFix":"# before\ncodex mcp add my-server               # no transport flags at all\n# after (stdio)\ncodex mcp add my-server --command npx -y some-mcp-server\n# after (streamable http)\ncodex mcp add my-server --url https://mcp.example.com/mcp","handlingStrategy":"validation","validationCode":"add_server() {\n  local name=\"$1\"; shift\n  local has_command=0 has_url=0\n  for a in \"$@\"; do\n    case \"$a\" in\n      --command) has_command=1 ;;\n      --url) has_url=1 ;;\n    esac\n  done\n  if [ \"$((has_command + has_url))\" -ne 1 ]; then\n    echo 'error: pass exactly one of --command or --url' >&2; return 2\n  fi\n  codex mcp add \"$name\" \"$@\"\n}","typeGuard":null,"tryCatchPattern":"if ! codex mcp add my-server \"$@\" 2>err.log; then\n  grep -q 'exactly one of --command or --url must be provided' err.log && { echo 'usage: codex mcp add <name> (--command <prog> [args...] | --url <https://...>)' >&2; exit 2; }\n  exit 1\nfi","preventionTips":["Centralize server registration in one wrapper that enforces the exactly-one rule","Fail scripts early when neither transport variable is set","Re-check flag names with `codex mcp add --help` after codex upgrades"],"tags":["cli","codex","mcp","argument-validation"],"backgroundTag":"mutually-exclusive-arguments","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}