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
- Remove the --header flags since stdio servers cannot use HTTP headers.
- Add --transport http or --transport sse and pass a URL instead of a command if the server is actually remote.
- 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
- Only pass --header with --transport http or sse.
- Match header flags to URL-based server entries.
- Keep stdio server invocations to command + -e env flags.
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
- Unexpected arguments after the URL: '{args}'. HTTP and SSE s
- Invalid command '{command}': it looks like an environment va
- A URL is required for {label} servers. Usage: grok mcp add -
- Invalid URL '{url}'. Server URLs must start with http:// or
- Invalid name '{name}'. Names can only contain letters, numbe
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/6ccb4641fa1cea6e.
Report an issue: GitHub.