authServerMetadataUrlでMCPのOAuth検出を指定する — Claude Code
MCPサーバーの標準エンドポイントがエラーになるとき、.mcp.jsonのoauthにauthServerMetadataUrlを書くとOAuth検出の既定の順序を飛ばせます。設定例と効き方、注意点を扱います。
authServerMetadataUrl は、MCPサーバーのOAuth認可サーバーを探す既定の手順を飛ばし、メタデータのURLをClaude Codeに直接渡す設定です。.mcp.json のサーバー定義にある oauth オブジェクトに書きます。サーバー側の標準エンドポイントがエラーを返すときや、検出を社内プロキシ経由にしたいときに使います。
既定ではどの順序でOAuthの接続先を探すか
何も指定しないとき、Claude Codeは次の順で認可サーバーの情報を探します。
- RFC 9728のProtected Resource Metadata(
/.well-known/oauth-protected-resource) - 見つからなければRFC 8414の認可サーバーメタデータ(
/.well-known/oauth-authorization-server)
サーバーが WWW-Authenticate ヘッダーで認可サーバーの場所を示す場合も、同じ自動検出が働きます。ここまでは設定が要りません。
この順序のどこかで詰まると、/mcp から認証を始められません。典型は次の2つです。
- サーバーの
/.well-known側が500系やリダイレクトの連鎖でエラーになる - 認可サーバーが別ホストの社内IdPで、メタデータの入口を管理者が固定している
こうしたとき、検出をやり直す代わりに「ここを見よ」と指定するのが authServerMetadataUrl です。
自動検出が通らないとき、どこから疑うか
- QサーバーのURLと種類(type: http)は合っているか?答えがまず接続自体の設定を直す。OAuthの話はその後
原因は検出より後ろ(クライアント登録、リダイレクトURI、スコープ)にあります。
.mcp.jsonに書く設定
設定の置き場所は、サーバー定義の oauth オブジェクトです。公式ドキュメントの例は次の形です。
{
"mcpServers": {
"my-server": {
"type": "http",
"url": "https://mcp.example.com/mcp",
"oauth": {
"authServerMetadataUrl": "https://auth.example.com/.well-known/openid-configuration"
}
}
}
}URLは https:// で始まるものに限られます。例ではOpenID Connectのディスカバリー文書(openid-configuration)を指していますが、書き方の要点は「認可サーバーのメタデータを返すURLを丸ごと書く」ことです。
設定を入れたら /mcp を開き、該当サーバーの認証をやり直します。
指定する前に、標準エンドポイントの状態を確かめる
「エラーになる」と思い込みで設定を入れると、本当の原因を見逃します。先に2つの /.well-known を叩いて、状態コードを見ます。
for p in oauth-protected-resource oauth-authorization-server; do
printf '%s: ' "$p"
curl -s -o /dev/null -w '%{http_code}\n' \
"https://mcp.example.com/.well-known/$p"
done読み方は次のとおりです。
| 結果 | 意味 | 次の手 |
|---|---|---|
| 1つ目が200 | 意味保護リソースメタデータが生きている | 次の手指定は不要。認可サーバー側の設定を確認 |
| 1つ目が404、2つ目が200 | 意味既定の2段目で見つかる | 次の手指定は不要 |
| どちらも404や5xx | 意味既定の順序では見つからない | 次の手メタデータURLが分かれば authServerMetadataUrl で指定 |
| 200だが中身が想定外 | 意味別の認可サーバーを指している | 次の手正しいメタデータURLを指定 |
メタデータURL自体は、IdPの管理画面か運用担当者に聞くのが確実です。OpenID ConnectのIdPなら、発行者URLの末尾に /.well-known/openid-configuration が付く形が一般的ですが、IdPごとに違うため、必ず curl で中身を確かめてから書きます。
指定すると変わるのは「検出」と「スコープの出どころ」
authServerMetadataUrl の効果は検出先の差し替えだけではありません。公式ドキュメントには、スコープに関する記述が2か所あります。
スコープの決まり方
指定なし(自動検出)
自動で見つけた認可サーバーメタデータの scopes_supported 全体は、要求スコープにしません。
authServerMetadataUrl を指定
指定したURLのメタデータにある scopes_supported が、そのまま要求スコープになります。
つまり、スコープを多く広告するIdPのメタデータを指定すると、既定より広いスコープを要求する可能性があります。最小権限で運用したい場合は、oauth.scopes で要求するスコープを固定します。値は空白区切りの1つの文字列です。
{
"mcpServers": {
"my-server": {
"type": "http",
"url": "https://mcp.example.com/mcp",
"oauth": {
"authServerMetadataUrl": "https://auth.example.com/.well-known/openid-configuration",
"scopes": "channels:read search:read"
}
}
}
}oauth.scopes は authServerMetadataUrl と、サーバーが /.well-known で広告するスコープの両方より優先されます。認可サーバーが offline_access を広告している場合は、リフレッシュのためにこの値が固定スコープへ自動で付け足されます。サインインのたびにブラウザを開かずに済む理由はここにあります。
oauth.scopes を書かなければ、要求するスコープの組はMCPサーバー側が決めます。固定は「承認済みの範囲に絞りたい」ときだけ足す設定で、既定のままで問題なく動いているサーバーに入れる必要はありません。
固定したスコープが足りなくなったとき
固定運用の落とし穴は、あとから別のスコープが必要になる場面です。ツールを呼んだ時点でサーバーが403 insufficient_scope を返すと、呼び出しは needs additional permissions というメッセージで失敗します。メッセージにはサーバーが求めたスコープ名が入り、/mcp ではそのサーバーが「要認証」の表示になります。
ここで /mcp から認証し直すだけでは直りません。Claude Codeが要求するのは、サーバーが名指ししたスコープではなく固定済みの oauth.scopes だからです。足りないスコープを書き足さない限り、再認証で得たトークンにも同じスコープは付きません。
- 1
メッセージのスコープ名を控える
needs additional permissionsに出ているスコープ名を、そのままメモします。 - 2
oauth.scopes に追記する
空白区切りの文字列に足します。例では
"channels:read search:read"にchat:writeを加え、"channels:read search:read chat:write"にします。 - 3
/mcp で認証し直す
該当サーバーを選んで、ブラウザのサインインをやり直します。
追加するスコープは、セキュリティ担当の承認範囲に入っているかを確かめてから書きます。固定の目的が最小権限である以上、エラーに言われるまま足すと意味が薄れます。
一緒に使いがちな設定
authServerMetadataUrl は、同じ oauth オブジェクトの他のキーと組み合わせる場面が多い設定です。
clientIdとcallbackPort: 動的クライアント登録に対応しない認可サーバーでは、事前登録した値が要ります。コールバックポートが埋まっている場合の対処はOAuth callback port is already in useの原因と対処にありますscopes: 上で見たとおり、要求範囲の固定に使います
なお headersHelper で Authorization ヘッダーを出す構成では、サーバーがその資格情報を拒否してもOAuthには切り替わりません。OAuthの検出を整えても効かない構成なので、headersHelperのServer rejectedエラーの原因と区別してください。
指定しても直らないケース
検出の問題ではない失敗に、この設定を足しても結果は変わりません。
- 認可サーバーが要求する
resourceの値とMCPサーバーのURLが食い違う、Entra IDのAADSTS9010010。oauthの設定項目にresourceを上書きするものは載っていません。症状と切り分けはClaude Code MCPでAADSTS9010010が出る原因で扱っています - トークンの有効期限切れで毎日再接続になる症状は、検出ではなく更新の問題です。MCP OAuthが毎日Connection expiredになる原因を参照してください
- 認可サーバーのトークンエンドポイントがプレーンな
http://の場合。資格情報は、HTTPS、またはlocalhost/127.0.0.1/::1のトークンエンドポイントにしか送られず、それ以外ではサインインに失敗します
バージョンの経緯と、再起動後に効かなかった不具合
設定の導入はv2.1.69です。changelogには「標準の検出が失敗するとき、カスタムのメタデータ検出URLを指定できる設定として追加した」と書かれています。
| バージョン | 変更 |
|---|---|
| v2.1.69 | 変更oauth.authServerMetadataUrl を追加 |
| v2.1.85 | 変更RFC 9728のProtected Resource Metadataによる検出に対応 |
| v2.1.97 | 変更再起動後のトークンリフレッシュで設定が無視される不具合を修正 |
| v2.1.98 | 変更同じ不具合の修正が重ねて記載 |
v2.1.97と98の修正は、ADFSのような外部IdPで影響が出ていたものです。「指定したのに再起動すると効かない」場合は、まず claude --version でバージョンを確認します。
claude --version
claude mcp get my-serverclaude mcp get <名前> は、サーバーにOAuthの資格情報が設定されているかを確かめるコマンドです。経緯の全体像はリモートMCPのOAuth認証にあり、claude mcp add を含む設定全般はClaude Code MCP設定ガイドが扱っています。
運用で迷いやすい点
指定は.mcp.jsonに書いて共有できるか
設定はサーバー定義の一部なので、プロジェクトスコープの .mcp.json に書けばチームで共有できます。URLは認可サーバーの公開メタデータで、秘密情報ではありません。クライアントシークレットは別扱いで、--client-secret で追加時にだけ渡し、システムのキーチェーンか認証情報ファイルに保存されます。
社内プロキシ経由にしたいときは
公式の説明では、検出を社内プロキシ経由にしたい場合も用途に挙がっています。プロキシ側でメタデータを返すURLを用意し、そのURLを書く形になります。なお、認可応答が想定外の発行者を名乗るサインインは失敗する仕様なので、プロキシが返すメタデータは実際の認可サーバーの内容と整合させておく必要があります。
指定をやめるには
authServerMetadataUrl の行を消せば、既定の検出に戻ります。