sipeed/picoclaw · error

invalid MCP URL %q

Error message

invalid MCP URL %q

What it means

Thrown by `picoclaw mcp add` when transport is http or sse and the target does not parse as an absolute URL. buildServerConfig runs url.ParseRequestURI(target) and additionally requires a non-empty Scheme and Host (add.go:212-215); anything missing either part is rejected with the raw target quoted. It is pure input validation before any config is written.

Source

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

		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")
	}

	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,
		)
	}

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Rewrite the target as a full absolute URL including scheme and host, e.g. https://example.com/mcp
  2. Quote the whole URL so the shell cannot mangle it: picoclaw mcp add mysvc --transport http "https://example.com/mcp"
  3. If the target is actually a local command, drop --transport http/sse and use stdio syntax

Example fix

# before
picoclaw mcp add cache --transport http localhost:6379/mcp
# after
picoclaw mcp add cache --transport http https://localhost:6379/mcp
Defensive patterns

Strategy: validation

Validate before calling

func validMCPURL(target string) bool {
	u, err := url.ParseRequestURI(target)
	return err == nil && u.Scheme != "" && u.Host != ""
}

// before shelling out:
if !validMCPURL(target) {
	return fmt.Errorf("target %q must be an absolute URL like https://host/mcp", target)
}

Prevention

When it happens

Trigger: `picoclaw mcp add mysvc --transport http localhost:8080/mcp` (no scheme), `--transport sse example.com/sse` (no scheme), a bare path like `/mcp` (no host), or a typo that makes ParseRequestURI fail.

Common situations: Copy-pasting an endpoint from vendor docs that list it as host:port without https://; shell quoting eating part of the URL; assuming the CLI infers the scheme like some other MCP clients do.

Related errors


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