From 28b2e652146cdb2ffe4353bf17b67d8f74023177 Mon Sep 17 00:00:00 2001 From: Emilis Baliukonis Date: Fri, 25 Apr 2025 16:46:53 +0300 Subject: [PATCH] Skip auth if there's a valid lockfile and saved tokens --- src/client.ts | 8 +++++--- src/lib/coordination.ts | 4 +++- src/proxy.ts | 7 ++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/client.ts b/src/client.ts index d620884..27c41ef 100644 --- a/src/client.ts +++ b/src/client.ts @@ -28,9 +28,6 @@ async function runClient(serverUrl: string, callbackPort: number, headers: Recor // Get the server URL hash for lockfile operations const serverUrlHash = getServerUrlHash(serverUrl) - // Coordinate authentication with other instances - const { server, waitForAuthCode, skipBrowserAuth } = await coordinateAuth(serverUrlHash, callbackPort, events) - // Create the OAuth client provider const authProvider = new NodeOAuthClientProvider({ serverUrl, @@ -38,6 +35,10 @@ async function runClient(serverUrl: string, callbackPort: number, headers: Recor clientName: 'MCP CLI Client', }) + // Coordinate authentication with other instances + const hasSavedTokens = !!(await authProvider.tokens()) + const { server, waitForAuthCode, skipBrowserAuth } = await coordinateAuth(serverUrlHash, callbackPort, events, hasSavedTokens) + // If auth was completed by another instance, just log that we'll use the auth from disk if (skipBrowserAuth) { log('Authentication was completed by another instance - will use tokens from disk...') @@ -99,6 +100,7 @@ async function runClient(serverUrl: string, callbackPort: number, headers: Recor // Wait for the authorization code from the callback or another instance const code = await waitForAuthCode() + console.log('~~~ CLIENT - AUTH CODE ~~~', code) try { log('Completing authorization...') diff --git a/src/lib/coordination.ts b/src/lib/coordination.ts index ad1d2f6..a38ad35 100644 --- a/src/lib/coordination.ts +++ b/src/lib/coordination.ts @@ -93,12 +93,14 @@ export async function waitForAuthentication(port: number): Promise { * @param serverUrlHash The hash of the server URL * @param callbackPort The port to use for the callback server * @param events The event emitter to use for signaling + * @param hasSavedTokens Whether the client has saved tokens * @returns An object with the server, waitForAuthCode function, and a flag indicating if browser auth can be skipped */ export async function coordinateAuth( serverUrlHash: string, callbackPort: number, events: EventEmitter, + hasSavedTokens: boolean, ): Promise<{ server: Server; waitForAuthCode: () => Promise; skipBrowserAuth: boolean }> { // Check for a lockfile (disabled on Windows for the time being) const lockData = process.platform === 'win32' ? null : await checkLockfile(serverUrlHash) @@ -109,7 +111,7 @@ export async function coordinateAuth( try { // Try to wait for the authentication to complete - const authCompleted = await waitForAuthentication(lockData.port) + const authCompleted = hasSavedTokens || (await waitForAuthentication(lockData.port)) if (authCompleted) { log('Authentication completed by another instance') diff --git a/src/proxy.ts b/src/proxy.ts index 9fd87d1..227b91a 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -25,9 +25,6 @@ async function runProxy(serverUrl: string, callbackPort: number, headers: Record // Get the server URL hash for lockfile operations const serverUrlHash = getServerUrlHash(serverUrl) - // Coordinate authentication with other instances - const { server, waitForAuthCode, skipBrowserAuth } = await coordinateAuth(serverUrlHash, callbackPort, events) - // Create the OAuth client provider const authProvider = new NodeOAuthClientProvider({ serverUrl, @@ -35,6 +32,10 @@ async function runProxy(serverUrl: string, callbackPort: number, headers: Record clientName: 'MCP CLI Proxy', }) + // Coordinate authentication with other instances + const hasSavedTokens = !!(await authProvider.tokens()) + const { server, waitForAuthCode, skipBrowserAuth } = await coordinateAuth(serverUrlHash, callbackPort, events, hasSavedTokens) + // If auth was completed by another instance, just log that we'll use the auth from disk if (skipBrowserAuth) { log('Authentication was completed by another instance - will use tokens from disk')