diff --git a/client/src/lib/auth.ts b/client/src/lib/auth.ts index 78d52a59e..c530a15de 100644 --- a/client/src/lib/auth.ts +++ b/client/src/lib/auth.ts @@ -253,10 +253,35 @@ export class DebugInspectorOAuthClientProvider extends InspectorOAuthClientProvi return JSON.parse(metadata); } + /** + * Saves the resource URL to session storage to persist it across the redirect. + */ + saveResource(resource: URL): void { + const key = getServerSpecificKey(SESSION_KEYS.RESOURCE_URL, this.serverUrl); + sessionStorage.setItem(key, resource.toString()); + } + + /** + * Retrieves the persisted resource URL from session storage. + */ + getResource(): URL | undefined { + const key = getServerSpecificKey(SESSION_KEYS.RESOURCE_URL, this.serverUrl); + const urlString = sessionStorage.getItem(key); + if (!urlString) { + return undefined; + } + return new URL(urlString); + } + clear() { super.clear(); sessionStorage.removeItem( getServerSpecificKey(SESSION_KEYS.SERVER_METADATA, this.serverUrl), ); + + // Also clear the resource URL + sessionStorage.removeItem( + getServerSpecificKey(SESSION_KEYS.RESOURCE_URL, this.serverUrl), + ); } } diff --git a/client/src/lib/constants.ts b/client/src/lib/constants.ts index 2e983302e..bf2dc5993 100644 --- a/client/src/lib/constants.ts +++ b/client/src/lib/constants.ts @@ -9,6 +9,7 @@ export const SESSION_KEYS = { PREREGISTERED_CLIENT_INFORMATION: "mcp_preregistered_client_information", SERVER_METADATA: "mcp_server_metadata", AUTH_DEBUGGER_STATE: "mcp_auth_debugger_state", + RESOURCE_URL: "mcp_resource_url", } as const; // Generate server-specific session storage keys diff --git a/client/src/lib/oauth-state-machine.ts b/client/src/lib/oauth-state-machine.ts index 914658535..caf7391e8 100644 --- a/client/src/lib/oauth-state-machine.ts +++ b/client/src/lib/oauth-state-machine.ts @@ -57,6 +57,11 @@ export const oauthTransitions: Record = { resourceMetadata ?? undefined, ); + // Persist the resource URL so it survives the redirect. + if (resource) { + context.provider.saveResource(resource); + } + const metadata = await discoverAuthorizationServerMetadata(authServerUrl); if (!metadata) { throw new Error("Failed to discover OAuth metadata"); @@ -171,6 +176,9 @@ export const oauthTransitions: Record = { const metadata = context.provider.getServerMetadata()!; const clientInformation = (await context.provider.clientInformation())!; + // Retrieve the resource from persistent storage, not volatile state. + const resource = context.provider.getResource(); + const tokens = await exchangeAuthorization(context.serverUrl, { metadata, clientInformation,