diff --git a/src/client.ts b/src/client.ts index d620884..b87a156 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...') diff --git a/src/lib/coordination.ts b/src/lib/coordination.ts index ad1d2f6..da6355e 100644 --- a/src/lib/coordination.ts +++ b/src/lib/coordination.ts @@ -25,13 +25,6 @@ export async function isPidRunning(pid: number): Promise { * @returns True if the lockfile is valid, false otherwise */ export async function isLockValid(lockData: LockfileData): Promise { - // Check if the lockfile is too old (over 30 minutes) - const MAX_LOCK_AGE = 30 * 60 * 1000 // 30 minutes - if (Date.now() - lockData.timestamp > MAX_LOCK_AGE) { - log('Lockfile is too old') - return false - } - // Check if the process is still running if (!(await isPidRunning(lockData.pid))) { log('Process from lockfile is not running') @@ -93,12 +86,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 +104,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')