Skip to content

Feat/mid session auth#1607

Closed
BobDickinson wants to merge 4 commits into
modelcontextprotocol:v2/mainfrom
BobDickinson:feat/mid-session-auth
Closed

Feat/mid session auth#1607
BobDickinson wants to merge 4 commits into
modelcontextprotocol:v2/mainfrom
BobDickinson:feat/mid-session-auth

Conversation

@BobDickinson

Copy link
Copy Markdown
Contributor

Mid-session authorization (web, TUI, CLI)

Closes #1526

Summary

Implements mid-session authorization for Inspector v2 as specified in specification/v2_auth_mid_session.md: detecting MCP 401/403 auth challenges after connect, normalizing them to AuthChallenge, running shared OAuthManager.handleAuthChallenge() recovery, and restoring the session without forcing a full disconnect/reconnect cycle.

Covers standard OAuth (token refresh, re-login, SEP-2350 step-up with scope union) and enterprise-managed auth (EMA) (silent legs 2–3 re-mint, IdP leg 1 when needed). All three surfaces share core/auth/challenge.ts and core recovery logic; UX and wire delivery differ by client as the spec describes.

Builds on connect-time OAuth/EMA already in v2 and aligns with v2_auth_hardening.md (scope union, issuer handling hooks) without waiting on the v2 SDK transport retry PR.

What this delivers

Shared core

  • AuthChallenge parsing from WWW-Authenticate (401/403, insufficient_scope, etc.).
  • handleAuthChallenge() outcomes: satisfied, step_up_confirm (EMA/web deferral), interactive, failed.
  • checkAuthChallengeSatisfied() — storage-only short-circuit before starting visible OAuth.
  • SEP-2350 scope union on step-up; scope replace on 401 re-login; union persisted only after successful completeOAuthFlow().
  • oauthUx.ts — shared copy for step-up modals, EMA vs standard OAuth, toasts, re-auth banner text.
  • runRunnerInteractiveOAuth() — shared TUI/CLI loopback callback flow (127.0.0.1:6276).
  • formatOAuthFailureDetail() — human-readable OAuth failure messages (no raw Zod JSON in UI).

Web (remote transport)

Note: The main challenge with the web app is that re-auth is generally detected on the backend (the Node side of the API), but authentication often needs to happen on the web app side of the API. So we needed a mechanism to notify the web app to trigger a re-auth (with details) and a way for the web app to then communicate results and populate the remote tranport with the new authenication state (esp tokens). Also, because re-auth can navigate away from Inspector and redirect back to inspector when complete, we needed a mechanism to record and restore app state (similar to how we record HTTP messages across an auth gap), such that after auth we show the same server connected, are on the same table, and ideally with the same state (entered tool call params, for example).

  • Dual delivery: command-scoped auth challenges on POST /api/mcp/send (HTTP 200 + retry once after recovery) vs ambient challenges on SSE.
  • POST /api/mcp/auth-state — hot-swap tokens on the node session without tearing down transport.
  • Auth-challenge intercept fetch on the remote MCP HTTP transport (challenge before stub provider auth()).
  • StepUpAuthModal — user confirmation before standard-OAuth redirect or EMA re-mint/IdP (Inspector-as-testing-tool visibility).
  • OAuth resume snapshot (sessionStorage) — restore server, app tab, and panel UI after full-page redirect; explicit disconnect clears snapshot and resets to Servers.
  • pendingReauth — defer interactive OAuth when browser tab is hidden; resume on visibility.
  • ReAuthBanner — persistent re-auth when OAuth aborts or callback fails.
  • Command-scoped recovery for tools, prompts, resources, and apps; ambient recovery for idle SSE.

TUI & CLI (direct transport)

  • InspectorClient.withDirectAuthRecovery() and directAuthRecovery transport intercept until v2 SDK owns silent retry.
  • TUI: Auth tab orchestration — auto OAuth on 401, step-up confirm on Auth tab (A/C, ↑/↓ + Enter), EMA confirm-then-handleAuthChallenge, loopback callback, clear OAuth (S).
  • CLI: cliOAuth.ts — connect-time and mid-session interactive OAuth; y/N step-up prompt; one-shot RPC retry after recovery.

Test infrastructure

Spec & docs

Testing

Automated (npm run validate) — all passed:

Package Tests
web 2434
cli 121
tui 247
launcher 5
Total 2807

Includes unit tests for challenge parsing, scope union, oauthUx copy, OAuthManager.handleAuthChallenge, web App OAuth resume lifecycle, TUI EMA step-up and Auth-tab flows, CLI interactive step-up prompts, remote auth-state propagation, and composable test-server scope enforcement.

Manual validation follows v2_auth_smoke_testing.md: standard step-up on oauth-step-up-demo, EMA step-up on test-server-ema, OAuth callback abort, and hosted servers (GitHub, Stytch, etc.).

Reviewer notes

  • EMA step-up confirm on web/TUI is deliberate (testing visibility), not a production-client default; silent re-mint runs only after user confirms.

@BobDickinson BobDickinson self-assigned this Jul 2, 2026
@BobDickinson BobDickinson added auth Issues and PRs related to authorization v2 Issues and PRs for v2 labels Jul 2, 2026
@BobDickinson

Copy link
Copy Markdown
Contributor Author

Superseded by same-repo PR #1608 (branch now on modelcontextprotocol/inspector for CI + checks).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth Issues and PRs related to authorization v2 Issues and PRs for v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants