Hmbown/CodeWhale · error

Provide either a command or URL for MCP server

Error message

Provide either a command or URL for MCP server '{name}'.

What it means

MCP server entries must specify how to connect: either a `command` (stdio transport) or a `url` (HTTP/SSE transport). When adding a server via the config mutation API with both fields absent, the library rejects the entry with this error since the resulting server definition would be unstartable.

Solutions

  1. Add `--command <executable>` for a stdio server, or `--url <http(s)://...>` for a remote server
  2. If the server should be remote, set `url`; if local, set `command` (optionally with `args` and `transport`)
  3. Fix the programmatic caller so it populates exactly one of command/url before inserting

Example fix

// before
codewhale mcp add docs --args serve --transport stdio
// after
codewhale mcp add docs --command mkdocs --args serve --transport stdio
Defensive patterns

Strategy: validation

Validate before calling

if command.is_none() && url.is_none() {
    return Err(anyhow::anyhow!("MCP server '{name}' needs --command or --url"));
}

Type guard

fn has_endpoint(cmd: &Option<String>, url: &Option<String>) -> bool {
    cmd.as_ref().map_or(false, |c| !c.trim().is_empty())
        || url.as_ref().map_or(false, |u| !u.trim().is_empty())
}

Prevention

When it happens

Trigger: Calling the add-server config function (crates/tui/src/mcp.rs:5937) with `command: None` and `url: None` — e.g. a CLI invocation like `codewhale mcp add myserver --arg x` that supplies args or transport but no command/url.

Common situations: Typing `mcp add name --args ...` forgetting `--command` or `--url`; generating server entries programmatically from templates where both optional fields were left empty; copying a config snippet and deleting the command line.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/9ef4ef2281118a1e. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/mcp.rs:5937

        write_atomic(path, template.as_bytes())?;
        Ok(if original.is_some() {
            McpWriteStatus::Overwritten
        } else {
            McpWriteStatus::Created
        })
    })
}

pub fn add_server_config(
    path: &Path,
    name: String,
    command: Option<String>,
    url: Option<String>,
    args: Vec<String>,
    transport: Option<String>,
) -> Result<()> {
    if command.is_none() && url.is_none() {
        anyhow::bail!("Provide either a command or URL for MCP server '{name}'.");
    }
    validate_mcp_transport(transport.as_deref())?;
    mutate_config(path, None, |cfg| {
        cfg.servers.insert(
            name,
            McpServerConfig {
                command,
                args,
                env: HashMap::new(),
                cwd: None,
                url,
                transport,
                connect_timeout: None,
                execute_timeout: None,
                read_timeout: None,
                disabled: false,
                enabled: true,
                required: false,

View on GitHub (pinned to 73e0f67d83)