fix(mcp): recover cleanly from OAuth failures#5595
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Backend: Client: Reviewed by Cursor Bugbot for commit 97b3e73. Bugbot is set up for automated code reviews on this repo. Configure here. |
Greptile SummaryThis PR improves MCP OAuth recovery and refresh feedback. The main changes are:
Confidence Score: 4/5The changed MCP failure paths need fixes before merging.
apps/sim/lib/mcp/service.ts and apps/sim/lib/mcp/client.ts
|
| Filename | Overview |
|---|---|
| apps/sim/lib/mcp/service.ts | Adds MCP status persistence and OAuth-pending handling, but the shared auth-error helper can hide non-OAuth 401 credential failures. |
| apps/sim/lib/mcp/client.ts | Adds connect timeout handling and structured diagnostics, but the new error logging can expose truncated secret fragments. |
| apps/sim/hooks/queries/mcp.ts | Stops auto-discovery for disconnected OAuth servers while keeping non-OAuth discovery behavior. |
| apps/sim/app/workspace/[workspaceId]/settings/components/mcp/mcp.tsx | Uses helper functions for MCP refresh action state and server tool labels. |
| apps/sim/app/workspace/[workspaceId]/settings/components/settings-header/settings-header.tsx | Adds optional error-tone rendering for settings header actions. |
Reviews (1): Last reviewed commit: "fix(mcp): improve OAuth failure recovery" | Re-trigger Greptile
| function isOauthAuthorizationError(error: unknown): boolean { | ||
| return error instanceof McpOauthAuthorizationRequiredError || error instanceof UnauthorizedError | ||
| } |
There was a problem hiding this comment.
When a headers-auth MCP server returns 401, the SDK can surface UnauthorizedError, but this helper now routes that through the OAuth-pending path. That path clears lastError, skips the failure counter, and avoids the failure cache, so disconnected non-OAuth servers can be retried repeatedly while the UI has no persisted credential error to show.
| ...describedError, | ||
| message: sanitizeForLogging(describedError.message, 500), | ||
| causeChain: describedError.causeChain?.map((cause) => sanitizeForLogging(cause, 500)), | ||
| stack: | ||
| error instanceof Error && error.stack | ||
| ? sanitizeForLogging(error.stack.split('\n').slice(1).join('\n'), 2000) | ||
| : undefined, |
There was a problem hiding this comment.
These new diagnostics log external MCP error messages, cause chains, and stacks after sanitizeForLogging, but that helper truncates before redacting. If a server error echoes a long or unterminated secret-bearing fragment, the redaction patterns may not match the truncated text and a secret prefix can be written to structured logs.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ef5f993. Configure here.

Summary
Abandoning an MCP OAuth flow no longer leaves the MCP settings page repeatedly attempting a doomed tool discovery or reporting a misleading generic failure. Disconnected OAuth servers wait for an explicit reconnect, connection attempts honor their configured timeout, and real failures persist so the list and detail views can show the actual reason.
Refresh feedback now distinguishes success from failure: failed refreshes show a retryable red-text Failed state, while the server list displays the persisted error instead of always saying “Unable to connect.” Connection diagnostics record timing, phase, outcome, auth type, header names, and sanitized error context without logging header values.
The persisted status policy keeps OAuth authorization-required servers disconnected without negative-caching them. Other failures become disconnected initially, promote to error after repeated failures, and reset on successful discovery.
Validation
git diff --checkpassed for the changed files.node_modules, producing unrelated package-version errors. The changed TypeScript paths compiled through the focused Vitest runs.Post-Deploy Monitoring & Validation
McpClient,McpService,authorization_required,timeout, andOAuth authorization pendingduring the first 24 hours./api/mcp/tools/discoverfailures; successful reconnects return toconnectedand clear the failure counter.