Skip to content

MCP OAuth: opencode mcp auth re-registers a new dynamic client every run instead of reusing the stored registration #35625

Description

@verkadabambam

Summary

opencode mcp auth <server> registers a brand-new dynamic OAuth client (RFC 7591) on every invocation — producing a new client_id and a full interactive browser consent each time — instead of reusing the client registration already stored in mcp-auth.json. This happens even when a valid stored registration and a valid refresh token exist.

Environment

  • opencode 1.17.14

Root cause

startAuth() in packages/opencode/src/mcp/index.ts constructs a McpOAuthPendingProvider. Its clientInformation() (in packages/opencode/src/mcp/oauth-provider.ts) returns only the in-memory pendingClientInfo (which is undefined at the start of a run) and never falls back to the persisted clientInfo on disk — unlike the base McpOAuthProvider.clientInformation(), which reads it via getForUrl(...). Its tokens() is the same (returns in-memory pendingTokens only).

The MCP SDK's auth() / authInternal() registers a new client whenever provider.clientInformation() returns undefined (before it would ever attempt a refresh). So every mcp auth run dynamic-registers a fresh client.

Evidence

Server-side logs show a fresh POST /register (new client_id) followed by a full /authorize + consent + callback on every opencode mcp auth run, rather than a bare refresh_token grant against the existing client.

Impact

Suggested fix

Have McpOAuthPendingProvider.clientInformation() / tokens() fall back to the persisted values on disk (or seed the pending provider from stored state), so re-authentication reuses the existing registration and can refresh instead of re-registering.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions