charmbracelet/crush · error

failed to get MCP auth URL: status code %d

Error message

failed to get MCP auth URL: status code %d

What it means

MCPAuthURL expects HTTP 200 from GET /workspaces/{id}/mcp/auth-url. Any other status (401 unauthorized, 404 unknown server name or workspace, 409 no flow in progress, 5xx server fault) is reported as this error with the numeric status embedded. It means the auth-URL lookup was rejected by the server, not that the request failed to send.

Source

Thrown at internal/client/proto.go:359

	}
	var pending []proto.MCPPendingAuthServer
	if err := json.NewDecoder(rsp.Body).Decode(&pending); err != nil {
		return nil, fmt.Errorf("failed to decode MCP pending auth: %w", err)
	}
	return pending, nil
}

// MCPAuthURL retrieves the current OAuth authorization URL for a named MCP
// server, if a flow is in progress.
func (c *Client) MCPAuthURL(ctx context.Context, id, name string) (string, error) {
	q := url.Values{"name": []string{name}}
	rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/mcp/auth-url", id), q, nil)
	if err != nil {
		return "", fmt.Errorf("failed to get MCP auth URL: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("failed to get MCP auth URL: status code %d", rsp.StatusCode)
	}
	var resp proto.MCPAuthResponse
	if err := json.NewDecoder(rsp.Body).Decode(&resp); err != nil {
		return "", fmt.Errorf("failed to decode MCP auth URL: %w", err)
	}
	return resp.AuthURL, nil
}

// MCPAuthenticate runs the OAuth flow for a named MCP server. The server's
// local browser is suppressed; the caller is responsible for surfacing the
// authorization URL (via polling [Client.MCPPendingAuth] / state events)
// and opening it on the user's machine. The call blocks until the flow
// completes, fails, or ctx is cancelled.
func (c *Client) MCPAuthenticate(ctx context.Context, id, name string) error {
	rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/mcp/auth", id), nil,
		jsonBody(proto.MCPNameRequest{Name: name}),
		http.Header{"Content-Type": []string{"application/json"}})
	if err != nil {

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check the status code in the message: 404 → verify the MCP server name is registered on this workspace; 401 → refresh credentials; 5xx → server-side fault, retry later.
  2. Confirm the exact server name string matches the registered MCP server (names are case-sensitive identifiers).
  3. Start the OAuth flow (authenticate) before polling the auth URL if the server only exposes a URL mid-flow.
  4. Verify client and server versions both support the /mcp/auth-url endpoint.

Example fix

// before
name := "GitHub" // registered as "github"
url, err := client.MCPAuthURL(ctx, wsID, name) // 404

// after
servers, err := client.MCPPendingAuth(ctx, wsID)
if err != nil {
    return err
}
for _, s := range servers {
    if s.Name == "github" {
        url, err := client.MCPAuthURL(ctx, wsID, s.Name)
        ...
    }
}
Defensive patterns

Strategy: retry

Validate before calling

// Ensure the MCP server name exists before asking for its auth URL.
servers, err := client.MCPPendingAuth(ctx, wsID)
if err != nil {
    return err
}
known := false
for _, s := range servers {
    if s.Name == name {
        known = true
        break
    }
}
if !known {
    return fmt.Errorf("mcp server %q not registered on workspace %s", name, wsID)

Try / catch

url, err := client.MCPAuthURL(ctx, id, name)
if err != nil {
    if strings.Contains(err.Error(), "status code 404") {
        return "", fmt.Errorf("mcp server %q unknown on this workspace: %w", name, err)
    }
    if strings.Contains(err.Error(), "status code 409") {
        return "", fmt.Errorf("no auth flow in progress for %q; start the flow first: %w", name, err)
    }
    if strings.Contains(err.Error(), "status code 5") {
        return retryWithBackoff(ctx, func() (string, error) { return client.MCPAuthURL(ctx, id, name) })
    }
    return "", err
}

Prevention

When it happens

Trigger: Calling MCPAuthURL(ctx, id, name) when the response status is not 200 — e.g. the named MCP server does not exist on the workspace (404), auth token is invalid (401), no OAuth flow has been started for that server (409/4xx), or the server returns 500.

Common situations: Querying auth-url for an MCP server name that was never registered or was renamed; calling before MCPAuthenticate initiated a flow; expired session token; hitting a server build that doesn't yet expose this route (404) after a version upgrade.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/4161c27f87d68b48. Report an issue: GitHub.