22
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MCP認可フローを仕様から読み解く(2025-06-18版)

Last updated at Posted at 2025-07-28

はじめに

2025-06-18版のMCP認可フローについて解説します。

MCP認可についてはすでに多くの記事が出ていますが、本記事では筆者自身の理解を整理する目的もかねて、「自動検出」「動的登録」「PKCE」など、MCP認可フローを理解するうえで欠かせない重要なポイントに焦点を当て、公式仕様をもとにできるだけわかりやすく解説していきます。

なお、MCP認可フローや各仕様の詳細な説明に入る前に、まず実際の動作を見てみたい方は本記事の「MCPクライアントツールで動作確認」をご覧ください。実際の動きを知ることで、認可フローの理解がよりスムーズになるでしょう。

MCP認可 (2025-06-18版) のハイライト

MCP認可は、安全かつ動的に通信を行うための仕組みを提供します。2025-06-18版では、従来の手動設定や煩雑な事前準備を減らし、より安全で柔軟な認可フローを実現するための機能強化が大きな特徴となっています。

主要な標準規格

2025-06-18版のMCP認可を構成する主要な標準規格と実装要求レベルです。

標準規格 ターゲット 実装要求レベル 説明
OAuth 2.1 認可フレームワーク ( draft-ietf-oauth-v2-1-13) 認可サーバー、MCPクライアント MUST 認証コード保護のため認可サーバーはOAuth 2.1 (PKCE必須) 実装必須。クライアントもPKCEを実装すること
OAuth 2.0 保護リソースメタデータ / Protected Resource Metadata (RFC9728) MCPサーバー, MCPクライアント MUST MCPサーバーに問い合わせ、保護リソースメタデータ(OAuth認可サーバーなどを含む)を通じて、認証サーバーURLなど取得する
OAuth 2.0 認可サーバーメタデータ / Authorization Server Metadata (RFC8414) 認可サーバー, MCPクライアント MUST 認可サーバーに問い合わせ、認可サーバーメタデータを通じて、認可サーバー問い合わせに必要な情報を取得する。これにより認可サーバーのエンドポイントの自動公開を実現
OAuth 2.0 動的クライアント登録 / Dynamic Client Registration Protocol (RFC7591) 認可サーバー, MCPクライアント SHOULD クライアントは自動的に自己の詳細情報を認可サーバーに提供し、一意の識別子を受け取る。これにより自動クライアント自己登録を実現
OAuth 2.0 リソースインジケーター / Resource Indicators for OAuth2.0 (RFC 8707で定義) MCPクライアント MUST 不正なリソースサーバーでのアクセストークンの使用を防ぐために、トークンをどのリソースサーバーで使うかを明示的に指定する仕組み

リソースと認可の責任分離

MCP認可仕様の2025-03-26版では、MCPサーバーは、「リソースサーバー」と「認可サーバー」の両方の役割を担っていました。しかし、2025-06-18版では、MCPサーバーは「リソースサーバー」として明確に定義され、認可の役割は認可サーバーが担当するようになりました。これは非常に大きな変更点です。

A protected MCP server acts as an OAuth 2.1 resource server, capable of accepting and responding to protected resource requests using access tokens.
An MCP client acts as an OAuth 2.1 client, making protected resource requests on behalf of a resource owner.
The authorization server is responsible for interacting with the user (if necessary) and issuing access tokens for use at the MCP server.

引用元: 2025-06-18 Authorization 2.1 Roles

このように「リソース」と「認可」の責任を分離することで、MCPサーバーはトークンの検証だけを行い、認可に関する複雑な処理は認可サーバーに任せることができます。つまり、ID管理の一元化だったり、既存のシングルサインオン(SSO)との連携がしやすくなり、エンタープライズ用途でも対応できるようになるわけです。とても大きな一歩です。

自動検出と動的登録

MCPクライアントは、必要なエンドポイントを自動的に検出し、新しいサーバーに対して自らを動的に登録することができます。これにより、ユーザーがクライアントIDや認可サーバーのエンドポイントといった情報を事前に手動で設定する必要がなくなります。

自律的に動作するAIエージェントが、MCPサーバーを自動的に検出し、自己登録・認可を行うようなユースケースを考えると、こうした機能は不可欠と言えるでしょう。

