⚠️ Blocked by SDK change — waiting on modelcontextprotocol/typescript-sdk#2561. No in-repo work is possible until that lands; the Inspector already ships a working client-side compensation (PR #1806).
Follow-up from #1805 / PR #1806.
Problem
Era auto/modern sends the SDK's server/discover negotiation probe before initialize, so authorization first surfaces at the probe. On the direct transport path (CLI/TUI, and any path with no stored tokens and therefore no authProvider), a 401 reaches the SDK as a raw SdkHttpError. The SDK's classifyHttpError only looks for a JSON-RPC error body — it ignores the HTTP status — so it verdicts "not a modern server". In pin mode (protocolEra: "modern") the classifier's verdict is then rethrown with the 401 discarded entirely: no status, not even a cause.
The Inspector worked around this in #1806 by enabling interceptAuthChallenges for the probing eras even with no stored tokens, so the 401 becomes a typed AuthChallengeError that survives the probe as data.cause. That is a client-side compensation for an SDK classification gap.
Asks (upstream @modelcontextprotocol/client)
classifyHttpError should treat HTTP 401/403 on the probe as auth-required, not as absence of modern evidence.
- Pin mode should not drop the HTTP status when rethrowing a probe failure — preserve the original error as
cause at minimum.
Value
With both fixed upstream, the Inspector's probe-era interceptAuthChallenges workaround in core/mcp/inspectorClient.ts can be narrowed or removed, and any other SDK consumer gets connect-time auth on the modern era for free.
Notes
- The
findNestedAuthError() unwrap in core/auth/challenge.ts is deliberately not gated on the SDK error code/message, so it should keep working across SDK rewording either way.
- Track the upstream issue/PR link here once filed.
Follow-up from #1805 / PR #1806.
Problem
Era
auto/modernsends the SDK'sserver/discovernegotiation probe beforeinitialize, so authorization first surfaces at the probe. On the direct transport path (CLI/TUI, and any path with no stored tokens and therefore noauthProvider), a 401 reaches the SDK as a rawSdkHttpError. The SDK'sclassifyHttpErroronly looks for a JSON-RPC error body — it ignores the HTTP status — so it verdicts "not a modern server". In pin mode (protocolEra: "modern") the classifier's verdict is then rethrown with the 401 discarded entirely: no status, not even acause.The Inspector worked around this in #1806 by enabling
interceptAuthChallengesfor the probing eras even with no stored tokens, so the 401 becomes a typedAuthChallengeErrorthat survives the probe asdata.cause. That is a client-side compensation for an SDK classification gap.Asks (upstream
@modelcontextprotocol/client)classifyHttpErrorshould treat HTTP 401/403 on the probe asauth-required, not as absence of modern evidence.causeat minimum.Value
With both fixed upstream, the Inspector's probe-era
interceptAuthChallengesworkaround incore/mcp/inspectorClient.tscan be narrowed or removed, and any other SDK consumer gets connect-time auth on the modern era for free.Notes
findNestedAuthError()unwrap incore/auth/challenge.tsis deliberately not gated on the SDK error code/message, so it should keep working across SDK rewording either way.