mcp-proxy
Version:
A TypeScript SSE proxy for MCP servers that use stdio transport.
1,120 lines (1,110 loc) • 90 kB
JavaScript
import { C as NEVER, S as _coercedNumber, T as AuthenticationMiddleware, _ as looseObject, a as startHTTPServer, b as string, c as LATEST_PROTOCOL_VERSION, d as isJSONRPCResponse, f as ZodNumber, g as literal, h as boolean, i as Client, l as isInitializedNotification, m as array, n as serializeMessage, o as proxyServer, p as any, r as Server, s as JSONRPCMessageSchema, t as ReadBuffer, u as isJSONRPCRequest, v as number$1, w as InMemoryEventStore, x as url, y as object } from "./stdio-DBuYn6eo.mjs";
import process from "node:process";
//#region node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/classic/compat.js
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
const ZodIssueCode = {
invalid_type: "invalid_type",
too_big: "too_big",
too_small: "too_small",
invalid_format: "invalid_format",
not_multiple_of: "not_multiple_of",
unrecognized_keys: "unrecognized_keys",
invalid_union: "invalid_union",
invalid_key: "invalid_key",
invalid_element: "invalid_element",
invalid_value: "invalid_value",
custom: "custom"
};
//#endregion
//#region node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/classic/coerce.js
function number(params) {
return _coercedNumber(ZodNumber, params);
}
//#endregion
//#region node_modules/.pnpm/eventsource-parser@3.0.6/node_modules/eventsource-parser/dist/index.js
var ParseError = class extends Error {
constructor(message, options) {
super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line;
}
};
function noop(_arg) {}
function createParser(callbacks) {
if (typeof callbacks == "function") throw new TypeError("`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?");
const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks;
let incompleteLine = "", isFirstChunk = !0, id, data = "", eventType = "";
function feed(newChunk) {
const chunk = isFirstChunk ? newChunk.replace(/^\xEF\xBB\xBF/, "") : newChunk, [complete, incomplete] = splitLines(`${incompleteLine}${chunk}`);
for (const line of complete) parseLine(line);
incompleteLine = incomplete, isFirstChunk = !1;
}
function parseLine(line) {
if (line === "") {
dispatchEvent();
return;
}
if (line.startsWith(":")) {
onComment && onComment(line.slice(line.startsWith(": ") ? 2 : 1));
return;
}
const fieldSeparatorIndex = line.indexOf(":");
if (fieldSeparatorIndex !== -1) {
const field = line.slice(0, fieldSeparatorIndex), offset = line[fieldSeparatorIndex + 1] === " " ? 2 : 1;
processField(field, line.slice(fieldSeparatorIndex + offset), line);
return;
}
processField(line, "", line);
}
function processField(field, value, line) {
switch (field) {
case "event":
eventType = value;
break;
case "data":
data = `${data}${value}
`;
break;
case "id":
id = value.includes("\0") ? void 0 : value;
break;
case "retry":
/^\d+$/.test(value) ? onRetry(parseInt(value, 10)) : onError(new ParseError(`Invalid \`retry\` value: "${value}"`, {
type: "invalid-retry",
value,
line
}));
break;
default:
onError(new ParseError(`Unknown field "${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}"`, {
type: "unknown-field",
field,
value,
line
}));
break;
}
}
function dispatchEvent() {
data.length > 0 && onEvent({
id,
event: eventType || void 0,
data: data.endsWith(`
`) ? data.slice(0, -1) : data
}), id = void 0, data = "", eventType = "";
}
function reset(options = {}) {
incompleteLine && options.consume && parseLine(incompleteLine), isFirstChunk = !0, id = void 0, data = "", eventType = "", incompleteLine = "";
}
return {
feed,
reset
};
}
function splitLines(chunk) {
const lines = [];
let incompleteLine = "", searchIndex = 0;
for (; searchIndex < chunk.length;) {
const crIndex = chunk.indexOf("\r", searchIndex), lfIndex = chunk.indexOf(`
`, searchIndex);
let lineEnd = -1;
if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = Math.min(crIndex, lfIndex) : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1) {
incompleteLine = chunk.slice(searchIndex);
break;
} else {
const line = chunk.slice(searchIndex, lineEnd);
lines.push(line), searchIndex = lineEnd + 1, chunk[searchIndex - 1] === "\r" && chunk[searchIndex] === `
` && searchIndex++;
}
}
return [lines, incompleteLine];
}
//#endregion
//#region node_modules/.pnpm/eventsource@3.0.7/node_modules/eventsource/dist/index.js
var ErrorEvent = class extends Event {
/**
* Constructs a new `ErrorEvent` instance. This is typically not called directly,
* but rather emitted by the `EventSource` object when an error occurs.
*
* @param type - The type of the event (should be "error")
* @param errorEventInitDict - Optional properties to include in the error event
*/
constructor(type, errorEventInitDict) {
var _a, _b;
super(type), this.code = (_a = errorEventInitDict == null ? void 0 : errorEventInitDict.code) != null ? _a : void 0, this.message = (_b = errorEventInitDict == null ? void 0 : errorEventInitDict.message) != null ? _b : void 0;
}
/**
* Node.js "hides" the `message` and `code` properties of the `ErrorEvent` instance,
* when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,
* we explicitly include the properties in the `inspect` method.
*
* This is automatically called by Node.js when you `console.log` an instance of this class.
*
* @param _depth - The current depth
* @param options - The options passed to `util.inspect`
* @param inspect - The inspect function to use (prevents having to import it from `util`)
* @returns A string representation of the error
*/
[Symbol.for("nodejs.util.inspect.custom")](_depth, options, inspect) {
return inspect(inspectableError(this), options);
}
/**
* Deno "hides" the `message` and `code` properties of the `ErrorEvent` instance,
* when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,
* we explicitly include the properties in the `inspect` method.
*
* This is automatically called by Deno when you `console.log` an instance of this class.
*
* @param inspect - The inspect function to use (prevents having to import it from `util`)
* @param options - The options passed to `Deno.inspect`
* @returns A string representation of the error
*/
[Symbol.for("Deno.customInspect")](inspect, options) {
return inspect(inspectableError(this), options);
}
};
function syntaxError(message) {
const DomException = globalThis.DOMException;
return typeof DomException == "function" ? new DomException(message, "SyntaxError") : new SyntaxError(message);
}
function flattenError(err) {
return err instanceof Error ? "errors" in err && Array.isArray(err.errors) ? err.errors.map(flattenError).join(", ") : "cause" in err && err.cause instanceof Error ? `${err}: ${flattenError(err.cause)}` : err.message : `${err}`;
}
function inspectableError(err) {
return {
type: err.type,
message: err.message,
code: err.code,
defaultPrevented: err.defaultPrevented,
cancelable: err.cancelable,
timeStamp: err.timeStamp
};
}
var __typeError = (msg) => {
throw TypeError(msg);
}, __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg), __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)), __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value), __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value), __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method), _readyState, _url, _redirectUrl, _withCredentials, _fetch, _reconnectInterval, _reconnectTimer, _lastEventId, _controller, _parser, _onError, _onMessage, _onOpen, _EventSource_instances, connect_fn, _onFetchResponse, _onFetchError, getRequestOptions_fn, _onEvent, _onRetryChange, failConnection_fn, scheduleReconnect_fn, _reconnect;
var EventSource = class extends EventTarget {
constructor(url$1, eventSourceInitDict) {
var _a, _b;
super(), __privateAdd(this, _EventSource_instances), this.CONNECTING = 0, this.OPEN = 1, this.CLOSED = 2, __privateAdd(this, _readyState), __privateAdd(this, _url), __privateAdd(this, _redirectUrl), __privateAdd(this, _withCredentials), __privateAdd(this, _fetch), __privateAdd(this, _reconnectInterval), __privateAdd(this, _reconnectTimer), __privateAdd(this, _lastEventId, null), __privateAdd(this, _controller), __privateAdd(this, _parser), __privateAdd(this, _onError, null), __privateAdd(this, _onMessage, null), __privateAdd(this, _onOpen, null), __privateAdd(this, _onFetchResponse, async (response) => {
var _a2;
__privateGet(this, _parser).reset();
const { body, redirected, status, headers } = response;
if (status === 204) {
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Server sent HTTP 204, not reconnecting", 204), this.close();
return;
}
if (redirected ? __privateSet(this, _redirectUrl, new URL(response.url)) : __privateSet(this, _redirectUrl, void 0), status !== 200) {
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, `Non-200 status code (${status})`, status);
return;
}
if (!(headers.get("content-type") || "").startsWith("text/event-stream")) {
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Invalid content type, expected \"text/event-stream\"", status);
return;
}
if (__privateGet(this, _readyState) === this.CLOSED) return;
__privateSet(this, _readyState, this.OPEN);
const openEvent = new Event("open");
if ((_a2 = __privateGet(this, _onOpen)) == null || _a2.call(this, openEvent), this.dispatchEvent(openEvent), typeof body != "object" || !body || !("getReader" in body)) {
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Invalid response body, expected a web ReadableStream", status), this.close();
return;
}
const decoder = new TextDecoder(), reader = body.getReader();
let open = !0;
do {
const { done, value } = await reader.read();
value && __privateGet(this, _parser).feed(decoder.decode(value, { stream: !done })), done && (open = !1, __privateGet(this, _parser).reset(), __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this));
} while (open);
}), __privateAdd(this, _onFetchError, (err) => {
__privateSet(this, _controller, void 0), !(err.name === "AbortError" || err.type === "aborted") && __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this, flattenError(err));
}), __privateAdd(this, _onEvent, (event) => {
typeof event.id == "string" && __privateSet(this, _lastEventId, event.id);
const messageEvent = new MessageEvent(event.event || "message", {
data: event.data,
origin: __privateGet(this, _redirectUrl) ? __privateGet(this, _redirectUrl).origin : __privateGet(this, _url).origin,
lastEventId: event.id || ""
});
__privateGet(this, _onMessage) && (!event.event || event.event === "message") && __privateGet(this, _onMessage).call(this, messageEvent), this.dispatchEvent(messageEvent);
}), __privateAdd(this, _onRetryChange, (value) => {
__privateSet(this, _reconnectInterval, value);
}), __privateAdd(this, _reconnect, () => {
__privateSet(this, _reconnectTimer, void 0), __privateGet(this, _readyState) === this.CONNECTING && __privateMethod(this, _EventSource_instances, connect_fn).call(this);
});
try {
if (url$1 instanceof URL) __privateSet(this, _url, url$1);
else if (typeof url$1 == "string") __privateSet(this, _url, new URL(url$1, getBaseURL()));
else throw new Error("Invalid URL");
} catch {
throw syntaxError("An invalid or illegal string was specified");
}
__privateSet(this, _parser, createParser({
onEvent: __privateGet(this, _onEvent),
onRetry: __privateGet(this, _onRetryChange)
})), __privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _reconnectInterval, 3e3), __privateSet(this, _fetch, (_a = eventSourceInitDict == null ? void 0 : eventSourceInitDict.fetch) != null ? _a : globalThis.fetch), __privateSet(this, _withCredentials, (_b = eventSourceInitDict == null ? void 0 : eventSourceInitDict.withCredentials) != null ? _b : !1), __privateMethod(this, _EventSource_instances, connect_fn).call(this);
}
/**
* Returns the state of this EventSource object's connection. It can have the values described below.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)
*
* Note: typed as `number` instead of `0 | 1 | 2` for compatibility with the `EventSource` interface,
* defined in the TypeScript `dom` library.
*
* @public
*/
get readyState() {
return __privateGet(this, _readyState);
}
/**
* Returns the URL providing the event stream.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)
*
* @public
*/
get url() {
return __privateGet(this, _url).href;
}
/**
* Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)
*/
get withCredentials() {
return __privateGet(this, _withCredentials);
}
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */
get onerror() {
return __privateGet(this, _onError);
}
set onerror(value) {
__privateSet(this, _onError, value);
}
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */
get onmessage() {
return __privateGet(this, _onMessage);
}
set onmessage(value) {
__privateSet(this, _onMessage, value);
}
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */
get onopen() {
return __privateGet(this, _onOpen);
}
set onopen(value) {
__privateSet(this, _onOpen, value);
}
addEventListener(type, listener, options) {
const listen = listener;
super.addEventListener(type, listen, options);
}
removeEventListener(type, listener, options) {
const listen = listener;
super.removeEventListener(type, listen, options);
}
/**
* Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)
*
* @public
*/
close() {
__privateGet(this, _reconnectTimer) && clearTimeout(__privateGet(this, _reconnectTimer)), __privateGet(this, _readyState) !== this.CLOSED && (__privateGet(this, _controller) && __privateGet(this, _controller).abort(), __privateSet(this, _readyState, this.CLOSED), __privateSet(this, _controller, void 0));
}
};
_readyState = /* @__PURE__ */ new WeakMap(), _url = /* @__PURE__ */ new WeakMap(), _redirectUrl = /* @__PURE__ */ new WeakMap(), _withCredentials = /* @__PURE__ */ new WeakMap(), _fetch = /* @__PURE__ */ new WeakMap(), _reconnectInterval = /* @__PURE__ */ new WeakMap(), _reconnectTimer = /* @__PURE__ */ new WeakMap(), _lastEventId = /* @__PURE__ */ new WeakMap(), _controller = /* @__PURE__ */ new WeakMap(), _parser = /* @__PURE__ */ new WeakMap(), _onError = /* @__PURE__ */ new WeakMap(), _onMessage = /* @__PURE__ */ new WeakMap(), _onOpen = /* @__PURE__ */ new WeakMap(), _EventSource_instances = /* @__PURE__ */ new WeakSet(), connect_fn = function() {
__privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _controller, new AbortController()), __privateGet(this, _fetch)(__privateGet(this, _url), __privateMethod(this, _EventSource_instances, getRequestOptions_fn).call(this)).then(__privateGet(this, _onFetchResponse)).catch(__privateGet(this, _onFetchError));
}, _onFetchResponse = /* @__PURE__ */ new WeakMap(), _onFetchError = /* @__PURE__ */ new WeakMap(), getRequestOptions_fn = function() {
var _a;
const init = {
mode: "cors",
redirect: "follow",
headers: {
Accept: "text/event-stream",
...__privateGet(this, _lastEventId) ? { "Last-Event-ID": __privateGet(this, _lastEventId) } : void 0
},
cache: "no-store",
signal: (_a = __privateGet(this, _controller)) == null ? void 0 : _a.signal
};
return "window" in globalThis && (init.credentials = this.withCredentials ? "include" : "same-origin"), init;
}, _onEvent = /* @__PURE__ */ new WeakMap(), _onRetryChange = /* @__PURE__ */ new WeakMap(), failConnection_fn = function(message, code) {
var _a;
__privateGet(this, _readyState) !== this.CLOSED && __privateSet(this, _readyState, this.CLOSED);
const errorEvent = new ErrorEvent("error", {
code,
message
});
(_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent);
}, scheduleReconnect_fn = function(message, code) {
var _a;
if (__privateGet(this, _readyState) === this.CLOSED) return;
__privateSet(this, _readyState, this.CONNECTING);
const errorEvent = new ErrorEvent("error", {
code,
message
});
(_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent), __privateSet(this, _reconnectTimer, setTimeout(__privateGet(this, _reconnect), __privateGet(this, _reconnectInterval)));
}, _reconnect = /* @__PURE__ */ new WeakMap(), EventSource.CONNECTING = 0, EventSource.OPEN = 1, EventSource.CLOSED = 2;
function getBaseURL() {
const doc = "document" in globalThis ? globalThis.document : void 0;
return doc && typeof doc == "object" && "baseURI" in doc && typeof doc.baseURI == "string" ? doc.baseURI : void 0;
}
//#endregion
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.24.3_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js
/**
* Normalizes HeadersInit to a plain Record<string, string> for manipulation.
* Handles Headers objects, arrays of tuples, and plain objects.
*/
function normalizeHeaders(headers) {
if (!headers) return {};
if (headers instanceof Headers) return Object.fromEntries(headers.entries());
if (Array.isArray(headers)) return Object.fromEntries(headers);
return { ...headers };
}
/**
* Creates a fetch function that includes base RequestInit options.
* This ensures requests inherit settings like credentials, mode, headers, etc. from the base init.
*
* @param baseFetch - The base fetch function to wrap (defaults to global fetch)
* @param baseInit - The base RequestInit to merge with each request
* @returns A wrapped fetch function that merges base options with call-specific options
*/
function createFetchWithInit(baseFetch = fetch, baseInit) {
if (!baseInit) return baseFetch;
return async (url$1, init) => {
return baseFetch(url$1, {
...baseInit,
...init,
headers: (init === null || init === void 0 ? void 0 : init.headers) ? {
...normalizeHeaders(baseInit.headers),
...normalizeHeaders(init.headers)
} : baseInit.headers
});
};
}
//#endregion
//#region node_modules/.pnpm/pkce-challenge@5.0.0/node_modules/pkce-challenge/dist/index.node.js
let crypto;
crypto = globalThis.crypto?.webcrypto ?? globalThis.crypto ?? import("node:crypto").then((m) => m.webcrypto);
/**
* Creates an array of length `size` of random bytes
* @param size
* @returns Array of random ints (0 to 255)
*/
async function getRandomValues(size) {
return (await crypto).getRandomValues(new Uint8Array(size));
}
/** Generate cryptographically strong random string
* @param size The desired length of the string
* @returns The random string
*/
async function random(size) {
const mask = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
let result = "";
const randomUints = await getRandomValues(size);
for (let i = 0; i < size; i++) {
const randomIndex = randomUints[i] % 66;
result += mask[randomIndex];
}
return result;
}
/** Generate a PKCE challenge verifier
* @param length Length of the verifier
* @returns A random verifier `length` characters long
*/
async function generateVerifier(length) {
return await random(length);
}
/** Generate a PKCE code challenge from a code verifier
* @param code_verifier
* @returns The base64 url encoded code challenge
*/
async function generateChallenge(code_verifier) {
const buffer = await (await crypto).subtle.digest("SHA-256", new TextEncoder().encode(code_verifier));
return btoa(String.fromCharCode(...new Uint8Array(buffer))).replace(/\//g, "_").replace(/\+/g, "-").replace(/=/g, "");
}
/** Generate a PKCE challenge pair
* @param length Length of the verifer (between 43-128). Defaults to 43.
* @returns PKCE challenge pair
*/
async function pkceChallenge(length) {
if (!length) length = 43;
if (length < 43 || length > 128) throw `Expected a length between 43 and 128. Received ${length}.`;
const verifier = await generateVerifier(length);
return {
code_verifier: verifier,
code_challenge: await generateChallenge(verifier)
};
}
//#endregion
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.24.3_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js
/**
* Reusable URL validation that disallows javascript: scheme
*/
const SafeUrlSchema = url().superRefine((val, ctx) => {
if (!URL.canParse(val)) {
ctx.addIssue({
code: ZodIssueCode.custom,
message: "URL must be parseable",
fatal: true
});
return NEVER;
}
}).refine((url$1) => {
const u = new URL(url$1);
return u.protocol !== "javascript:" && u.protocol !== "data:" && u.protocol !== "vbscript:";
}, { message: "URL cannot use javascript:, data:, or vbscript: scheme" });
/**
* RFC 9728 OAuth Protected Resource Metadata
*/
const OAuthProtectedResourceMetadataSchema = looseObject({
resource: string().url(),
authorization_servers: array(SafeUrlSchema).optional(),
jwks_uri: string().url().optional(),
scopes_supported: array(string()).optional(),
bearer_methods_supported: array(string()).optional(),
resource_signing_alg_values_supported: array(string()).optional(),
resource_name: string().optional(),
resource_documentation: string().optional(),
resource_policy_uri: string().url().optional(),
resource_tos_uri: string().url().optional(),
tls_client_certificate_bound_access_tokens: boolean().optional(),
authorization_details_types_supported: array(string()).optional(),
dpop_signing_alg_values_supported: array(string()).optional(),
dpop_bound_access_tokens_required: boolean().optional()
});
/**
* RFC 8414 OAuth 2.0 Authorization Server Metadata
*/
const OAuthMetadataSchema = looseObject({
issuer: string(),
authorization_endpoint: SafeUrlSchema,
token_endpoint: SafeUrlSchema,
registration_endpoint: SafeUrlSchema.optional(),
scopes_supported: array(string()).optional(),
response_types_supported: array(string()),
response_modes_supported: array(string()).optional(),
grant_types_supported: array(string()).optional(),
token_endpoint_auth_methods_supported: array(string()).optional(),
token_endpoint_auth_signing_alg_values_supported: array(string()).optional(),
service_documentation: SafeUrlSchema.optional(),
revocation_endpoint: SafeUrlSchema.optional(),
revocation_endpoint_auth_methods_supported: array(string()).optional(),
revocation_endpoint_auth_signing_alg_values_supported: array(string()).optional(),
introspection_endpoint: string().optional(),
introspection_endpoint_auth_methods_supported: array(string()).optional(),
introspection_endpoint_auth_signing_alg_values_supported: array(string()).optional(),
code_challenge_methods_supported: array(string()).optional(),
client_id_metadata_document_supported: boolean().optional()
});
/**
* OpenID Connect Discovery 1.0 Provider Metadata
* see: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
*/
const OpenIdProviderMetadataSchema = looseObject({
issuer: string(),
authorization_endpoint: SafeUrlSchema,
token_endpoint: SafeUrlSchema,
userinfo_endpoint: SafeUrlSchema.optional(),
jwks_uri: SafeUrlSchema,
registration_endpoint: SafeUrlSchema.optional(),
scopes_supported: array(string()).optional(),
response_types_supported: array(string()),
response_modes_supported: array(string()).optional(),
grant_types_supported: array(string()).optional(),
acr_values_supported: array(string()).optional(),
subject_types_supported: array(string()),
id_token_signing_alg_values_supported: array(string()),
id_token_encryption_alg_values_supported: array(string()).optional(),
id_token_encryption_enc_values_supported: array(string()).optional(),
userinfo_signing_alg_values_supported: array(string()).optional(),
userinfo_encryption_alg_values_supported: array(string()).optional(),
userinfo_encryption_enc_values_supported: array(string()).optional(),
request_object_signing_alg_values_supported: array(string()).optional(),
request_object_encryption_alg_values_supported: array(string()).optional(),
request_object_encryption_enc_values_supported: array(string()).optional(),
token_endpoint_auth_methods_supported: array(string()).optional(),
token_endpoint_auth_signing_alg_values_supported: array(string()).optional(),
display_values_supported: array(string()).optional(),
claim_types_supported: array(string()).optional(),
claims_supported: array(string()).optional(),
service_documentation: string().optional(),
claims_locales_supported: array(string()).optional(),
ui_locales_supported: array(string()).optional(),
claims_parameter_supported: boolean().optional(),
request_parameter_supported: boolean().optional(),
request_uri_parameter_supported: boolean().optional(),
require_request_uri_registration: boolean().optional(),
op_policy_uri: SafeUrlSchema.optional(),
op_tos_uri: SafeUrlSchema.optional(),
client_id_metadata_document_supported: boolean().optional()
});
/**
* OpenID Connect Discovery metadata that may include OAuth 2.0 fields
* This schema represents the real-world scenario where OIDC providers
* return a mix of OpenID Connect and OAuth 2.0 metadata fields
*/
const OpenIdProviderDiscoveryMetadataSchema = object({
...OpenIdProviderMetadataSchema.shape,
...OAuthMetadataSchema.pick({ code_challenge_methods_supported: true }).shape
});
/**
* OAuth 2.1 token response
*/
const OAuthTokensSchema = object({
access_token: string(),
id_token: string().optional(),
token_type: string(),
expires_in: number().optional(),
scope: string().optional(),
refresh_token: string().optional()
}).strip();
/**
* OAuth 2.1 error response
*/
const OAuthErrorResponseSchema = object({
error: string(),
error_description: string().optional(),
error_uri: string().optional()
});
/**
* Optional version of SafeUrlSchema that allows empty string for retrocompatibility on tos_uri and logo_uri
*/
const OptionalSafeUrlSchema = SafeUrlSchema.optional().or(literal("").transform(() => void 0));
/**
* RFC 7591 OAuth 2.0 Dynamic Client Registration metadata
*/
const OAuthClientMetadataSchema = object({
redirect_uris: array(SafeUrlSchema),
token_endpoint_auth_method: string().optional(),
grant_types: array(string()).optional(),
response_types: array(string()).optional(),
client_name: string().optional(),
client_uri: SafeUrlSchema.optional(),
logo_uri: OptionalSafeUrlSchema,
scope: string().optional(),
contacts: array(string()).optional(),
tos_uri: OptionalSafeUrlSchema,
policy_uri: string().optional(),
jwks_uri: SafeUrlSchema.optional(),
jwks: any().optional(),
software_id: string().optional(),
software_version: string().optional(),
software_statement: string().optional()
}).strip();
/**
* RFC 7591 OAuth 2.0 Dynamic Client Registration client information
*/
const OAuthClientInformationSchema = object({
client_id: string(),
client_secret: string().optional(),
client_id_issued_at: number$1().optional(),
client_secret_expires_at: number$1().optional()
}).strip();
/**
* RFC 7591 OAuth 2.0 Dynamic Client Registration full response (client information plus metadata)
*/
const OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(OAuthClientInformationSchema);
/**
* RFC 7591 OAuth 2.0 Dynamic Client Registration error response
*/
const OAuthClientRegistrationErrorSchema = object({
error: string(),
error_description: string().optional()
}).strip();
/**
* RFC 7009 OAuth 2.0 Token Revocation request
*/
const OAuthTokenRevocationRequestSchema = object({
token: string(),
token_type_hint: string().optional()
}).strip();
//#endregion
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.24.3_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth-utils.js
/**
* Utilities for handling OAuth resource URIs.
*/
/**
* Converts a server URL to a resource URL by removing the fragment.
* RFC 8707 section 2 states that resource URIs "MUST NOT include a fragment component".
* Keeps everything else unchanged (scheme, domain, port, path, query).
*/
function resourceUrlFromServerUrl(url$1) {
const resourceURL = typeof url$1 === "string" ? new URL(url$1) : new URL(url$1.href);
resourceURL.hash = "";
return resourceURL;
}
/**
* Checks if a requested resource URL matches a configured resource URL.
* A requested resource matches if it has the same scheme, domain, port,
* and its path starts with the configured resource's path.
*
* @param requestedResource The resource URL being requested
* @param configuredResource The resource URL that has been configured
* @returns true if the requested resource matches the configured resource, false otherwise
*/
function checkResourceAllowed({ requestedResource, configuredResource }) {
const requested = typeof requestedResource === "string" ? new URL(requestedResource) : new URL(requestedResource.href);
const configured = typeof configuredResource === "string" ? new URL(configuredResource) : new URL(configuredResource.href);
if (requested.origin !== configured.origin) return false;
if (requested.pathname.length < configured.pathname.length) return false;
const requestedPath = requested.pathname.endsWith("/") ? requested.pathname : requested.pathname + "/";
const configuredPath = configured.pathname.endsWith("/") ? configured.pathname : configured.pathname + "/";
return requestedPath.startsWith(configuredPath);
}
//#endregion
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.24.3_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/errors.js
/**
* Base class for all OAuth errors
*/
var OAuthError = class extends Error {
constructor(message, errorUri) {
super(message);
this.errorUri = errorUri;
this.name = this.constructor.name;
}
/**
* Converts the error to a standard OAuth error response object
*/
toResponseObject() {
const response = {
error: this.errorCode,
error_description: this.message
};
if (this.errorUri) response.error_uri = this.errorUri;
return response;
}
get errorCode() {
return this.constructor.errorCode;
}
};
/**
* Invalid request error - The request is missing a required parameter,
* includes an invalid parameter value, includes a parameter more than once,
* or is otherwise malformed.
*/
var InvalidRequestError = class extends OAuthError {};
InvalidRequestError.errorCode = "invalid_request";
/**
* Invalid client error - Client authentication failed (e.g., unknown client, no client
* authentication included, or unsupported authentication method).
*/
var InvalidClientError = class extends OAuthError {};
InvalidClientError.errorCode = "invalid_client";
/**
* Invalid grant error - The provided authorization grant or refresh token is
* invalid, expired, revoked, does not match the redirection URI used in the
* authorization request, or was issued to another client.
*/
var InvalidGrantError = class extends OAuthError {};
InvalidGrantError.errorCode = "invalid_grant";
/**
* Unauthorized client error - The authenticated client is not authorized to use
* this authorization grant type.
*/
var UnauthorizedClientError = class extends OAuthError {};
UnauthorizedClientError.errorCode = "unauthorized_client";
/**
* Unsupported grant type error - The authorization grant type is not supported
* by the authorization server.
*/
var UnsupportedGrantTypeError = class extends OAuthError {};
UnsupportedGrantTypeError.errorCode = "unsupported_grant_type";
/**
* Invalid scope error - The requested scope is invalid, unknown, malformed, or
* exceeds the scope granted by the resource owner.
*/
var InvalidScopeError = class extends OAuthError {};
InvalidScopeError.errorCode = "invalid_scope";
/**
* Access denied error - The resource owner or authorization server denied the request.
*/
var AccessDeniedError = class extends OAuthError {};
AccessDeniedError.errorCode = "access_denied";
/**
* Server error - The authorization server encountered an unexpected condition
* that prevented it from fulfilling the request.
*/
var ServerError = class extends OAuthError {};
ServerError.errorCode = "server_error";
/**
* Temporarily unavailable error - The authorization server is currently unable to
* handle the request due to a temporary overloading or maintenance of the server.
*/
var TemporarilyUnavailableError = class extends OAuthError {};
TemporarilyUnavailableError.errorCode = "temporarily_unavailable";
/**
* Unsupported response type error - The authorization server does not support
* obtaining an authorization code using this method.
*/
var UnsupportedResponseTypeError = class extends OAuthError {};
UnsupportedResponseTypeError.errorCode = "unsupported_response_type";
/**
* Unsupported token type error - The authorization server does not support
* the requested token type.
*/
var UnsupportedTokenTypeError = class extends OAuthError {};
UnsupportedTokenTypeError.errorCode = "unsupported_token_type";
/**
* Invalid token error - The access token provided is expired, revoked, malformed,
* or invalid for other reasons.
*/
var InvalidTokenError = class extends OAuthError {};
InvalidTokenError.errorCode = "invalid_token";
/**
* Method not allowed error - The HTTP method used is not allowed for this endpoint.
* (Custom, non-standard error)
*/
var MethodNotAllowedError = class extends OAuthError {};
MethodNotAllowedError.errorCode = "method_not_allowed";
/**
* Too many requests error - Rate limit exceeded.
* (Custom, non-standard error based on RFC 6585)
*/
var TooManyRequestsError = class extends OAuthError {};
TooManyRequestsError.errorCode = "too_many_requests";
/**
* Invalid client metadata error - The client metadata is invalid.
* (Custom error for dynamic client registration - RFC 7591)
*/
var InvalidClientMetadataError = class extends OAuthError {};
InvalidClientMetadataError.errorCode = "invalid_client_metadata";
/**
* Insufficient scope error - The request requires higher privileges than provided by the access token.
*/
var InsufficientScopeError = class extends OAuthError {};
InsufficientScopeError.errorCode = "insufficient_scope";
/**
* Invalid target error - The requested resource is invalid, missing, unknown, or malformed.
* (Custom error for resource indicators - RFC 8707)
*/
var InvalidTargetError = class extends OAuthError {};
InvalidTargetError.errorCode = "invalid_target";
/**
* A full list of all OAuthErrors, enabling parsing from error responses
*/
const OAUTH_ERRORS = {
[InvalidRequestError.errorCode]: InvalidRequestError,
[InvalidClientError.errorCode]: InvalidClientError,
[InvalidGrantError.errorCode]: InvalidGrantError,
[UnauthorizedClientError.errorCode]: UnauthorizedClientError,
[UnsupportedGrantTypeError.errorCode]: UnsupportedGrantTypeError,
[InvalidScopeError.errorCode]: InvalidScopeError,
[AccessDeniedError.errorCode]: AccessDeniedError,
[ServerError.errorCode]: ServerError,
[TemporarilyUnavailableError.errorCode]: TemporarilyUnavailableError,
[UnsupportedResponseTypeError.errorCode]: UnsupportedResponseTypeError,
[UnsupportedTokenTypeError.errorCode]: UnsupportedTokenTypeError,
[InvalidTokenError.errorCode]: InvalidTokenError,
[MethodNotAllowedError.errorCode]: MethodNotAllowedError,
[TooManyRequestsError.errorCode]: TooManyRequestsError,
[InvalidClientMetadataError.errorCode]: InvalidClientMetadataError,
[InsufficientScopeError.errorCode]: InsufficientScopeError,
[InvalidTargetError.errorCode]: InvalidTargetError
};
//#endregion
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.24.3_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js
var UnauthorizedError = class extends Error {
constructor(message) {
super(message !== null && message !== void 0 ? message : "Unauthorized");
}
};
function isClientAuthMethod(method) {
return [
"client_secret_basic",
"client_secret_post",
"none"
].includes(method);
}
const AUTHORIZATION_CODE_RESPONSE_TYPE = "code";
const AUTHORIZATION_CODE_CHALLENGE_METHOD = "S256";
/**
* Determines the best client authentication method to use based on server support and client configuration.
*
* Priority order (highest to lowest):
* 1. client_secret_basic (if client secret is available)
* 2. client_secret_post (if client secret is available)
* 3. none (for public clients)
*
* @param clientInformation - OAuth client information containing credentials
* @param supportedMethods - Authentication methods supported by the authorization server
* @returns The selected authentication method
*/
function selectClientAuthMethod(clientInformation, supportedMethods) {
const hasClientSecret = clientInformation.client_secret !== void 0;
if (supportedMethods.length === 0) return hasClientSecret ? "client_secret_post" : "none";
if ("token_endpoint_auth_method" in clientInformation && clientInformation.token_endpoint_auth_method && isClientAuthMethod(clientInformation.token_endpoint_auth_method) && supportedMethods.includes(clientInformation.token_endpoint_auth_method)) return clientInformation.token_endpoint_auth_method;
if (hasClientSecret && supportedMethods.includes("client_secret_basic")) return "client_secret_basic";
if (hasClientSecret && supportedMethods.includes("client_secret_post")) return "client_secret_post";
if (supportedMethods.includes("none")) return "none";
return hasClientSecret ? "client_secret_post" : "none";
}
/**
* Applies client authentication to the request based on the specified method.
*
* Implements OAuth 2.1 client authentication methods:
* - client_secret_basic: HTTP Basic authentication (RFC 6749 Section 2.3.1)
* - client_secret_post: Credentials in request body (RFC 6749 Section 2.3.1)
* - none: Public client authentication (RFC 6749 Section 2.1)
*
* @param method - The authentication method to use
* @param clientInformation - OAuth client information containing credentials
* @param headers - HTTP headers object to modify
* @param params - URL search parameters to modify
* @throws {Error} When required credentials are missing
*/
function applyClientAuthentication(method, clientInformation, headers, params) {
const { client_id, client_secret } = clientInformation;
switch (method) {
case "client_secret_basic":
applyBasicAuth(client_id, client_secret, headers);
return;
case "client_secret_post":
applyPostAuth(client_id, client_secret, params);
return;
case "none":
applyPublicAuth(client_id, params);
return;
default: throw new Error(`Unsupported client authentication method: ${method}`);
}
}
/**
* Applies HTTP Basic authentication (RFC 6749 Section 2.3.1)
*/
function applyBasicAuth(clientId, clientSecret, headers) {
if (!clientSecret) throw new Error("client_secret_basic authentication requires a client_secret");
const credentials = btoa(`${clientId}:${clientSecret}`);
headers.set("Authorization", `Basic ${credentials}`);
}
/**
* Applies POST body authentication (RFC 6749 Section 2.3.1)
*/
function applyPostAuth(clientId, clientSecret, params) {
params.set("client_id", clientId);
if (clientSecret) params.set("client_secret", clientSecret);
}
/**
* Applies public client authentication (RFC 6749 Section 2.1)
*/
function applyPublicAuth(clientId, params) {
params.set("client_id", clientId);
}
/**
* Parses an OAuth error response from a string or Response object.
*
* If the input is a standard OAuth2.0 error response, it will be parsed according to the spec
* and an instance of the appropriate OAuthError subclass will be returned.
* If parsing fails, it falls back to a generic ServerError that includes
* the response status (if available) and original content.
*
* @param input - A Response object or string containing the error response
* @returns A Promise that resolves to an OAuthError instance
*/
async function parseErrorResponse(input) {
const statusCode = input instanceof Response ? input.status : void 0;
const body = input instanceof Response ? await input.text() : input;
try {
const { error, error_description, error_uri } = OAuthErrorResponseSchema.parse(JSON.parse(body));
return new (OAUTH_ERRORS[error] || ServerError)(error_description || "", error_uri);
} catch (error) {
return new ServerError(`${statusCode ? `HTTP ${statusCode}: ` : ""}Invalid OAuth error response: ${error}. Raw body: ${body}`);
}
}
/**
* Orchestrates the full auth flow with a server.
*
* This can be used as a single entry point for all authorization functionality,
* instead of linking together the other lower-level functions in this module.
*/
async function auth(provider, options) {
var _a, _b;
try {
return await authInternal(provider, options);
} catch (error) {
if (error instanceof InvalidClientError || error instanceof UnauthorizedClientError) {
await ((_a = provider.invalidateCredentials) === null || _a === void 0 ? void 0 : _a.call(provider, "all"));
return await authInternal(provider, options);
} else if (error instanceof InvalidGrantError) {
await ((_b = provider.invalidateCredentials) === null || _b === void 0 ? void 0 : _b.call(provider, "tokens"));
return await authInternal(provider, options);
}
throw error;
}
}
async function authInternal(provider, { serverUrl, authorizationCode, scope, resourceMetadataUrl, fetchFn }) {
var _a, _b;
let resourceMetadata;
let authorizationServerUrl;
try {
resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl, { resourceMetadataUrl }, fetchFn);
if (resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0) authorizationServerUrl = resourceMetadata.authorization_servers[0];
} catch (_c) {}
/**
* If we don't get a valid authorization server metadata from protected resource metadata,
* fallback to the legacy MCP spec's implementation (version 2025-03-26): MCP server base URL acts as the Authorization server.
*/
if (!authorizationServerUrl) authorizationServerUrl = new URL("/", serverUrl);
const resource = await selectResourceURL(serverUrl, provider, resourceMetadata);
const metadata = await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn });
let clientInformation = await Promise.resolve(provider.clientInformation());
if (!clientInformation) {
if (authorizationCode !== void 0) throw new Error("Existing OAuth client information is required when exchanging an authorization code");
const supportsUrlBasedClientId = (metadata === null || metadata === void 0 ? void 0 : metadata.client_id_metadata_document_supported) === true;
const clientMetadataUrl = provider.clientMetadataUrl;
if (clientMetadataUrl && !isHttpsUrl(clientMetadataUrl)) throw new InvalidClientMetadataError(`clientMetadataUrl must be a valid HTTPS URL with a non-root pathname, got: ${clientMetadataUrl}`);
if (supportsUrlBasedClientId && clientMetadataUrl) {
clientInformation = { client_id: clientMetadataUrl };
await ((_a = provider.saveClientInformation) === null || _a === void 0 ? void 0 : _a.call(provider, clientInformation));
} else {
if (!provider.saveClientInformation) throw new Error("OAuth client information must be saveable for dynamic registration");
const fullInformation = await registerClient(authorizationServerUrl, {
metadata,
clientMetadata: provider.clientMetadata,
fetchFn
});
await provider.saveClientInformation(fullInformation);
clientInformation = fullInformation;
}
}
const nonInteractiveFlow = !provider.redirectUrl;
if (authorizationCode !== void 0 || nonInteractiveFlow) {
const tokens$1 = await fetchToken(provider, authorizationServerUrl, {
metadata,
resource,
authorizationCode,
fetchFn
});
await provider.saveTokens(tokens$1);
return "AUTHORIZED";
}
const tokens = await provider.tokens();
if (tokens === null || tokens === void 0 ? void 0 : tokens.refresh_token) try {
const newTokens = await refreshAuthorization(authorizationServerUrl, {
metadata,
clientInformation,
refreshToken: tokens.refresh_token,
resource,
addClientAuthentication: provider.addClientAuthentication,
fetchFn
});
await provider.saveTokens(newTokens);
return "AUTHORIZED";
} catch (error) {
if (!(error instanceof OAuthError) || error instanceof ServerError) {} else throw error;
}
const state = provider.state ? await provider.state() : void 0;
const { authorizationUrl, codeVerifier } = await startAuthorization(authorizationServerUrl, {
metadata,
clientInformation,
state,
redirectUrl: provider.redirectUrl,
scope: scope || ((_b = resourceMetadata === null || resourceMetadata === void 0 ? void 0 : resourceMetadata.scopes_supported) === null || _b === void 0 ? void 0 : _b.join(" ")) || provider.clientMetadata.scope,
resource
});
await provider.saveCodeVerifier(codeVerifier);
await provider.redirectToAuthorization(authorizationUrl);
return "REDIRECT";
}
/**
* SEP-991: URL-based Client IDs
* Validate that the client_id is a valid URL with https scheme
*/
function isHttpsUrl(value) {
if (!value) return false;
try {
const url$1 = new URL(value);
return url$1.protocol === "https:" && url$1.pathname !== "/";
} catch (_a) {
return false;
}
}
async function selectResourceURL(serverUrl, provider, resourceMetadata) {
const defaultResource = resourceUrlFromServerUrl(serverUrl);
if (provider.validateResourceURL) return await provider.validateResourceURL(defaultResource, resourceMetadata === null || resourceMetadata === void 0 ? void 0 : resourceMetadata.resource);
if (!resourceMetadata) return;
if (!checkResourceAllowed({
requestedResource: defaultResource,
configuredResource: resourceMetadata.resource
})) throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${defaultResource} (or origin)`);
return new URL(resourceMetadata.resource);
}
/**
* Extract resource_metadata, scope, and error from WWW-Authenticate header.
*/
function extractWWWAuthenticateParams(res) {
const authenticateHeader = res.headers.get("WWW-Authenticate");
if (!authenticateHeader) return {};
const [type, scheme] = authenticateHeader.split(" ");
if (type.toLowerCase() !== "bearer" || !scheme) return {};
const resourceMetadataMatch = extractFieldFromWwwAuth(res, "resource_metadata") || void 0;
let resourceMetadataUrl;
if (resourceMetadataMatch) try {
resourceMetadataUrl = new URL(resourceMetadataMatch);
} catch (_a) {}
const scope = extractFieldFromWwwAuth(res, "scope") || void 0;
const error = extractFieldFromWwwAuth(res, "error") || void 0;
return {
resourceMetadataUrl,
scope,
error
};
}
/**
* Extracts a specific field's value from the WWW-Authenticate header string.
*
* @param response The HTTP response object containing the headers.
* @param fieldName The name of the field to extract (e.g., "realm", "nonce").
* @returns The field value
*/
function extractFieldFromWwwAuth(response, fieldName) {
const wwwAuthHeader = response.headers.get("WWW-Authenticate");
if (!wwwAuthHeader) return null;
const pattern = /* @__PURE__ */ new RegExp(`${fieldName}=(?:"([^"]+)"|([^\\s,]+))`);
const match = wwwAuthHeader.match(pattern);
if (match) return match[1] || match[2];
return null;
}
/**
* Looks up RFC 9728 OAuth 2.0 Protected Resource Metadata.
*
* If the server returns a 404 for the well-known endpoint, this function will
* return `undefined`. Any other errors will be thrown as exceptions.
*/
async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn = fetch) {
var _a, _b;
const response = await discoverMetadataWithFallback(serverUrl, "oauth-protected-resource", fetchFn, {
protocolVersion: opts === null || opts === void 0 ? void 0 : opts.protocolVersion,
metadataUrl: opts === null || opts === void 0 ? void 0 : opts.resourceMetadataUrl
});
if (!response || response.status === 404) {
await ((_a = response === null || response === void 0 ? void 0 : response.body) === null || _a === void 0 ? void 0 : _a.cancel());
throw new Error(`Resource server does not implement OAuth 2.0 Protected Resource Metadata.`);
}
if (!response.ok) {
await ((_b = response.body) === null || _b === void 0 ? void 0 : _b.cancel());
throw new Error(`HTTP ${response.status} trying to load well-known OAuth protected resource metadata.`);
}
return OAuthProtectedResourceMetadataSchema.parse(await response.json());
}
/**
* Helper function to handle fetch with CORS retry logic
*/
async function fetchWithCorsRetry(url$1, headers, fetchFn = fetch) {
try {
return await fetchFn(url$1, { headers });
} catch (error) {
if (error instanceof TypeError) if (headers) return fetchWithCorsRetry(url$1, void 0, fetchFn);
else return;
throw error;
}
}
/**
* Constructs the well-known path for auth-related metadata discovery
*/
function buildWellKnownPath(wellKnownPrefix, pathname = "", options = {}) {
if (pathname.endsWith("/")) pathname = pathname.slice(0, -1);
return options.prependPathname ? `${pathname}/.well-known/${wellKnownPrefix}` : `/.well-known/${wellKnownPrefix}${pathname}`;
}
/**
* Tries to discover OAuth metadata at a specific URL
*/
async function tryM