Claude Media
リモートMCPのOAuth認証 — 401起点の流れとClaude CodeのCIMD対応

リモートMCPのOAuth認証 — 401起点の流れとClaude CodeのCIMD対応

リモートMCPのOAuth認証を、401応答から認可サーバー発見、CIMD(Client ID Metadata Documents)での登録、PKCE付きトークン取得まで追います。Claude Codeでの挙動も扱います。

リモートMCPサーバーに接続するとき、Claude CodeはAPIキーではなくOAuth 2.1ベースの認可フローでアクセストークンを取得します。トークンなしでリクエストを送ると401が返り、そこから認可サーバーを見つけ、クライアントとして登録し、PKCE(Proof Key for Code Exchange、認可コード横取り対策)付きの認可コードを交換してようやくトークンにたどり着く手順です。MCPの認可仕様は2026-07-28版で改訂されました。Dynamic Client Registration(DCR)を非推奨にし、Client ID Metadata Documents(CIMD)へ主軸を移す変更です。仕様のRFCレベルの中身と、Claude Codeが2025年6月の初対応からどう実装を積み重ねてきたかをまとめます。

なぜリモートMCPにAPIキーでなくOAuthが必要なのか

MCPのトランスポートはstdioとStreamable HTTPが主流で、認可の要不要はここで分かれます。stdio接続はクライアントがサーバーをローカルの子プロセスとして起動するため、ネットワークを介さず環境変数でクレデンシャルを渡せば足ります。MCP仕様自身も、stdioトランスポートの実装には認可フローを適用しないよう求める立場です。

一方Streamable HTTPで接続するリモートサーバーは、クライアントとサーバーが初対面であることが前提です。GitHubやSentry、Slackのようなリモートサーバーは不特定多数のクライアントから接続され、あらかじめクライアントIDを交換しておく関係が成立しません。「初対面の相手にどうやって安全にトークンを渡すか」が、リモートMCPの認可仕様が解く課題です。人間が都度ログインしない連携にはMCPのOAuth Client Credentials拡張 — 人間不在の認証という別の答えもあります。

仕様はOAuth 2.1をベースにしています。保護リソースメタデータ(RFC9728)・認可サーバーメタデータ(RFC8414)・PKCE・Resource Indicators(RFC8707)を組み合わせた答えです。Claude.ai・Claude Desktop・Claude Codeの3面での対応表はMCPとはにまとめてあります。本記事はそのうち、リモートサーバーとのOAuth認可フローの仕組み自体に絞ります。

MCPで401が返るとどうなるか — 認可フローの7段階

リモートMCPの認可フローは、401応答をきっかけに次の7段階で進みます。各段階が異なるRFCに対応しており、どれか1つでも欠けると接続できません。

手順

401からトークン取得までの7段階

  1. 1

    未認証リクエストと401応答

    クライアントがトークンなしでMCPサーバーへリクエストを送ると、サーバーは401 Unauthorizedを返します。WWW-Authenticateヘッダーには保護リソースメタデータのURLが載ります。

  2. 2

    保護リソースメタデータの取得(RFC9728)

    ヘッダーのresource_metadataが示すURL、無ければ/.well-known/oauth-protected-resourceを叩きます。authorization_serversフィールドが認可サーバーの手がかりです。

  3. 3

    認可サーバーメタデータの発見(RFC8414 / OIDC)

    /.well-known/oauth-authorization-serverと/.well-known/openid-configurationを優先順位付きで試します。メタデータのissuer値が問い合わせ先URLと一致しなければ、そのメタデータは使いません。

  4. 4

    クライアント登録

    Client ID Metadata Documents・事前登録・Dynamic Client Registrationの3方式から選びます。詳しくは次の節です。

  5. 5

    PKCEとresourceパラメータ付きの認可リクエスト

    クライアントはcode_challengeを生成し、接続先MCPサーバーの正規URIをresourceパラメータとして認可リクエストとトークンリクエストの両方に含めます(RFC8707)。ブラウザでユーザーが認可すると、認可サーバーはコールバックへ認可コードとiss(発行者識別子)を返します。

  6. 6

    iss検証とトークン交換

    クライアントは事前に記録した発行者識別子とissを突き合わせ、一致しなければコードをトークンエンドポイントへ渡しません(RFC9207)。一致すればcode_verifierとresourceを添えてトークンを要求します。

  7. 7

    Bearerトークンでのリクエスト

    以降のMCPリクエストにはAuthorization: Bearer <token>ヘッダーを毎回付けます。トークンをURLのクエリ文字列に含めることは、仕様で禁止されています。

クライアント登録の3方式とDCR非推奨

