You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
V2 MCP OAuth: serialize credential refresh across locations/processes #34520
Tracking the deferred concurrency hardening for V2 MCP OAuth (packages/core/src/mcp). The initial OAuth implementation deliberately ignores cross-location/cross-process credential refresh races; this issue captures that follow-up.
Problem
MCP OAuth tokens are stored in the globalCredential table (credential.ts, makeGlobalNode), while Integration and the MCP service are location-scoped (integration.ts, makeLocationNode). The credential identity for a remote server is keyed by a hash of its (normalized) URL, so two locations using the same server URL share one global credential row.
When that shared token expires, multiple refreshers can run concurrently:
Same process, multiple locations — separate location-scoped MCP/provider instances each decide to refresh the same global row. With rotating refresh tokens, the second refresh invalidates the first, dropping a location into needs_auth.
Separate processes (daemon + CLI, or two servers) — no shared memory, only the shared SQLite DB. Same race, no in-memory coordination available.
Note: V1 had this race too — its file lock only serialized the write, not the decision to refresh.
Proposed direction
In-process: a global single-flight keyed by credential id (in the global tier alongside Credential) so concurrent refreshers coalesce onto one result.
Cross-process: optimistic compare-and-swap on the credential row — refresh inside a transaction, re-read, and if the stored refresh token already changed, adopt the existing fresh token instead of overwriting.
Out of scope
The base OAuth layer (provider, DCR, interactive authorize, connect-time credential read, reconnect-on-auth) ships without this; refresh works fine in the single-location happy path.
The issue does not use one of the three required templates (Bug Report, Feature Request, or Question). Please resubmit using the appropriate template — this appears to be a Bug Report or tracking issue for a known race condition.
Please edit this issue to address the above within 2 hours, or it will be automatically closed.
This issue might be a duplicate of existing issues. Please check:
Partly done: concurrent refreshes in the same process are now shared (#48937, packages/core/src/mcp/oauth.ts), and invalidation only drops the row if it still holds our refresh token. Cross-process serialization is still open in #50994. Closing this in favor of that PR.
Activity
github-actions commentedon Jun 29, 2026
This issue doesn't fully meet our contributing guidelines.
What needs to be fixed:
Please edit this issue to address the above within 2 hours, or it will be automatically closed.
This issue might be a duplicate of existing issues. Please check:
If you believe this was flagged incorrectly, please let a maintainer know.
github-actions commentedon Jun 30, 2026
This issue has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.
Feel free to open a new issue that follows our issue templates.
opencode-agent commentedon Jun 30, 2026
Reopening: this was auto-closed by issue compliance automation, but the author is now exempt under the team/opencode-agent automation guard.
neriousy commentedon Oct 21, 2026
Partly done: concurrent refreshes in the same process are now shared (#48937, packages/core/src/mcp/oauth.ts), and invalidation only drops the row if it still holds our refresh token. Cross-process serialization is still open in #50994. Closing this in favor of that PR.