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
- 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.
- Confirm the exact server name string matches the registered MCP server (names are case-sensitive identifiers).
- Start the OAuth flow (authenticate) before polling the auth URL if the server only exposes a URL mid-flow.
- 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
- Copy MCP server names from the registration/manifest rather than typing them by hand.
- Only poll auth-url while an OAuth flow is active for that server.
- Pin compatible client/server versions; new endpoints 404 on older servers.
- Differentiate retry policy by status class: retry 5xx, never retry 4xx.
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
- failed to get MCP pending auth: status code %d
- failed to create OAuth handler for mcp %q: %w
- oauth token source: %w
- failed to refresh MCP tools: status code %d
- failed to read MCP resource: status code %d
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/4161c27f87d68b48.
Report an issue: GitHub.