MCP Server における Authorization RFC の動向キャッチアップ

source: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/284
2025-03-26 Spec ... 今日時点での最新版の仕様

Sequence & Session
シーケンス図が割とわかりやすい。
個人的にアンテナに引っかかった話をメモっていく(下記)
HTTP + SSE をベースとする(stdio ではない)トランスポートでは、Server 側が能動的に Client にデータを送る手段は SSE しかない。つまり最初の1回 (?) は Client からリクエストをもらう必要がある。Client は Server からのイベントを Listen する意志を HTTP リクエストで明示する必要があって、そこで初めて Server は(MCP 上の概念として)自発的に Client 対するデータ送信ができるようになってる。
HTTP (+SSE) 的には複数回のリクエストだが、MCP 上のやり取りとしては1回分、という感じになる。んで、MCP 上でのセッションを表現するために Mcp-Session-Id
というヘッダが考案されている。これは Initialization 時に Server 側が InitializaResult
のレスポンスでそういう HTTP ヘッダを含める必要がある。これはプロトコル的には任意。これで「セッション」の概念が使えるようになる。このへんは、なんだか TCP/IP のスタックで既視感がある。ID は UUID みたいなグローバルユニークな値で、かつ 暗号的に 安全なものであるべき。
Server が Mcp-Session-Id
を付与するかは任意だが、Client はこのヘッダを受け取ったら必ず以降の通信でその ID使う必要がある(それはそう)。で、セッションID が必要な Server は、Mcp-Session-Id
がない (Initialization 以外での) 通信を弾くべき。具体的には 400 Bad Request 応答。
Mcp-Session-Id
を伴う 404 レスポンスがあった場合、Client は新しいセッションを開始しなければならない。
つまり、Session Id を持たない InitializeRequest
を送る必要がある。
Client 側からセッションを閉じたい場合は、Client から Mcp-Session-Id
をくっつけた DELETE を送るのが推奨。こうすることで明示的にセッションを閉じる意思表明になる。ここで、Server はその要求を拒否するために 405 Not Allowed を送ってもよい。(?この応答の必要性はあんまり良くわかっていない。Server が拒否したいシチュエーションがぱっと出てこなかった)

Authorization
※あくまで認可なので、認証とは切り分ける
Transport レベルでの認可を実現する。Authorization は MCP の実装において任意。
Authorization をサポートする HTTP-based な transport は、この仕様を実装すべきである。
Authorization をサポートする STDIO transport は、この仕様に準拠すべきではない。その代わりに、環境からクレデンシャルを取得する
他の Transport は、(このプロトコル仕様に限らず)その通信プロトコル上で確立しているベスプラに従わねばならない。
...要するに、HTTP ベースな Transport で、この OAuth ベースの仕組みが適用されるという話
MCP における Authorization は次の3つを基礎としているが、全部ではなくサブセットに準拠している
- OAuth 2.1 IETF DRAFT
- OAuth 2.0 Authorization Server Metadata (RFC8414)
- OAuth 2.0 Dynamic Client Registration Protocol (RFC7591)

Authorization (2/n)
Grant Type はそのユースケースに応じて選択するべき、とある
例えば、Authorization Code
は人間に代わって仕事をするような性質のものに。
Client Credentials
は、人間ではない、(OAuth Client とは) 別のアプリケーションがクライアントである場合。人間 (end user) に成り代わる必要がない。
ここでもシーケン図がわかりやすい