sipeed/picoclaw · error

--env can only be used with stdio transport

Error message

--env can only be used with stdio transport

What it means

For http/sse transports, buildServerConfig rejects any --env/-e assignments: a remote MCP server cannot receive your local environment variables, so mixing them is an error, not a warning. The env list has already been parsed by parseEnvAssignments, so any -e KEY=value present triggers this.

Source

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

	env, err := parseEnvAssignments(opts.Env)
	if err != nil {
		return config.MCPServerConfig{}, err
	}
	headers, err := parseHeaderAssignments(opts.Headers)
	if err != nil {
		return config.MCPServerConfig{}, err
	}

	server := config.MCPServerConfig{
		Enabled:  true,
		Type:     transport,
		Deferred: opts.Deferred,
	}

	switch transport {
	case "http", "sse":
		if len(env) > 0 {
			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")

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Remove the --env/-e flags for http/sse servers
  2. Send credentials as headers instead: `-H 'Authorization: Bearer <token>'`
  3. If the server truly needs env vars, run it locally with stdio transport

Example fix

# before
picoclaw mcp add api https://example.com/mcp -t http -e API_KEY=secret
# after
picoclaw mcp add api https://example.com/mcp -t http -H 'Authorization: Bearer secret'
Defensive patterns

Strategy: validation

Validate before calling

if [ "$TRANSPORT" = http ] || [ "$TRANSPORT" = sse ]; then [ ${#ENVS[@]:-0} -eq 0 ] || { echo "--env is stdio-only"; exit 2; }; fi

Prevention

When it happens

Trigger: `picoclaw mcp add name https://host/mcp --transport http -e KEY=value` (or -e KEY=value with -t sse).

Common situations: Copy-pasting a working stdio add command and switching only the transport; habit of passing API keys via -e.

Related errors


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