Title: fix(mcp): bound and tear down one-shot OAuth fetches so auth can't hang by waleedlatif1 · Pull Request #5789 · simstudioai/sim · GitHub
Open Graph Title: fix(mcp): bound and tear down one-shot OAuth fetches so auth can't hang by waleedlatif1 · Pull Request #5789 · simstudioai/sim
X Title: fix(mcp): bound and tear down one-shot OAuth fetches so auth can't hang by waleedlatif1 · Pull Request #5789 · simstudioai/sim
Description: Summary Root-caused the Gauge MCP OAuth "Connecting… forever" hang on staging: the SSRF-guarded fetch used for all one-shot OAuth legs (discovery, dynamic client registration, token exchange/refresh, RFC 7009 revocation) created a fresh pinned undici Agent per request and never destroyed it, and returned the live response so the MCP SDK read the body outside any deadline. The SDK sets no timeout on OAuth legs, so a stalled body read or an accumulating leaked keep-alive socket could leave the callback (and the browser waiting on it) pending indefinitely. Empirically confirmed via a staging diagnostic + DB: the callback burned its state, completed discovery, then hung before the token POST — no token exchange, no error, tokens never persisted. An isolated repro proved the SDK/flow itself reaches the token POST in <1s; the guard's lifecycle was the fault. What changed Buffer the (always-small) OAuth JSON body inside the guard, under the composed deadline/caller AbortSignal, then return a detached in-memory Response. undici's bodyTimeout only measures idle gaps between chunks and cannot bound a slow-drip/stalled body — the AbortSignal is the only true wall-clock deadline over the body read, so the read now lives inside it. destroy() (not close()) the per-request pinned Agent on every path so a one-shot leg can't strand its keep-alive socket, and teardown itself can't hang on an in-flight request. Fixed the same per-request Agent leak in the auth-type probe (tears the Agent down after best-effort session cleanup settles). Returning a normalized global Response also makes provider token-endpoint errors surface cleanly instead of the SDK's opaque "[object Response]" parse failure. Aligned with the official MCP TypeScript SDK's contract (all lifecycle/deadline enforcement lives in the injected fetch) and undici best practice (per-request pinned Agent → buffer body → destroy(); AbortSignal as the authoritative deadline). Type of Change Bug fix Testing Unit: 14 guard tests (pinning, teardown on success/failure, detached-body readability, deadline over a stalled body read, DNS/abort composition) + updated probe/revoke suites — full lib/mcp suite green (366 tests). Integration against live Gauge: drove the real SDK auth() with the new guard behavior — reaches the token POST, returns in ~1.9s, 0 leaked Agents (8 created / 8 destroyed), and surfaces a clean invalid_grant message. tsc clean; biome clean. Not yet re-run through the full staging OAuth flow end-to-end (the temporary McpHttpDiag logging from #5782 is still live and will confirm the token POST now fires; a follow-up removes it once verified). Checklist Code follows project style guidelines Self-reviewed my changes Tests added/updated and passing No new warnings introduced I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)
Open Graph Description: Summary Root-caused the Gauge MCP OAuth "Connecting… forever" hang on staging: the SSRF-guarded fetch used for all one-shot OAuth legs (discovery, dynamic client registration, token exch...
X Description: Summary Root-caused the Gauge MCP OAuth "Connecting… forever" hang on staging: the SSRF-guarded fetch used for all one-shot OAuth legs (discovery, dynamic client registration, to...
Opengraph URL: https://github.com/simstudioai/sim/pull/5789
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:250a5061-59e4-50f4-7a63-f8bcdbd9eeea |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | 8CA0:11247E:12BB488:1AE1931:6A63423F |
| html-safe-nonce | 635d495ae20fba26d36ce63544a3d166cf7766e945f365a16f34468107d6886b |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4Q0EwOjExMjQ3RToxMkJCNDg4OjFBRTE5MzE6NkE2MzQyM0YiLCJ2aXNpdG9yX2lkIjoiMzQ1MjY1Nzk4MjY0MzU4NTU5OSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | f9ad8e8376b749dbad754e7d32b5f81f41f38b5b5f9ff3766e906ca8229bbbed |
| hovercard-subject-tag | pull_request:4095713021 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/simstudioai/sim/pull/5789/files |
| twitter:image | https://avatars.githubusercontent.com/u/40672544?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/40672544?s=400&v=4 |
| og:image:alt | Summary Root-caused the Gauge MCP OAuth "Connecting… forever" hang on staging: the SSRF-guarded fetch used for all one-shot OAuth legs (discovery, dynamic client registration, token exch... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 59e55daad7174ca59d63c6974d58276ccb5477442e550bebb3c035e1bef11c94 |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/simstudioai/sim git https://github.com/simstudioai/sim.git |
| octolytics-dimension-user_id | 199344406 |
| octolytics-dimension-user_login | simstudioai |
| octolytics-dimension-repository_id | 912559512 |
| octolytics-dimension-repository_nwo | simstudioai/sim |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 912559512 |
| octolytics-dimension-repository_network_root_nwo | simstudioai/sim |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 990295d92a4cc7b63fbbd83a046217cd7d77d49c |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width