目的
ブラウザで認可を完了し、新しいトークンが保存されているのに、起動中の中継プログラムが Authentication required を返し続ける再認証ループを解消する。ブラウザの完了表示も実際のトークン交換・保存の結果を反映させる。
前提と観測
2026-08-21 の報告・確認は本Issueのコメントに残っている。2026-09-30にも同じ症状が再発した。
- 実行中の npm パッケージは github-rag-mcp 0.11.0。中継のOAuth処理はリポジトリの
mcp-server/server/index.js と同じ構造。
- ブラウザは localhost callback で
Authorization successful を表示するが、現在のコードはtoken endpointへの交換・保存より先にこのレスポンスを送る。
- 実際に認可後の
oauth-tokens.json は更新され、その保存済みトークンを新しいremote clientで使った検索は成功(isError=false、count=1)。既存MCPプロセスの検索はその直前に Authentication required を返した。
getAccessToken() はメモリキャッシュが falsy の時だけファイルを読む。refresh失敗後も古いキャッシュを保持し、performOAuthFlow() が2〜3秒でpendingエラーを返すと代入は行われない。
- callback完了時に保存してpendingをnullにしても、メモリキャッシュの古い値を更新する経路がない。このため次の呼び出しが新しい認可を始める。
- 同じホームの複数プロセスが同じtoken/client registrationファイルを共有している。別プロセスで更新された有効なトークンを古いメモリ値で覆い隠してはならない。
根拠: mcp-server/server/index.js の startOAuthFlow / performOAuthFlow / getAccessToken / onUnauthorized、本Issueの2026-08-21コメント、2026-09-30の保存済みトークンによる実検索。
要求と制約
- 認可完了後の次のMCP呼び出しは保存された新しいトークンを利用し、同じ理由で再びブラウザを開かない。
- refresh失敗や401で無効と判明したトークンを、キャッシュまたはディスクからそのまま再採用し続けない。
- 有効な既存トークンは引き続き利用できる。別プロセスによる更新も取り込める。
- pendingのタイムアウト、失敗、完了を呼び出し側へ安全に伝え、処理が停止したり未処理Promise rejectionを起こしたりしない。
- ブラウザの成功表示はtoken交換と保存成功後に出す。交換や保存の失敗は成功表示にしない。
- トークン、OAuth code/state/verifier、secret入りURLをログ、Issue、PR、テスト結果に出さない。
- MCPのstdio/HTTPプロトコル、検索の意味、既存のユーザー設定を維持する。原因が未確定のApp切替やissuer不一致を今回の原因と断定しない。
- 公開リリース・バージョン変更はこの修正のマージとは別の人間確認。今回の実機には検証済み修正版を可逆的に適用して検索復旧を確認する。
検証
古いキャッシュ・refresh失敗・遅れて完了する認可の組み合わせを再現し、完了後の再呼び出しが新しいトークンを利用する回帰テスト。別プロセスによるファイル更新、401後の無効トークン再読込、交換/保存失敗とブラウザ表示も検証する。テストでは実在する認証情報を使わない。
対象ファイル
mcp-server/server/index.js、必要なOAuth処理モジュール
mcp-server/test/ とテスト実行設定
- 動作仕様を所有する該当ドキュメント
関連
#176 はランダムなcallback portとclient registrationの修理。本Issueは完了後のtoken/cache状態を扱う。
目的
ブラウザで認可を完了し、新しいトークンが保存されているのに、起動中の中継プログラムが
Authentication requiredを返し続ける再認証ループを解消する。ブラウザの完了表示も実際のトークン交換・保存の結果を反映させる。前提と観測
2026-08-21 の報告・確認は本Issueのコメントに残っている。2026-09-30にも同じ症状が再発した。
mcp-server/server/index.jsと同じ構造。Authorization successfulを表示するが、現在のコードはtoken endpointへの交換・保存より先にこのレスポンスを送る。oauth-tokens.jsonは更新され、その保存済みトークンを新しいremote clientで使った検索は成功(isError=false、count=1)。既存MCPプロセスの検索はその直前にAuthentication requiredを返した。getAccessToken()はメモリキャッシュが falsy の時だけファイルを読む。refresh失敗後も古いキャッシュを保持し、performOAuthFlow()が2〜3秒でpendingエラーを返すと代入は行われない。根拠:
mcp-server/server/index.jsのstartOAuthFlow/performOAuthFlow/getAccessToken/onUnauthorized、本Issueの2026-08-21コメント、2026-09-30の保存済みトークンによる実検索。要求と制約
検証
古いキャッシュ・refresh失敗・遅れて完了する認可の組み合わせを再現し、完了後の再呼び出しが新しいトークンを利用する回帰テスト。別プロセスによるファイル更新、401後の無効トークン再読込、交換/保存失敗とブラウザ表示も検証する。テストでは実在する認証情報を使わない。
対象ファイル
mcp-server/server/index.js、必要なOAuth処理モジュールmcp-server/test/とテスト実行設定関連
#176 はランダムなcallback portとclient registrationの修理。本Issueは完了後のtoken/cache状態を扱う。