sipeed/picoclaw · error

--header can only be used with http or sse transport

Error message

--header can only be used with http or sse transport

What it means

Headers are only meaningful for http/sse servers; buildServerConfig rejects any parsed --header/-H value once transport falls through to the stdio branch (add.go:221-223). Since --transport defaults to stdio, supplying a header without explicitly selecting a remote transport always fails. The guard prevents silently dropping auth headers a stdio child process would never use.

Source

Thrown at cmd/picoclaw/internal/mcp/add.go:222

			return config.MCPServerConfig{}, fmt.Errorf("--env can only be used with stdio transport")
		}
		if strings.TrimSpace(opts.EnvFile) != "" {
			return config.MCPServerConfig{}, fmt.Errorf("--env-file can only be used with stdio transport")
		}
		if len(args) > 0 {
			return config.MCPServerConfig{}, fmt.Errorf("%s transport does not accept command arguments", transport)
		}
		parsedURL, err := url.ParseRequestURI(target)
		if err != nil || parsedURL.Scheme == "" || parsedURL.Host == "" {
			return config.MCPServerConfig{}, fmt.Errorf("invalid MCP URL %q", target)
		}
		server.URL = target
		server.Headers = headers
		return server, nil
	}

	if len(headers) > 0 {
		return config.MCPServerConfig{}, fmt.Errorf("--header can only be used with http or sse transport")
	}

	if looksLikeRemoteURL(target) {
		return config.MCPServerConfig{}, fmt.Errorf(
			"target %q looks like a remote MCP URL, but transport is %q. Use --transport http or --transport sse",
			target,
			transport,
		)
	}

	command := target
	commandArgs := append([]string(nil), args...)

	if err := validateLocalCommandPath(target); err != nil {
		return config.MCPServerConfig{}, err
	}
	if isLocalCommandPath(command) {
		command = expandHomePath(command)

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. If the target is a URL, add --transport http (or streamable-http, which normalizes to http) or --transport sse
  2. If the target really is a stdio command, remove the -H/--header flags

Example fix

# before
picoclaw mcp add s ./server -H "X-Key: v"
# after
picoclaw mcp add s https://example.com/mcp --transport http -H "X-Key: v"
Defensive patterns

Strategy: validation

Validate before calling

# validate flag/transport compatibility before invoking
if [ ${#HEADERS[@]} -gt 0 ] && [ "$TRANSPORT" = "stdio" ]; then
  echo "--header requires --transport http or sse" >&2; exit 2
fi
picoclaw mcp add "$name" "$target" --transport "$TRANSPORT" "${HEADERS[@]}"

Prevention

When it happens

Trigger: `picoclaw mcp add s mycmd -H "Authorization: Bearer x"` with no --transport flag (defaults to stdio).

Common situations: Adding an API-key header out of habit while configuring a local stdio server; not noticing that --transport defaults to stdio; migrating a remote server entry but forgetting the -t flag.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/3be2b451a745f542. Report an issue: GitHub.