xai-org/grok-build · error

--header can only be used with HTTP or SSE servers.

Error message

--header can only be used with HTTP or SSE servers.

What it means

This error is thrown by the `grok mcp add` command resolver when the `--header` flag is supplied but the resolved transport is a stdio server (no --transport given and the trailing command is not a URL). Headers only make sense for HTTP/SSE transports, so the CLI rejects the combination early with guidance. It is a usage/validation error, not a runtime failure.

Source

Thrown at crates/codegen/xai-grok-pager/src/mcp_cmd.rs:329

    } else {
        &args.args
    };
    // Clap's "source" group guarantees at most one of these is set.
    let source = args
        .command_or_url
        .as_deref()
        .or(args.command.as_deref())
        .or(args.url.as_deref());

    match transport {
        McpTransport::Stdio => {
            let Some(command) = source else {
                bail!(
                    "A command is required for stdio servers. Usage: grok mcp add <name> -- <command> [args...]"
                );
            };
            if !args.header.is_empty() {
                bail!("--header can only be used with HTTP or SSE servers.");
            }
            // A KEY=value command means an env pair leaked out of -e, which takes one pair per flag (the old --env was greedy)
            if looks_like_env_pair(command) {
                let pairs: Vec<String> = args
                    .env
                    .iter()
                    .map(String::as_str)
                    .chain([command])
                    .map(|pair| format!("-e {pair}"))
                    .collect();
                bail!(
                    "Invalid command '{command}': it looks like an environment variable. Pass each variable as its own flag: {}",
                    pairs.join(" ")
                );
            }
            let env = parse_env_vars(&args.env)?;

            let mut warnings = Vec::new();

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Remove the --header flags since stdio servers cannot use HTTP headers.
  2. Add --transport http or --transport sse and pass a URL instead of a command if the server is actually remote.
  3. Move any auth configuration to env vars passed with -e KEY=value for the stdio process.

Example fix

// before
grok mcp add fs --header 'Authorization: Bearer x' -- npx -y @modelcontextprotocol/server-fs /tmp
// after
grok mcp add fs -- npx -y @modelcontextprotocol/server-fs /tmp
Defensive patterns

Strategy: validation

Validate before calling

fn is_url(s: &str) -> bool { s.starts_with("http://") || s.starts_with("https://") }
if !headers.is_empty() && !(transport_is_http_or_sse || command.map_or(false, is_url)) {
    eprintln!("--header requires --transport http/sse (or a URL command)");
}

Type guard

fn is_remote_transport(t: &str) -> bool { matches!(t, "http" | "sse") }

Prevention

When it happens

Trigger: Running `grok mcp add <name> --header 'Name: value' -- <command> [args...]` where the transport resolves to stdio (source is a command, not an http/https URL and no --transport http/sse was passed).

Common situations: Developers copying an HTTP-server invocation and just swapping the command for a local stdio binary; scripts templating headers for all servers; misunderstanding that headers are ignored/unsupported for stdio MCP servers.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/6ccb4641fa1cea6e. Report an issue: GitHub.