Skip to content

Allow configurable redirect_uri for MCP OAuth clients #23787

Closed

Description

@tahsinrahman

Problem

opencode currently hardcodes the OAuth callback as http://127.0.0.1:19876/mcp/oauth/callback when connecting to a remote MCP server that requires OAuth. This prevents users from reusing OAuth clients whose redirect URIs are already pinned on the provider side.

Concrete example

The official Claude Code Slack plugin ships a Slack MCP client:

{
  "mcpServers": {
    "slack": {
      "type": "http",
      "url": "https://mcp.slack.com/mcp",
      "oauth": {
        "clientId": "1601185624273.8899143856786",
        "callbackPort": 3118
      }
    }
  }
}

Attempting to reuse the same clientId in opencode produces:

redirect_uri did not match any configured URIs.
Passed URI: http://127.0.0.1:19876/mcp/oauth/callback

In the browser URL: redirect_uri=http%3A%2F%2F127.0.0.1%3A19876%2Fmcp%2Foauth%2Fcallback

The Slack OAuth app has http://127.0.0.1:3118/... registered, so it rejects opencode's callback. The user has no way to override this without registering their own Slack app.

Proposed solution

Make the redirect URI user-configurable alongside clientId:

{
  "mcp": {
    "slack": {
      "type": "remote",
      "url": "https://mcp.slack.com/mcp",
      "oauth": {
        "clientId": "1601185624273.8899143856786",
        "redirectUri": "http://127.0.0.1:3118/mcp/oauth/callback"
      }
    }
  }
}

Implementation note

Configurable output alone isn't enough — opencode must also bind the local callback listener to the host/port/path parsed from redirectUri, otherwise the provider will redirect to a port opencode isn't listening on.

For the common case (http://127.0.0.1:<port>/<path>), this means:

  • Parse host, port, path from redirectUri
  • Bind the OAuth callback HTTP server to that host:port
  • Serve the callback route at that path
  • Send the same URI as redirect_uri in the authorization request

Benefits

  • Enables reuse of OAuth clients pinned to other tools (Claude Code, Cursor, etc.)
  • Lets users put opencode behind a reverse proxy with a stable external callback URL
  • Matches the existing pattern of making clientId configurable

Workarounds today

  1. Register your own app on the provider and use its clientId
  2. Rely on dynamic client registration (RFC 7591) if the MCP server supports it
  3. Use a different transport (e.g., a local stdio MCP server that proxies to the remote)

None of these are viable when the provider has a fixed OAuth app and no DCR support.

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Apr 22, 2026
  2. github-actions commented on Apr 22, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    Additionally, this issue does not follow the Feature Request template — the title should start with [FEATURE]: and should include the required verification checkbox. Please review our contributing guidelines when filing future issues.

    If you believe this was flagged incorrectly, please let a maintainer know.

  3. aommm commented on May 11, 2026

    @aommm

    FWIW, with the latest release of opencode I could add the slack mcp like this:

    "slack": {
          "type": "remote",
          "url": "https://mcp.slack.com/mcp",
          "enabled": true,
          "oauth": {
            "clientId": "1601185624273.8899143856786",
            "redirectUri": "http://localhost:3118/callback"
          }
        }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)needs:complianceThis means the issue will auto-close after 2 hours.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions