Skip to content

Conversation

@dcramer
Copy link

@dcramer dcramer commented Dec 19, 2025

This fixes the OAuth flow in WSL2 where 127.0.0.1 inside WSL is not accessible from the Windows host browser. Using localhost enables WSL2's built-in localhost forwarding between Windows and WSL.

🤖 Generated with Claude Code

@dcramer
Copy link
Author

dcramer commented Dec 19, 2025

aside i dont know if localhost causes issues in some scenarios?

will run the generate command and update pr

This fixes the OAuth flow in WSL2 where 127.0.0.1 inside WSL is not
accessible from the Windows host browser. Using localhost enables
WSL2's built-in localhost forwarding between Windows and WSL.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@dcramer dcramer force-pushed the fix/oauth-wsl-localhost branch from e0d1d45 to 99c9dde Compare December 19, 2025 04:34
@dcramer
Copy link
Author

dcramer commented Dec 19, 2025

Likely a path here where I could just detect WSL but it might not be worth it. I think the "theres no dns/localhost" case is probably an outlier. Willing to be convinced, but I'm not sure the complexity of OS detection is worth it if its a 0.001% kind of thing.

example:

diff --git a/packages/opencode/src/mcp/oauth-callback.ts b/packages/opencode/src/mcp/oauth-callback.ts
index c434b21ed..218aa5fec 100644
--- a/packages/opencode/src/mcp/oauth-callback.ts
+++ b/packages/opencode/src/mcp/oauth-callback.ts
@@ -1,5 +1,5 @@
 import { Log } from "../util/log"
-import { OAUTH_CALLBACK_PORT, OAUTH_CALLBACK_PATH } from "./oauth-provider"
+import { OAUTH_CALLBACK_HOST, OAUTH_CALLBACK_PORT, OAUTH_CALLBACK_PATH } from "./oauth-provider"
 
 const log = Log.create({ service: "mcp.oauth-callback" })
 
@@ -161,7 +161,7 @@ export namespace McpOAuthCallback {
   export async function isPortInUse(): Promise<boolean> {
     return new Promise((resolve) => {
       Bun.connect({
-        hostname: "localhost",
+        hostname: OAUTH_CALLBACK_HOST,
         port: OAUTH_CALLBACK_PORT,
         socket: {
           open(socket) {
diff --git a/packages/opencode/src/mcp/oauth-provider.ts b/packages/opencode/src/mcp/oauth-provider.ts
index 3661034cc..9324da977 100644
--- a/packages/opencode/src/mcp/oauth-provider.ts
+++ b/packages/opencode/src/mcp/oauth-provider.ts
@@ -7,9 +7,21 @@ import type {
 } from "@modelcontextprotocol/sdk/shared/auth.js"
 import { McpAuth } from "./auth"
 import { Log } from "../util/log"
+import { release } from "os"
 
 const log = Log.create({ service: "mcp.oauth" })
 
+function getLoopbackHost(): string {
+  // WSL requires localhost for Windows host browser -> WSL callback forwarding
+  // Pattern matches clipboard.ts:32
+  if (release().includes("WSL")) {
+    return "localhost"
+  }
+  // 127.0.0.1 is guaranteed to work without DNS resolution
+  return "127.0.0.1"
+}
+
+const OAUTH_CALLBACK_HOST = getLoopbackHost()
 const OAUTH_CALLBACK_PORT = 19876
 const OAUTH_CALLBACK_PATH = "/mcp/oauth/callback"
 
@@ -32,7 +44,7 @@ export class McpOAuthProvider implements OAuthClientProvider {
   ) {}
 
   get redirectUrl(): string {
-    return `http://localhost:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}`
+    return `http://${OAUTH_CALLBACK_HOST}:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}`
   }
 
   get clientMetadata(): OAuthClientMetadata {
@@ -151,4 +163,4 @@ export class McpOAuthProvider implements OAuthClientProvider {
   }
 }
 
-export { OAUTH_CALLBACK_PORT, OAUTH_CALLBACK_PATH }
+export { OAUTH_CALLBACK_HOST, OAUTH_CALLBACK_PORT, OAUTH_CALLBACK_PATH }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant