Skip to content

fix(mcp): recover cleanly from OAuth failures#5595

Open
j15z wants to merge 2 commits into
stagingfrom
fix/mcp-page
Open

fix(mcp): recover cleanly from OAuth failures#5595
j15z wants to merge 2 commits into
stagingfrom
fix/mcp-page

Conversation

@j15z

@j15z j15z commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

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

  • 25 focused MCP/API test files passed (375 tests).
  • React Query pattern audit passed with zero violations.
  • Biome and git diff --check passed for the changed files.
  • Full TypeScript checking could not be used in the isolated staging worktree because workspace package links resolved through another branch’s node_modules, producing unrelated package-version errors. The changed TypeScript paths compiled through the focused Vitest runs.

Post-Deploy Monitoring & Validation

  • Search application logs for McpClient, McpService, authorization_required, timeout, and OAuth authorization pending during the first 24 hours.
  • Healthy signal: abandoned OAuth servers remain disconnected without repeated /api/mcp/tools/discover failures; successful reconnects return to connected and clear the failure counter.
  • Failure signal: renewed 60-second discovery requests, repeated cooldown errors for OAuth-pending servers, or header values appearing in MCP diagnostics.
  • Roll back this PR if MCP list availability regresses or refresh failures stop exposing a safe actionable error. Owner: MCP/settings team during the first business day after deployment.

Compound Engineering
Codex

@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 11, 2026 11:22pm

Request Review

@cursor

cursor Bot commented Jul 11, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches MCP discovery, DB status persistence, and refresh API behavior across service, hooks, and UI; changes are well-tested but affect connection/OAuth flows users rely on.

Overview
Improves MCP OAuth and connection failure handling so abandoned OAuth flows stop triggering doomed auto-discovery and the UI reflects persisted server state instead of generic errors.

Backend: mcpService now owns connection status writes (connected, OAuth-pending disconnected with no lastError, failures with consecutive-failure promotion to error). Failed updates can be skipped when a newer successful discovery wins (discoveryStartedAt / lastConnected guard). OAuth auth errors are not negative-cached. The per-server refresh API only bumps lastToolsRefresh and returns status fields from the DB—it no longer overwrites connectionStatus on discovery failure (preserving OAuth-pending).

Client: useMcpToolsQuery / force refresh skip OAuth servers unless connected; discovery failures invalidate the server list. Settings UI uses getServerToolsLabel and getRefreshActionState (retryable red Failed on refresh errors). McpClient passes configured initialize timeout and logs sanitized connection diagnostics (header names only, no secret values).

Reviewed by Cursor Bugbot for commit 97b3e73. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR improves MCP OAuth recovery and refresh feedback. The main changes are:

  • Skips automatic tool discovery for OAuth servers waiting on reconnect.
  • Persists MCP discovery failures and refresh results for the settings UI.
  • Adds clearer refresh button states and server error labels.
  • Adds connection diagnostics with timing, phase, outcome, auth type, and header names.

Confidence Score: 4/5

The changed MCP failure paths need fixes before merging.

  • Non-OAuth 401 responses can be persisted as OAuth-pending with no actionable error.
  • New diagnostic logging can expose secret prefixes from truncated external error text.
  • The UI-only refresh state changes look contained.

apps/sim/lib/mcp/service.ts and apps/sim/lib/mcp/client.ts

Security Review

The new MCP diagnostics can log truncated external error text before redaction has safely removed secret fragments.

Important Files Changed

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

Comment on lines +69 to +71
function isOauthAuthorizationError(error: unknown): boolean {
return error instanceof McpOauthAuthorizationRequiredError || error instanceof UnauthorizedError
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Non-OAuth 401s Lose Errors

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.

Comment thread apps/sim/lib/mcp/client.ts Outdated
Comment on lines +174 to +180
...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,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Truncated Secrets Can Leak

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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread apps/sim/hooks/queries/mcp.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant