はじめに
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で利用可能だった
Implicit
やResource 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)
(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のシーケンスを元に一部ノートを修正)
- 認可コード取得のリクエスト
- クライアント
- クライアントはcode_verifierを作成(例: ZzZEOUD3AP)
- code_verifierをハッシュしてcode_challengeを作成
- クライアントは認可サーバーにリクエスト
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_challenge
とcode_verifier
を照合して一致したらトークン発行
- クライアントは認可サーバーのトークン取得エンドポイントにPOSTリクエスト送信
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
を照合してトークン発行
- クライアントは認可サーバーのトークン取得エンドポイントにPOSTリクエスト送信
リソースインジケーター(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認可フローを体験したい場合は、以下のツールを使ってみるのがオススメです。
それぞれのツールで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サーバー)にアクセス完了
以下、Postmanアプリのバージョン11.55.5
時点(releaseノートはこちら)でのMCP認可フローにおける挙動で気付いた点です:
- MCP OAuthではPKCE対応しているものの、デフォルトではPKCEありでの認可フローにならない。したがって、「Authorize」ボタンを押してからのアクセストークン取得までのフローでは
code_verifier
やcode_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 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認可フローは現在も進化の途中にあり、継続的な情報のキャッチアップが欠かせません。私も気が向いたら、またアップデートの解説記事を書こうと思います。
最後に、もし内容に誤りや記述ミスなどがありましたら、ご指摘いただけると幸いです