クライアントは認可リクエストを送る前に、認可サーバーへ自分の身元を示すクライアントIDを持っている必要があります。仕様は3つの登録方式と優先順位を定義しています。

方式事前関係仕組み
事前登録事前関係必要仕組み固定のclient_id / client_secretをハードコードするか、UIで入力する
Client ID Metadata Documents(CIMD)事前関係不要仕組みhttpsのURLをclient_idとして使い、認可サーバーがそのURLからJSONメタデータを取得・検証する
Dynamic Client Registration(DCR)事前関係不要仕組みPOST /registerでクライアント情報を送信し、認可サーバーがclient_idを発行する

優先順位は「事前登録済みなら事前登録 → 認可サーバーがCIMDに対応していればCIMD → DCRに対応していればDCR → どれも無ければユーザーに手入力させる」の順です。2026-07-28版の仕様は、DCR(RFC7591)をクライアント登録メカニズムとして非推奨にしました。CIMDに対応していない認可サーバーとの後方互換にのみ残す位置づけです。廃止までの猶予期間は12か月以上あり、既存のDCR対応サーバーがすぐ動かなくなるわけではありません。

CIMDが解決するのは、DCRの構造的な弱点です。DCRで発行されたクライアントIDは、発行した認可サーバーに紐づきます。仕様は「クライアント認証情報は発行元の認可サーバーのissuer識別子で管理し、認可サーバーが変わったら再登録が必要」と定めており、サーバーを乗り換えるたびに登録し直す手間が生じます。CIMDのクライアントIDは自分がホストするHTTPS URLそのものなので、認可サーバーが変わってもURLは変わらず、再登録が不要です。

Claude CodeがCIMDに対応したのはv2.1.81(2026年3月)で、DCR非対応サーバーへの主要な回避策として実装されました。DCRにもCIMDにも対応していないサーバーでは、開発者ポータルで事前にOAuthアプリを登録し、発行された認証情報を渡します。

# 事前登録した client_id / client_secret でリモートサーバーを追加
claude mcp add --transport http \
  --client-id your-client-id --client-secret --callback-port 8080 \
  my-server https://mcp.example.com/mcp

CIMDとは何か — Claude Codeでの使われ方

CIMD(Client ID Metadata Documents)は、クライアントIDを自分がホストするHTTPS URLにする登録方式です。認可サーバーはそのURLを取りに行き、返ってきたJSONでクライアントの身元を確かめます。

Claude CodeはDCRに頼れないサーバーで、CIMDを自動で見つけて使います。利用者が設定するものはありません。DCRにもCIMDにも対応しない場合だけ、事前登録の認証情報が要ります。

