openai/codex · error · anyhow::Error
exactly one of --command or --url must be provided
Error message
exactly one of --command or --url must be provided
What it means
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.
Source
Thrown at codex-rs/cli/src/mcp_cmd.rs:405
oauth_client_registration,
oauth_resource,
}),
..
} => (
McpServerTransportConfig::StreamableHttp {
url,
bearer_token_env_var,
http_headers: None,
env_http_headers: None,
http_headers_helper: None,
},
oauth_client_id,
oauth_client_registration
.map(McpOAuthClientRegistration::from)
.unwrap_or_default(),
oauth_resource,
),
AddMcpTransportArgs { .. } => bail!("exactly one of --command or --url must be provided"),
};
let new_entry = McpServerConfig {
auth: Default::default(),
transport: transport.clone(),
environment_id: codex_config::DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string(),
enabled: true,
required: false,
supports_parallel_tool_calls: false,
omit_tools_from: None,
disabled_reason: None,
startup_timeout_sec: None,
tool_timeout_sec: None,
default_tools_approval_mode: None,
enabled_tools: None,
disabled_tools: None,
scopes: None,
oauth: oauth_client_idView on GitHub (pinned to 339751715c)
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.
Example fix
# before codex mcp add my-server # no transport flags at all # after (stdio) codex mcp add my-server --command npx -y some-mcp-server # after (streamable http) codex mcp add my-server --url https://mcp.example.com/mcp
Defensive patterns
Strategy: validation
Validate before calling
add_server() {
local name="$1"; shift
local has_command=0 has_url=0
for a in "$@"; do
case "$a" in
--command) has_command=1 ;;
--url) has_url=1 ;;
esac
done
if [ "$((has_command + has_url))" -ne 1 ]; then
echo 'error: pass exactly one of --command or --url' >&2; return 2
fi
codex mcp add "$name" "$@"
} Try / catch
if ! codex mcp add my-server "$@" 2>err.log; then
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; }
exit 1
fi Prevention
- 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
When it happens
Trigger: `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.
Common situations: 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.
Related errors
- command is required
- No MCP server named '{name}' found.
- `--remote-auth-token-env` is only supported for interactive
- `--strict-config` is not supported for `codex {subcommand}`
- environment variable `{env_var_name}` is not set
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/95c8618dfc6f0a8e.
Report an issue: GitHub.