inspector/core/mcp/node/authChallengeFetch.ts
Cliff Hall 373f346e5f
Some checks failed
Run install, format, lint, build, and test on every push / build (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish-github-container-registry (push) Has been cancelled
chore: close quality-gate coverage gaps (#1689) (#1766)
Closes #1689. Typecheck cli/tui src, add a core/ format+lint gate, and gate core/json + core/client coverage. See PR #1766 for the full review history.
2026-07-24 17:20:12 -04:00

35 lines
1.1 KiB
TypeScript

import {
AuthChallengeError,
parseAuthChallengeFromResponse,
} from "../../auth/challenge.js";
/**
* Wrap fetch so MCP HTTP 401/403 responses become {@link AuthChallengeError}
* before the SDK invokes `auth()` on a frozen remote token provider.
*/
export function createAuthChallengeInterceptFetch(
baseFetch: typeof fetch,
): typeof fetch {
return async (input, init) => {
const response = await baseFetch(input, init);
if (response.status !== 401 && response.status !== 403) {
return response;
}
const challenge = parseAuthChallengeFromResponse(response);
/* v8 ignore next 3 -- parseAuthChallengeFromResponse only returns undefined for non-401/403, which the status guard above already excludes */
if (!challenge) {
return response;
}
// Release the connection before throwing so the SDK transport is not left
// with a half-read 401/403 body on streamable HTTP.
await response.body?.cancel().catch(() => {});
throw new AuthChallengeError(
challenge,
response.status,
`MCP auth challenge (${response.status})`,
);
};
}