From e868f8f06d7dfc859ada22ace8fdad7822e3cceb Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 24 Jul 2025 06:59:25 +0000 Subject: [PATCH 1/2] feat: Add onPopupWindow callback and update README --- README.md | 1 + src/auth/browser-provider.ts | 7 +++++++ src/react/types.ts | 6 ++++++ src/react/useMcp.ts | 3 +++ 4 files changed, 17 insertions(+) diff --git a/README.md b/README.md index 1b871b0..bc4aa8e 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,7 @@ function useMcp(options: UseMcpOptions): UseMcpResult | `autoReconnect` | `boolean \| number` | Auto reconnect if an established connection is lost, with delay in ms (default: 3000) | | `transportType` | `'auto' \| 'http' \| 'sse'` | Transport type preference: 'auto' (HTTP with SSE fallback), 'http' (HTTP only), 'sse' (SSE only) (default: 'auto') | | `preventAutoAuth` | `boolean` | Prevent automatic authentication popup on initial connection (default: false) | +| `onPopupWindow` | `(url: string, features: string) => void` | Callback invoked just before the authentication popup window is opened | #### Return Value diff --git a/src/auth/browser-provider.ts b/src/auth/browser-provider.ts index 7b0e7b1..2690e9a 100644 --- a/src/auth/browser-provider.ts +++ b/src/auth/browser-provider.ts @@ -15,6 +15,7 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider { readonly clientName: string readonly clientUri: string readonly callbackUrl: string + readonly onPopupWindow: ((url: string, features: string) => void) | undefined constructor( serverUrl: string, @@ -23,6 +24,7 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider { clientName?: string clientUri?: string callbackUrl?: string + onPopupWindow?: (url: string, features: string) => void } = {}, ) { this.serverUrl = serverUrl @@ -34,6 +36,7 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider { options.callbackUrl || (typeof window !== 'undefined' ? new URL('/oauth/callback', window.location.origin).toString() : '/oauth/callback'), ) + this.onPopupWindow = options.onPopupWindow } // --- SDK Interface Methods --- @@ -167,6 +170,10 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider { // Attempt to open the popup const popupFeatures = 'width=600,height=700,resizable=yes,scrollbars=yes,status=yes' // Make configurable if needed try { + // If a callback is provided, invoke it before opening the popup + if (this.onPopupWindow) { + this.onPopupWindow(sanitizedAuthUrl, popupFeatures) + } const popup = window.open(sanitizedAuthUrl, `mcp_auth_${this.serverUrlHash}`, popupFeatures) if (!popup || popup.closed || typeof popup.closed === 'undefined') { diff --git a/src/react/types.ts b/src/react/types.ts index 61934ea..009bb9f 100644 --- a/src/react/types.ts +++ b/src/react/types.ts @@ -30,6 +30,12 @@ export type UseMcpOptions = { transportType?: 'auto' | 'http' | 'sse' /** Prevent automatic authentication popup on initial connection (default: false) */ preventAutoAuth?: boolean + /** + * Callback function that is invoked just before the authentication popup window is opened. + * @param url The URL that will be opened in the popup. + * @param features The features string for the popup window. + */ + onPopupWindow?: (url: string, features: string) => void } export type UseMcpResult = { diff --git a/src/react/useMcp.ts b/src/react/useMcp.ts index f95b4f2..c7239f1 100644 --- a/src/react/useMcp.ts +++ b/src/react/useMcp.ts @@ -47,6 +47,7 @@ export function useMcp(options: UseMcpOptions): UseMcpResult { autoReconnect = DEFAULT_RECONNECT_DELAY, transportType = 'auto', preventAutoAuth = false, + onPopupWindow, } = options const [state, setState] = useState('discovering') @@ -176,6 +177,7 @@ export function useMcp(options: UseMcpOptions): UseMcpResult { clientName, clientUri, callbackUrl, + onPopupWindow, }) addLog('debug', 'BrowserOAuthClientProvider initialized in connect.') } @@ -779,6 +781,7 @@ export function useMcp(options: UseMcpOptions): UseMcpResult { clientName, clientUri, callbackUrl, + onPopupWindow, }) addLog('debug', 'BrowserOAuthClientProvider initialized/updated on mount/option change.') } From ab3831764e600b1dfd3cfdabf12e472a97f8a99f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 24 Jul 2025 07:21:45 +0000 Subject: [PATCH 2/2] feat: Pass window reference to onPopupWindow callback --- README.md | 2 +- src/auth/browser-provider.ts | 11 ++++++----- src/react/types.ts | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bc4aa8e..b247654 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,7 @@ function useMcp(options: UseMcpOptions): UseMcpResult | `autoReconnect` | `boolean \| number` | Auto reconnect if an established connection is lost, with delay in ms (default: 3000) | | `transportType` | `'auto' \| 'http' \| 'sse'` | Transport type preference: 'auto' (HTTP with SSE fallback), 'http' (HTTP only), 'sse' (SSE only) (default: 'auto') | | `preventAutoAuth` | `boolean` | Prevent automatic authentication popup on initial connection (default: false) | -| `onPopupWindow` | `(url: string, features: string) => void` | Callback invoked just before the authentication popup window is opened | +| `onPopupWindow` | `(url: string, features: string, window: Window \| null) => void` | Callback invoked just after the authentication popup window is opened | #### Return Value diff --git a/src/auth/browser-provider.ts b/src/auth/browser-provider.ts index 2690e9a..04c708c 100644 --- a/src/auth/browser-provider.ts +++ b/src/auth/browser-provider.ts @@ -15,7 +15,7 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider { readonly clientName: string readonly clientUri: string readonly callbackUrl: string - readonly onPopupWindow: ((url: string, features: string) => void) | undefined + readonly onPopupWindow: ((url: string, features: string, window: Window | null) => void) | undefined constructor( serverUrl: string, @@ -24,7 +24,7 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider { clientName?: string clientUri?: string callbackUrl?: string - onPopupWindow?: (url: string, features: string) => void + onPopupWindow?: (url: string, features: string, window: Window | null) => void } = {}, ) { this.serverUrl = serverUrl @@ -170,11 +170,12 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider { // Attempt to open the popup const popupFeatures = 'width=600,height=700,resizable=yes,scrollbars=yes,status=yes' // Make configurable if needed try { - // If a callback is provided, invoke it before opening the popup + const popup = window.open(sanitizedAuthUrl, `mcp_auth_${this.serverUrlHash}`, popupFeatures) + + // If a callback is provided, invoke it after opening the popup if (this.onPopupWindow) { - this.onPopupWindow(sanitizedAuthUrl, popupFeatures) + this.onPopupWindow(sanitizedAuthUrl, popupFeatures, popup) } - const popup = window.open(sanitizedAuthUrl, `mcp_auth_${this.serverUrlHash}`, popupFeatures) if (!popup || popup.closed || typeof popup.closed === 'undefined') { console.warn( diff --git a/src/react/types.ts b/src/react/types.ts index 009bb9f..b80df54 100644 --- a/src/react/types.ts +++ b/src/react/types.ts @@ -35,7 +35,7 @@ export type UseMcpOptions = { * @param url The URL that will be opened in the popup. * @param features The features string for the popup window. */ - onPopupWindow?: (url: string, features: string) => void + onPopupWindow?: (url: string, features: string, window: Window | null) => void } export type UseMcpResult = {