MCP endpoint URL の query パラメータはクライアントのサーバー同一性と OAuth resource を変える
MCP
OAuth
設計判断
知識
判断
Remote MCP の接続オプションを接続 URL の query パラメータで渡す方式には、OAuth との相互作用による落とし穴がある。MCP クライアント(Codex CLI 等)は設定された URL 全体をサーバーの識別子として扱うため、query を追加・変更しただけで別サーバー扱いになり、取得済みの token / grant が引き継がれない。さらに OAuth の resource 概念とズレる: サーバーが protected resource metadata で広告する resource は通常 query なしの endpoint URL なので、クライアントが「自分の接続先 URL」と「metadata の resource」を突き合わせる実装だと不一致になり、認可フローや grant 解決が失敗しうる(invalid_grant 系のエラーとして現れる)。
症状の見え方
- query なしでは接続できていたクライアントが、query を付けた途端 handshake で失敗する。
- エラーはクライアント側では grant が見つからない旨、サーバー側では汎用の JSON-RPC エラーとして現れ、query パラメータの値自体の妥当性とは無関係に起きるため原因が特定しにくい。
判断基準
- query でオプションを渡す設計を採用するなら、「URL 変更=再認可が走る」ことを前提に、handshake が外部依存なしで成功し、未認証・無効トークンは 401 challenge で再認可に誘導される経路を必須条件にする。これが満たされれば query 変更後もクライアントは自然に再ログインして回復できる。
- クライアントの well-known 探索は query を運ばない(well-known パス導出で query は落ちる)ため、query 付き URL を resource identifier にする設計は成立しない。resource は query なしで固定し、query はあくまで非秘密の接続オプションに限定する。
- 対象スコープの指定手段として path・query・tool 引数を比較する際、query の評価軸に「OAuth のサーバー同一性を変える」コストを含める。頻繁に切り替える値なら tool 引数側に寄せる方が認可の再実行を避けられる。
検証
実クライアントで「query なしで認可済み → query を追加して再接続」の順を再現し、再認可プロンプトが出て完了後に接続できるか、それとも handshake で死ぬかを確認する。サーバーのログだけでなくクライアント側のエラー文言(grant 不在・Bad request)も突き合わせる。