github/github-mcp-server · warning

unsupported platform: %s

Error message

unsupported platform: %s

What it means

openURL has no launcher for runtime.GOOS: the switch covers linux (xdg-open), darwin (open), windows (rundll32) and rejects everything else (freebsd, android, js/wasm, plan9...). In the managed flow this error is a signal, not a dead end — beginPKCE treats a non-nil openURL error by falling back to URL elicitation or the manual authorization URL. It only surfaces raw to callers invoking openURL directly.

Source

Thrown at internal/oauth/env.go:36

// openBrowser tries to open url in the user's default browser. It returns an
// error when no browser can plausibly be launched so the caller can fall back
// to elicitation. On Linux it treats a headless session (no display server) as
// unopenable, which is the common case for SSH and containers.
func openBrowser(url string) error {
	var cmd *exec.Cmd
	switch runtime.GOOS {
	case "linux":
		if os.Getenv("DISPLAY") == "" && os.Getenv("WAYLAND_DISPLAY") == "" {
			return errNoDisplay
		}
		cmd = exec.Command("xdg-open", url)
	case "darwin":
		cmd = exec.Command("open", url)
	case "windows":
		cmd = exec.Command("rundll32", "url.dll,FileProtocolHandler", url)
	default:
		return fmt.Errorf("unsupported platform: %s", runtime.GOOS)
	}

	cmd.Stdout = io.Discard
	cmd.Stderr = io.Discard
	if err := cmd.Start(); err != nil {
		return err
	}
	// The launcher (xdg-open/open/rundll32) exits as soon as it hands off to the
	// browser. Reap it asynchronously so it does not linger as a zombie for the
	// lifetime of this long-running server.
	go func() { _ = cmd.Wait() }()
	return nil
}

// isRunningInDocker reports whether the process is running inside a Docker (or
// containerd) container. Detection relies on Linux-specific paths and is always
// false elsewhere. It is used only to skip a PKCE flow that cannot work: a
// random callback port inside a container cannot be reached from the host

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Rely on the fallback: the flow prints/elicits the authorization URL — open it manually in any browser
  2. On an unsupported OS, set BROWSER or implement your own opener and use the URL-elicitation prompt path
  3. Build/run on a supported platform (linux, macOS, windows) for auto-open behavior
Defensive patterns

Strategy: fallback

Try / catch

if err := m.openURL(u); err != nil {
    // fall back to URL elicitation / manual instructions — the flow already does this internally
    prompter.PromptURL(ctx, Prompt{URL: u})
}

Prevention

When it happens

Trigger: The binary runs on an OS outside the switch (internal/oauth/env.go:25-37), e.g. built for freebsd/arm64 or GOOS=js; on linux the DISPLAY/WAYLAND_DISPLAY check can instead return errNoDisplay (a different, handled error); every non-covered GOOS returns fmt.Errorf("unsupported platform: %s", runtime.GOOS).

Common situations: Community builds for BSD; experimental wasm builds; cross-compiled binaries tested on unusual OSes; ChromeOS Crostini is linux and fine, but true chromeos builds would hit this.

Related errors


AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15). Data as JSON: /api/errors/0a686bef91dd79d3. Report an issue: GitHub.