なお、こうした仕組みを支えているのが、前述の「主要な標準仕様」で紹介した各種仕様です。それぞれの仕様については、次節「MCP認可フロー」で詳しく解説します。

自動検出:

  • OAuth 2.0 保護リソースメタデータ / Protected Resource Metadata (RFC9728)
  • OAuth 2.0 認可サーバーメタデータ / Authorization Server Metadata (RFC8414)

動的登録:

  • OAuth 2.0 動的クライアント登録 / Dynamic Client Registration Protocol (RFC7591)

OAuth2.1のOAuth 2.0との互換性について

OAuth 2.1は、OAuth 2.0との互換性を保ちながら、より安全で最新のベストプラクティスを取り入れた仕様です。主な変更点は以下のとおりです:

  • PKCE(認可コードを安全に扱うための仕組み。詳細は後述)が必須となった
  • OAuth 2.0で利用可能だったImplicitResource Owner Credentialsなどの認可タイプはOAuth 2.1では使用できなくなっている
  • リダイレクトURIの厳密な一致など、セキュリティ強化のための追加制約が導入されている

情報元: The OAuth 2.1 Authorization Framework - Compatibility with OAuth 2.0

MCP認可フロー

シーケンス

MCP認可フローは、以下のシーケンスで進みます。

(引用: MCP Authorization 2025-06-18のシーケンスを元に一部ノートとALTを加筆・修正)

このシーケンスでは、トークン無しでMCPサーバーにアクセスしてから、最終的に認可サーバーより取得したアクセストークンでMCPサーバーにアクセスするまでの認可フローが記されています。ステップ①〜④は後述のセクションで説明します。

(1) 認可サーバー検出(Authorization Server Location)

MCPクライアントは、MCPサーバーに対して「保護リソースメタデータ」(標準規格:RFC 9728 - OAuth 2.0 Protected Resource Metadata)をリクエストし、認可サーバーのURLなどの情報を取得します。この保護リソースメタデータから取得した認可サーバー情報を元に、次のステップである「(2) 認可サーバーのメタデータ検出」のためのリクエストを認可サーバーに送信します。

この保護リソースメタデータで取得可能な情報については、下記レスポンス例や、標準規格 RFC 9728が参考になります。

Protected Resource metadataリクエスト例

GET /.well-known/oauth-protected-resource HTTP/1.1
Host: resource.example.com

Protected Resource metadataレスポンス例

{
  "resource":
    "https://resource.example.com",
  "authorization_servers":
    ["https://as1.example.com",
    "https://as2.example.net"],
  "bearer_methods_supported":
    ["header", "body"],
  "scopes_supported":
    ["profile", "email", "phone"],
  "resource_documentation":
    "https://resource.example.com/resource_documentation.html"
}

