目的
MCP server 起動時に WebSocket 接続と最初のツール呼び出しが同時に refreshAccessToken() を呼ぶ競合状態を修正する。
前提
CHANNEL_ENABLED 時、プロセス起動でキャッシュ済みトークンを読み込み、WebSocket を即座に開始する
- WebSocket の
connectWebSocket() → getAccessToken() と、最初のツール呼び出しの callRemoteTool() → getAccessToken() がほぼ同時に実行される
- 両方が同じ期限切れ refresh token (R1) で Worker の
/oauth/token に同時リクエストを送る
- Worker は両方を受け付け(previous token サポート)、それぞれ別の新 refresh token (R2, R3) を発行
oauth-tokens.json への書き込み順は非決定的。KV の current token と一致しないトークンがファイルに残る可能性がある
- 次回セッション起動時にファイルの孤児 refresh token でリフレッシュ失敗 → ブラウザ再認証要求
制約
@cloudflare/workers-oauth-provider の KV grant は current + previous の2世代のみ保持
- 同時リフレッシュの3つ目以降のトークンは KV から参照不能になる
saveTokens() の concurrent write は Windows でファイル破損のリスクもある
対象ファイル
mcp-server/server/index.js: getAccessToken() に _refreshLock プロミスを追加して同時リフレッシュを直列化
目的
MCP server 起動時に WebSocket 接続と最初のツール呼び出しが同時に
refreshAccessToken()を呼ぶ競合状態を修正する。前提
CHANNEL_ENABLED時、プロセス起動でキャッシュ済みトークンを読み込み、WebSocket を即座に開始するconnectWebSocket()→getAccessToken()と、最初のツール呼び出しのcallRemoteTool()→getAccessToken()がほぼ同時に実行される/oauth/tokenに同時リクエストを送るoauth-tokens.jsonへの書き込み順は非決定的。KV の current token と一致しないトークンがファイルに残る可能性がある制約
@cloudflare/workers-oauth-providerの KV grant は current + previous の2世代のみ保持saveTokens()の concurrent write は Windows でファイル破損のリスクもある対象ファイル
mcp-server/server/index.js:getAccessToken()に_refreshLockプロミスを追加して同時リフレッシュを直列化