From cfcdb47c765668daf4fab77b72f2667601b6565e Mon Sep 17 00:00:00 2001 From: hchangjae Date: Mon, 20 Apr 2026 23:25:04 +0900 Subject: [PATCH] fix(mcp): stop OAuth callback server after authentication completes --- packages/opencode/src/mcp/index.ts | 5 ++++- packages/opencode/src/mcp/oauth-callback.ts | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts index 09fcfc756a16..ad9337b10ed8 100644 --- a/packages/opencode/src/mcp/index.ts +++ b/packages/opencode/src/mcp/index.ts @@ -839,10 +839,13 @@ export const layer = Layer.effect( const storedState = yield* auth.getOAuthState(mcpName) if (storedState !== result.oauthState) { yield* auth.clearOAuthState(mcpName) + yield* Effect.tryPromise(() => McpOAuthCallback.stopIfIdle()).pipe(Effect.ignore) throw new Error("OAuth state mismatch - potential CSRF attack") } yield* auth.clearOAuthState(mcpName) - return yield* finishAuth(mcpName, code) + const status = yield* finishAuth(mcpName, code) + yield* Effect.tryPromise(() => McpOAuthCallback.stopIfIdle()).pipe(Effect.ignore) + return status }) const finishAuth = Effect.fn("MCP.finishAuth")(function* (mcpName: string, authorizationCode: string) { diff --git a/packages/opencode/src/mcp/oauth-callback.ts b/packages/opencode/src/mcp/oauth-callback.ts index fbb43d39216b..08764f30c65f 100644 --- a/packages/opencode/src/mcp/oauth-callback.ts +++ b/packages/opencode/src/mcp/oauth-callback.ts @@ -225,6 +225,12 @@ export async function stop(): Promise { mcpNameToState.clear() } +export async function stopIfIdle(): Promise { + if (pendingAuths.size === 0) { + await stop() + } +} + export function isRunning(): boolean { return server !== undefined }