Skip to content

Commit e4d8b22

Browse files
committed
fix(mcp): stop OAuth callback server after authentication completes
1 parent ae7a351 commit e4d8b22

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

packages/opencode/src/mcp/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,10 +839,13 @@ export const layer = Layer.effect(
839839
const storedState = yield* auth.getOAuthState(mcpName)
840840
if (storedState !== result.oauthState) {
841841
yield* auth.clearOAuthState(mcpName)
842+
yield* Effect.promise(() => McpOAuthCallback.stopIfIdle())
842843
throw new Error("OAuth state mismatch - potential CSRF attack")
843844
}
844845
yield* auth.clearOAuthState(mcpName)
845-
return yield* finishAuth(mcpName, code)
846+
const status = yield* finishAuth(mcpName, code)
847+
yield* Effect.promise(() => McpOAuthCallback.stopIfIdle())
848+
return status
846849
})
847850

848851
const finishAuth = Effect.fn("MCP.finishAuth")(function* (mcpName: string, authorizationCode: string) {

packages/opencode/src/mcp/oauth-callback.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,18 @@ export async function stop(): Promise<void> {
225225
mcpNameToState.clear()
226226
}
227227

228+
export async function stopIfIdle(): Promise<void> {
229+
if (pendingAuths.size === 0) {
230+
await stop()
231+
}
232+
}
233+
234+
export async function stopIfIdle(): Promise<void> {
235+
if (pendingAuths.size === 0) {
236+
await stop()
237+
}
238+
}
239+
228240
export function isRunning(): boolean {
229241
return server !== undefined
230242
}

0 commit comments

Comments
 (0)