仕様が求める条件は次のとおりです。

  • クライアントIDのURLはhttpsで、パス部分を含む(例: https://example.com/client.json)
  • そのURLが返すJSONに、client_id・client_name・redirect_urisを含める
  • 認可サーバーは、メタデータのclient_id_metadata_document_supportedをtrueにして対応を宣言する

クライアントは、この宣言を見てCIMDを選びます。サーバーがCIMD対応かどうかは、認可サーバーメタデータを取得すると確かめられます。

curl -s https://auth.example.com/.well-known/oauth-authorization-server \
  | grep client_id_metadata_document_supported

trueが返れば、Claude Codeは追加の設定なしでCIMDを使います。項目自体が無いサーバーは、DCRか事前登録で接続することになります。

スコープの決め方と追加認可(step-up)の流れ

MCPクライアントは、必要最小限のスコープだけを要求する原則(least privilege)に従います。優先順位は明確です。まず401応答のWWW-Authenticateヘッダーにあるscopeパラメータを使い、それが無ければ保護リソースメタデータのscopes_supported全体を使います。

Claude Codeはこの原則をv2.1.196(2026年6月)で仕様どおりに徹底しました。それ以前は、自動発見した認可サーバーメタデータのscopes_supportedカタログを丸ごと要求していました。その結果、GitLab self-hosted等の一部のエンタープライズIdPで問題が起きていました。MCPのEnterprise Authorization拡張 — IdPで一元管理する仕組みも参考になります。管理者専用やテンプレート用のスコープまで宣伝するID基盤が、invalid_scopeエラーで認可リクエストを拒否していたのです。現在はWWW-Authenticateか保護リソースメタデータが示す範囲だけを要求し、どちらも無ければscopeパラメータ自体を送りません。

組織のセキュリティ方針でスコープをさらに絞りたい場合は、.mcp.jsonのoauth.scopesにスペース区切りの文字列を設定します。認可サーバーがより広いスコープを宣伝していても、要求範囲をその設定に固定できるからです。認可サーバーがoffline_accessをscopes_supportedに含めている場合、Claude Codeはこれを自動で追加します。ブラウザでの再ログインなしにトークンを更新するための措置です。

実行中のツール呼び出しが403 insufficient_scopeで拒否されると、クライアントは不足分のスコープを既存のスコープと合わせて要求し直します。これがstep-up認可フローです。仕様は「前回までに要求したスコープと、今回のエラーが示すスコープの和集合を取る」ことを求めており、再認可のたびに以前の権限が失われないようにする設計です。Claude Codeも、固定したoauth.scopesの範囲内でこの再認可を行います。

Claude CodeでリモートMCPを認証する手順

OAuth対応のリモートサーバーは、追加してからセッション内で/mcpを実行し、ブラウザでログインするだけで接続が完了します。取得したトークンは安全に保存され、期限が切れると自動で更新されます。RailwayのMCPサーバーもこの方式で、接続手順はRailwayのMCPサーバーが扱います。

claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
/mcp

セッションを開かずに認証したい場合は、claude mcp login <name>がシェルから直接OAuthフローを実行します(v2.1.186から)。SSHセッションやディスプレイの無いLinux環境ではローカルブラウザが検出できないため、認可URLをそのまま表示するモードに自動で切り替わります(v2.1.191)。--no-browserを付けると、ブラウザがある環境でも強制的にこのモードにできます。

claude mcp login sentry --no-browser

--callback-portは特定のリダイレクトURIをあらかじめ登録しているサーバー向けに、コールバックポートを固定するオプションで、既定ではポートはランダムに選ばれます。一方、.mcp.jsonでheaders.Authorizationを設定したサーバーがそのヘッダーを拒否した場合、Claude CodeはOAuthへフォールバックせず、接続失敗として報告します。トークンの有効性を確認するか、OAuthを使うならヘッダー設定を外します。

非対話モード(claude -pやAgent SDK実行)には/mcpパネルが無いため、Claude Code自身が認可フローを代行できません。v2.1.196からは、ツール検索が有効な状態で未認証のサーバーがあると、Claudeにそのサーバーのツールが使えないことを伝えるようになりました。設定が読めていないかのように振る舞う代わりに、どのサーバーへのサインインが必要かを名指しできます。サインイン自体は対話セッションの/mcpかclaude mcp loginで完了させます。

Claude Codeにclaude.aiのサブスクリプションでログインしていれば、claude.aiで追加して認証済みのコネクタ(Google Drive・GitHub・Slack等)は自動的に使えます。APIキーやapiKeyHelper、Bedrockなどのサードパーティプロバイダー、claude setup-tokenで得たCLAUDE_CODE_OAUTH_TOKENが有効なときは読み込まれません。ただしMicrosoft 365・Gmail・Google Calendarは例外です。アップストリームのIDプロバイダーがclaude.aiの登録済みリダイレクトURLしか受け付けないため、Claude Codeからのローカル認証には対応していません。

これらのホストを指すサーバーにサインインすると、is Anthropic-hosted and doesn't support local OAuthと表示されます。先にclaude mcp remove <name>で自分の登録を外し、claude.aiのコネクタ画面(claude.ai/customize/connectors)で接続します。外さないと、同じURLのコネクタが隠れたままになります。

v2.1.287のclaude mcpで確認できるOAuth関連オプション

手元のv2.1.287で、サブコマンドのヘルプだけを実行して確認しました。ログインやサーバー追加は行っていません。

claude mcp login --help
Usage: claude mcp login [options] <name>
 
Authenticate with an MCP server (HTTP, SSE, or claude.ai connector)
 
Options:
  -h, --help    Display help for command
  --no-browser  Print the authorization URL instead of opening a browser (for
                SSH/headless sessions — paste the redirect URL back when
                prompted)

対象に「claude.ai connector」が入っている点に注目できます。claude mcp add側のヘルプでは、OAuthに関わるオプションは次の3つです。

  --callback-port <port>       Fixed port for OAuth callback (for servers
                               requiring pre-registered redirect URIs)
  --client-id <clientId>       OAuth client ID for HTTP/SSE servers
  --client-secret              Prompt for OAuth client secret (or set
                               MCP_CLIENT_SECRET env var)
  -t, --transport <transport>  Transport type (stdio, sse, http). Defaults to
                               stdio if not specified.

--transportが受け付けるのはstdio・sse・httpの3種類で、WebSocketはありません。--client-idの説明は「HTTP/SSEサーバー向け」です。シークレットは引数に直接書かず、プロンプトか環境変数MCP_CLIENT_SECRETで渡す作りになっています。保存済みの認証情報を消すclaude mcp logout <name>も同じ階層にあります。ヘルプの説明は「Clear stored OAuth credentials for an MCP server」です。

Claude CodeのOAuth対応はどこまで自動化されたか

Claude Codeのリモートサーバー対応は2025年6月のOAuth初対応から始まり、1年強かけて仕様の主要な要素を取り込んできました。

あゆみ

Claude CodeのリモートMCP OAuth対応の積み上がり

  1. 2025年6月v1.0.27 リモートMCPサーバー(SSE・HTTP)がOAuthに対応
  2. 2025年6月v1.0.35 認可サーバーの自動発見に対応
  3. 2026年2月v2.1.30 事前設定クレデンシャル(--client-id / --client-secret)を追加

    DCR非対応サーバー向けです。

  4. 2026年2月v2.1.49 step-up認可とディスカバリーキャッシュに対応
  5. 2026年2月v2.1.63 コールバック失敗時にURLを手動で貼り付けるフォールバックを追加
  6. 2026年3月v2.1.69 authServerMetadataUrl でメタデータ発見を上書き可能に
  7. 2026年3月v2.1.81 Client ID Metadata Document(CIMD)に対応
  8. 2026年3月v2.1.85 RFC9728の保護リソースメタデータでの発見に対応

    RFC9728を優先し、RFC8414へフォールバックする発見チェーンが揃いました。

  9. 2026年6月v2.1.186 claude mcp login でシェルから直接OAuthを実行可能に
  10. 2026年6月v2.1.196 scopes_supported の丸ごと要求をやめ、invalid_scope を回避
  11. 2026年7月v2.1.206 一過性のトークン更新エラーで再認証扱いにしない修正

    以前はセッションの終わりまで、認証が必要なサーバーとして扱われていました。

CIMDへの対応は2026年3月、スコープ要求の見直しは6月で、仕様の変化に実装が少し遅れて追いかける形です。ADFSやGitLab self-hostedのようなエンタープライズIdP向けの修正は、v2.1.97やv2.1.196のように後から入っています。

エンタープライズ環境でよくあるつまずき

認可サーバーが企業の内製IDプロバイダーだと、公開SaaS向けの実装では想定していない挙動に当たりやすくなります。まず、Claude Codeがどの応答を「サインインが必要」と見なすかを分けておくと切り分けが早くなります。

くらべる

401・403を受けたときの扱いの違い

/mcp に出る

OAuthの入口に案内される

未サインインのサーバーは、401でも403でも/mcpに「認証が必要」として並びます。サインイン済みのサーバーが401を返したときは、保存済みトークンを更新して一度だけ再試行し、それも失敗した場合にだけ並びます。

OAuthに進まない

接続失敗として報告される

headersやheadersHelperでAuthorizationを自分で設定したサーバーは、401や403でも認証待ちにはなりません。接続失敗として扱われ、直すのは設定した側の資格情報です。ヘルパーの場合のエラー文と切り分けはheadersHelperのServer rejectedエラーにあります。

claude.aiコネクタには例外が2つあります。claude.ai側がセッションのトークンを拒否した401では、認証待ちになりません。クラウドセッションに届いたコネクタの再認可は、claude.ai側で行います。

症状ごとの原因と対処は次のとおりです。

  • 「Incompatible auth server: does not support dynamic client registration」: 認可サーバーがCIMDにもDCRにも対応していません。開発者ポータルで事前にOAuthアプリを登録し、--client-idと--client-secret、登録済みリダイレクトURIと一致する--callback-portを指定して追加し直します
  • invalid_scopeで認可リクエストが拒否される: 認可サーバーが管理者専用スコープまでscopes_supportedに宣伝しているケースで、v2.1.195以前ではその全体を要求してしまっていました。v2.1.196以降なら、自動発見したメタデータからは要求しません
  • リダイレクトURIの不一致で拒否される: v2.1.229だけ、コールバックをhttp://127.0.0.1:PORT/callbackで送っていました。リダイレクトURIを完全一致で照合するサーバーはこれを弾き、v2.1.231でlocalhostの形に戻っています
  • OAuth callback port <port> is already in useで始まる失敗: --callback-portや環境変数MCP_OAUTH_CALLBACK_PORTでポートを固定していると起きやすくなります。メッセージ中のlsof -ti:<port> -sTCP:LISTENで占有プロセスを探せます。Windowsではnetstat -ano | findstr :<port>が案内されます
  • No available ports for OAuth redirect: ローカルの127.0.0.1でリッスンできないときの失敗です。セキュリティソフトやサンドボックスの方針が原因になり得ます。v2.1.268より前は、OSに任せたポートへのフォールバックが無く、WindowsでHyper-Vが予約したポート範囲に当たった場合にも出ることがありました
  • authServerMetadataUrlを設定したのに再起動後に効いていない: v2.1.97 / v2.1.98で修正された、トークン更新時に設定が読み込まれない不具合です。ADFSのような独自のディスカバリー経路を持つIdPで顕在化していました。設定の書き方と効き方はauthServerMetadataUrlでMCPのOAuth検出を指定する手順にあります
  • 複数のOAuth対応MCPサーバーを使うとキーチェーンが壊れる(macOS): 大きなOAuthメタデータがsecurityコマンドの標準入力バッファを超え、認証情報が破損する不具合でした。他にもキーチェーンの競合や読み取りタイムアウトの修正が複数バージョンに分かれて入っています
  • リフレッシュトークンが拒否された: 通知で/mcpが案内されるので、サーバーを選んでRe-authenticateを実行します。ツール呼び出しの途中で切れたときは、MCP server "<name>" needs you to sign in again (run /mcp to re-authenticate)が出ます

v2.1.193以降は、認証が必要な設定済みサーバーがあると起動時に通知が出ます。通知は各サーバーにつき1回で、/mcpには認証待ちのサーバーが全部並びます。

よくある質問

すべてのトランスポートでOAuthが使えるか

使えません。OAuthに対応するのはStreamable HTTP(と後方互換のSSE)だけです。サーバーからClaudeへ予告なくイベントを送るWebSocketトランスポートは、双方向の常時接続という性質上、OAuthもclaude mcp add --transportフラグも非対応です。認証には別の方式を用意する必要があります。

同じサーバーをClaude Codeとclaude.aiの両方に追加したらどちらが優先されるか

同じURLを指すサーバーがClaude Code側にもclaude.aiのコネクタ側にも存在する場合、Claude Code側で追加したものが優先されます。コネクタは/mcpで非表示(hidden)として一覧に出て、重複を外す方法も併せて示されます。

OAuthトークンを取り消したいときはどうするか

/mcpメニューの「Clear authentication」で、そのサーバーへのアクセスを取り消せます。シェルからならclaude mcp logout <name>が保存済みのOAuth認証情報を消します。次回接続時はブラウザでの認可からやり直しです。

認可後のブラウザリダイレクトが失敗したらどうするか

自動的なlocalhostへのリダイレクトが接続エラーで失敗した場合でも、認可自体はサーバー側で完了しています。ブラウザのアドレスバーに表示されているコールバックURLをコピーし、Claude Codeが表示するURL入力プロンプトに貼り付ければ、そのまま認証を完了できます。

組織はメンバーが使えるコネクタのツールを制限できるか

組織はclaude.aiコネクタのツールごとに「ask」または「blocked」を設定できます。Claude Codeは起動時にこの設定を読み、ローカルで強制します。

  • ask: 呼び出しのたびにYour organization requires approval for this toolという理由で確認が出ます。acceptEdits・auto・bypassPermissionsでも省略されず、「今後は確認しない」の選択肢もありません。一致する許可ルールがあっても確認は消えず、確認を出さないdontAskモードでは拒否になります
  • blocked: Claudeがツールを見る前に除外されます。/mcpのツール一覧にはdisabled by your organizationとして残ります

例外はデスクトップアプリのローカル・SSHセッションです。blockedはアプリ側で外されますが、askはClaude Codeに届かず、通常の権限ルールが適用されます。

まとめ

日常の接続はclaude mcp addと/mcpで済みます。DCRにもCIMDにも対応しない認可サーバーや企業IdPが相手のときだけ、事前登録クレデンシャルとスコープ固定が要ります。失敗したときは、エラー文言と、サインイン済みかどうかの2点から切り分けられます。

claude mcp addの全オプションとスコープ管理はClaude Code MCP設定ガイドにあります。症状別の切り分けはMCPサーバーに接続できないときの切り分け手順、OAuth対応サーバーを作る側の実装はMCPサーバー自作ガイドが扱っています。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. modelcontextprotocol.io/specification/2026-07-28/basic/authorization
  2. modelcontextprotocol.io/specification/2026-07-28/basic/authorization/client-regist…
  3. modelcontextprotocol.io/specification/2026-07-28/basic/authorization/authorization…
  4. modelcontextprotocol.io/specification/2026-07-28/changelog
  5. code.claude.com/docs/en/mcp
  6. code.claude.com/docs/en/changelog
  7. code.claude.com/docs/en/errors
この記事を共有:XはてブLinkedIn
MCP をもっと見る →