(引用: RFC 9728 https://datatracker.ietf.org/doc/html/rfc9728)

認可サーバーは、このメタデータのauthorization_serversフィールドに含まれてます。

(2) 認可サーバーのメタデータ検出 (Athorization Server Metadata Discovery )

クライアントは認可サーバーに対して「認可サーバーメタデータ」(標準規格:RFC 8414 - OAuth 2.0 Authorization Server Metadata) をリクエストし、認可エンドポイントやトークンエンドポイントなどの情報を自動で取得します。この認可サーバーの自動メタデータ検出の仕組みにより、認可サーバーはOAuthエンドポイントを自動的に公開でき、クライアントにとっては、OAuthに必要なエンドポイント(認可、トークン)どの手動設定を減らすことができます。

この認可サーバーメタデータで取得可能な情報については、下記レスポンス例や、標準規格 RFC 8414が参考になります。

Autorization server metadataリクエスト例

GET /.well-known/oauth-authorization-server HTTP/1.1
Host: example.com

Autorization server metadataレスポンス例

{
  "issuer":
    "https://server.example.com",
  "authorization_endpoint":
    "https://server.example.com/authorize",
  "token_endpoint":
    "https://server.example.com/token",
  "token_endpoint_auth_methods_supported":
    ["client_secret_basic", "private_key_jwt"],
  "token_endpoint_auth_signing_alg_values_supported":
    ["RS256", "ES256"],
  "userinfo_endpoint":
    "https://server.example.com/userinfo",
  "jwks_uri":
    "https://server.example.com/jwks.json",
  "registration_endpoint":
    "https://server.example.com/register",
  "scopes_supported":
    ["openid", "profile", "email", "address",
      "phone", "offline_access"],
  "response_types_supported":
    ["code", "code token"],
  "service_documentation":
    "http://server.example.com/service_documentation.html",
  "ui_locales_supported":
    ["en-US", "en-GB", "en-CA", "fr-FR", "fr-CA"]
}

(引用: RFC8414 https://datatracker.ietf.org/doc/html/rfc8414)

(3) 動的クライアント登録(Dynamic Client Registration)

クライアントは、動的クライアント登録(標準規格: RFC7591 - OAuth 2.0 Dynamic Client Registration Protocol) の仕組みにより、認可サーバーに自分自身を自動登録し、一意のクライアントIDなどを取得できます。

OAuth認可フローでは、あらかじめOAuthクライアントを登録し、リクエスト時に事前に発行されたクライアントIDを指定するのが一般的です。しかしMCPでは、動的クライアント登録のサポートが推奨(SHOULD)されており、これによりクライアントは、従来は事前に必要だったクライアント登録手続きを、実行時に動的に行えるようになったのです。

この動的クライアント登録に必要なリクエスト情報や得られるレスポンス情報については、下記リクエスト・レスポンス例や、標準規格 RFC7591が参考になります。

Dynamic Client Registrationリクエスト例

POST /register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: server.example.com
{
  "redirect_uris": [
    "https://client.example.org/callback",
    "https://client.example.org/callback2"],
  "client_name": "My Example Client",
  "client_name#ja-Jpan-JP":
     "\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u540D",
  "token_endpoint_auth_method": "client_secret_basic",
  "logo_uri": "https://client.example.org/logo.png",
  "jwks_uri": "https://client.example.org/my_public_keys.jwks",
  "example_extension_parameter": "example_value"
}

Dynamic Client Registrationレスポンス例(成功時)

HTTP/1.1 201 Created
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
  "client_id": "s6BhdRkqt3",
  "client_secret": "cf136dc3c1fc93f31185e5885805d",
  "client_id_issued_at": 2893256800,
  "client_secret_expires_at": 2893276800,
  "redirect_uris": [
    "https://client.example.org/callback",
    "https://client.example.org/callback2"],
  "grant_types": ["authorization_code", "refresh_token"],
  "client_name": "My Example Client",
  "client_name#ja-Jpan-JP":
     "\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u540D",
  "token_endpoint_auth_method": "client_secret_basic",
  "logo_uri": "https://client.example.org/logo.png",
  "jwks_uri": "https://client.example.org/my_public_keys.jwks",
  "example_extension_parameter": "example_value"
}

(引用: RFC7591 https://tools.ietf.org/html/rfc7591)

OAuthプロバイダーの動的クライアント登録 (DCR)サポート状況(2025/07時点)

参考までに、有名なOAuthプロバイダーをピックアップしてDCRのサポート状況を調べてみました。

OAuthプロバイダー DCRサポート状況
Okta ◯ サポート(ref)
Auth0 ◯ サポート (ref)
Ping Identity ◯ サポート (ref)
Keycloak (OSS) ◯ サポート [ref]
Microsoft Entra ID ❌ 未公式サポート・未確認
Amazon Cognito ❌ 未公式サポート・未確認

(4) 標準のOAuth認可 + PKCE フロー

先述の通り、OAuth2.1ではPKCEが必須になりました。

PKCE(Proof Key for Code Exchange)は、OAuth 2.0の認可フローで認可コードを安全に取得するための拡張仕様です。
標準規格は RFC7636 です。

モバイルアプリやSPAなど、クライアントシークレット(client_secret)を安全に管理できない環境では、認可コードが盗まれてアクセストークンを不正取得されるリスクがあるため、そういう環境ではクライアントシークレットは持てません。PKCEはそういう環境のためのクライアントシークレットなしで認可コードを安全に取得できる仕組みです。

PKCE用パラメーター

PKCEでは、クライアントシークレットなしで認可コードを安全に取得するために、次の2つのパラメーターを活用します:

  • code_verifier: クライアントが生成するランダム文字列
  • code_challenge: code_verifierのハッシュ値(SHA-256暗号化したものをBase64URLエンコード)で変換した文字列

PKCEありのOAuthフロー

(引用: MCP Authorization 2025-06-18のシーケンスを元に一部ノートを修正)

  • 認可コード取得のリクエスト
    • クライアント
      1. クライアントはcode_verifierを作成(例: ZzZEOUD3AP)
      2. code_verifierをハッシュしてcode_challengeを作成
      3. クライアントは認可サーバーにリクエスト
      GET /authorize?
        client_id=abc123&redirect_uri=...&response_type=code
        &code_challenge=xxx&code_challenge_method=S256
      
    • 認可サーバー
      • ユーザー認証を行い、認可コード(AuthCode54321)をクライアントに返却
  • アクセストークン取得リクエスト
    • クライアントは認可サーバーのトークン取得エンドポイントにPOSTリクエスト送信
      POST /token
      
      payload (form):
      grant_type=authorization_code
      code=<認可コード:AuthCode54321>
      client_id=abc123
      code_verifier=ZzZEOUD3AP
      
    • 認可サーバー側でcode_challengecode_verifierを照合して一致したらトークン発行

PKCEフローにおいては、盗まれる可能性があるclient_secretは使わずに、code_verifierで一時的なセキュリティを担保します。仮に、認可コードが盗まれたとしても、code_verifierがなければ悪用できません。

なお、クライアントは取得したアクセストークンを、MCPサーバーへのリクエスト時にAuthorizationヘッダーとして付与します(アクセストークンは、クエリパラメーターで渡さないよう注意)。

Authorization: Bearer <アクセストークン>

PKCEなしのフロー(従来型)との比較

こちらはPKCEとそうでない場合のOAuthフローの違いをまとめたテーブルです。

比較項目 PKCEなし PKCEあり
認可リクエスト (認可コード取得) /authorize?client_id=... /authorize?client_id=...&code_challenge=...
トークンリクエスト code + client_id + client_secret code + client_id + code_verifier
セキュリティ client_secret に依存 code_verifier で検証

PKCEなしのフロー(従来型)

  • 認可コード取得のリクエスト
    • クライアント
      • クライアントは認可サーバーにリクエスト
        GET /authorize?
          client_id=abc123&redirect_uri=...&response_type=code
        
    • 認可サーバー
      • ユーザー認証を行い、認可コード(AuthCode54321)をクライアントに返却
  • アクセストークン取得リクエスト
    • クライアントは認可サーバーのトークン取得エンドポイントにPOSTリクエスト送信
      POST /token
      
      payload (form):
      ----
      grant_type=authorization_code
      code=<認可コード:AuthCode54321>
      client_id=abc123
      client_secret=<クライアントシークレット>
      
    • 認可サーバー側でclient_secretを照合してトークン発行

リソースインジケーター(Resource Indicators)の指定

従来のOAuth 2.0では、アクセストークンがどのリソースサーバー向けなのか明確に区別されていないため、同じトークンが複数のリソースサーバーで使い回されてしまうリスクがありました。たとえば、api.example.com用に発行されたトークンを、誤ってapi.example1.comに使っても通ってしまうことがあります。

この問題を解決するために登場したのが「リソースインジケーター」(RFC 8707 - Resource Indicators for OAuth 2.0)です。
リソースインジケーターでは、resourceパラメーターを使って、明示的にトークンをどのリソースサーバー(MCPサーバー)で使うかを指定します。

ポイントは以下の通りです:

  • 認可リクエストとトークンリクエストの両方で、resourceパラメーター(複数指定も可)を使って対象リソースを指定する
  • 認可サーバーは、そのリソース専用のアクセストークンを発行する
  • 他のリソースサーバーでは、そのトークンは使えない(無効になる)

認可コードリクエストの例

GET /as/authorization.oauth2?response_type=code
  &client_id=s6BhdRkqt3
  &state=tNwzQ87pC6llebpmac_IDeeq-mCR2wLDYljHUZUAWuI
  &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
  &scope=calendar%20contacts
  &resource=https%3A%2F%2Fcal.example.com%2F
  &resource=https%3A%2F%2Fcontacts.example.com%2F HTTP/1.1
Host: authorization-server.example.com

自動検出や動的登録によって、リソースサーバーへの接続は簡単になりますが、その分、悪意のあるサーバーに接続してしまうリスクも高まります。
リソースインジケーターは、こうしたセキュリティリスクを減らすための仕組みです。

MCPクライアントツールで動作確認

実際にMCP認可フローを体験したい場合は、以下のツールを使ってみるのがオススメです。

  • Postman MCPリクエスト (url)
  • MCP Inspector (url)

それぞれのツールでMCPサーバーにリクエストを送り、認可フローの流れを確認できます。
ここでは、OAuth認可を実装しているnotion mcpサーバー https://mcp.notion.com/sse (SSE) に対して2つのツールで動作確認してます。

Postman MCPリクエスト

Postmanでは、他のAPIリクエストと同じような使い勝手でMCPサーバーに対してリクエストを送信できます。使い方は簡単です。下記Gitアニメのように次のステップでMCP認可フローを確認できます。

  • 「New」ボタンでMCPリクエストを選択してMCPリクエストを作成
  • エンドポイントにMCPサーバーURLを入力して「Connect」ボタンをクリック
  • 初回はトークンなしリクエストが送信されるため401エラーとなり、レスポンスエリアに「Authorize」ボタンが表示される
  • 「Authorize」ボタンをクリックすると、認可フローが開始される
  • 認可サーバーの自動検出 → 自己登録 → OAuthの認可フローを経て、最終的にアクセストークンを取得し、リソースサーバー(MCPサーバー)にアクセス完了

mcp-auth-demo-postman.gif

以下、Postmanアプリのバージョン11.55.5時点(releaseノートはこちら)でのMCP認可フローにおける挙動で気付いた点です:

  • MCP OAuthではPKCE対応しているものの、デフォルトではPKCEありでの認可フローにならない。したがって、「Authorize」ボタンを押してからのアクセストークン取得までのフローではcode_verifiercode_challengeパラメータは活用されない
  • 認可やトークンリクエストにおいてリソースインジケーター(resourceパラメーター)は指定されない

MCP Inspector

MCP InspectorはAnthropic社が公式パッケージ名前空間@modelcontextprotocol/inspectorとして提供するデバッグツールです。しっかりMCP認可フローも確認できます。

  • MCP Inspector立ち上げる
    npx -y @modelcontextprotocol/inspector
    
  • Transport TypeとURLにそれぞれSSEとMCPサーバーURLを入力し「Connect」ボタンをクリックすると、認可フローが開始される
  • 認可サーバーの自動検出 → 自己登録 → OAuthの認可フローを経て、最終的にアクセストークンを取得し、リソースサーバー(MCPサーバー)にアクセス完了

mcp-auth-demo-mcp-inspector.gif

以下、MCP Inspector バージョン0.16.2時点 (releaseノートはこちら)でのMCP認可フローにおける挙動で気付いた点です:

  • MCP OAuthでPKCE対応しており、PKCEありでの認可フローが行われる
  • 認可やトークンリクエストにおいてリソースインジケーター(resourceパラメーター)は指定されない
  • UI上、動的クライアント登録をサポートしていない認可サーバでは認可フローの確認ができない

* 本記事執筆時点では最新が0.16.2になってますが、上記動画では便宜上0.15.0を利用してます

さいごに

2025-06-18版のMCP認可フローについて、重要なポイントに絞って解説しました。
MCP認可フローは、これからのサービス連携やAIエージェントの時代において、ますます重要性が増していきます。従来のOAuth 2.0と比べ、より安全かつ柔軟な認可が可能になり、手動設定の手間も大幅に削減されました。

ぜひ実際に動かしてみて、その仕組みやメリットを体感してみてください。
なお、MCP認可フローは現在も進化の途中にあり、継続的な情報のキャッチアップが欠かせません。私も気が向いたら、またアップデートの解説記事を書こうと思います。

最後に、もし内容に誤りや記述ミスなどがありましたら、ご指摘いただけると幸いです:pray:

22
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?