perf(mcp): per-server tool cache + surface OAuth start errors#4691
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview OAuth start error handling now surfaces safe, user-facing authorization-server messages via a new Adds focused unit tests for per-server caching behavior (hits, partial failures, OAuth-pending soft skip, Reviewed by Cursor Bugbot for commit e7eb5f2. Configure here. |
Greptile SummaryThis PR refactors the MCP tool-discovery cache from a single per-workspace entry to a per-
Confidence Score: 5/5Safe to merge — the caching refactor is well-isolated, non-OAuth errors still receive the generic client message, and 7 new tests cover the key paths. The per-server cache change is a targeted replacement of one Map key strategy with another; all branches (cache hit, fetch, OAuth-pending, error) are covered by new tests and the discriminated union makes the control flow easy to follow. The OAuth error-surfacing change is correctly guarded so only OAuthError instances reach surfaceOauthError, while DB and network errors stay behind the generic fallback. No existing behavior is regressed. No files require special attention; the previous review thread and outside-diff comment capture the only two residual observations. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[discoverTools called] --> B[getWorkspaceServers]
B --> C{servers empty?}
C -- yes --> D[return empty array]
C -- no --> E[Promise.all over servers]
E --> F{forceRefresh?}
F -- no --> G{cache hit for\nworkspace:id:server:id?}
G -- hit --> H[DiscoveryOutcome: cached]
G -- miss --> I[resolveConfigEnvVars + createClient + listTools]
F -- yes --> I
I -- success --> J[DiscoveryOutcome: fetched]
I -- OAuthError / UnauthorizedError --> K[DiscoveryOutcome: oauth-pending]
I -- other error --> L[DiscoveryOutcome: error]
H --> M[aggregate allTools]
J --> N[write per-server cache key\nawait Promise.allSettled cacheWrites]
J --> M
K --> O[fire DB update: status=disconnected]
L --> P[fire DB update: status=failed\nincrement failedCount]
N --> M
O --> Q[deferredSideEffects fire-and-forget]
P --> Q
M --> R[await cacheWrites]
R --> S[fire deferredSideEffects]
S --> T[mcpConnectionManager.connect for fetched servers]
T --> U[return allTools]
Reviews (4): Last reviewed commit: "chore(mcp): tighten clearCache comment t..." | Re-trigger Greptile |
|
@greptile |
|
@cursor review |
|
@greptile |
|
@cursor review |
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e7eb5f2. Configure here.
Summary
(workspaceId, serverId)instead of one entry per workspace, so a slow or broken server can't invalidate every other server's cached tools (previously one timeout on Exa stalled the whole MCP Tools page on "Loading…")Raw body:envelope, falls back gracefully when format doesn't match)forceRefresh, OAuth-pending soft skip, empty workspace,clearCache, and cross-workspace isolationType of Change
Testing
Tested manually on staging against Exa (timing out), PlanetScale (healthy), and semrush (OAuth-pending) — confirmed healthy servers render instantly from cache while broken ones retry. All 265 MCP unit tests pass.
Checklist