本文へ移動
🔐

remote MCP server を社内で使い始めると、最初は「OAuth でログインできるか」だけを見がちです。ですが、実務で止まりやすいのはログイン後です。どの scope を要求するのか、MCP server と下流 API の token を混ぜていないか、write tool だけ後から追加承認へ戻せるか、401 と 403 をどう扱うか。ここを曖昧にすると、MCP は便利な接続面ではなく、権限の抜け道になります。

この記事では、MCP の authorization / OAuth scope 設計 に絞って整理します。MCP server を組織で許可する台帳は MCP サーバーカタログ設計ガイド、MCP 全体の認証・監査・配布統制は MCP エンタープライズ運用ガイド、未信頼入力や tool poisoning は MCP prompt injection 対策ガイド、Claude Code から接続する手順は Claude Code MCP ガイド に分けています。

今回は、remote MCP server を OAuth 2.1 の protected resource として扱い、scope、resource indicator、audience validation、step-up authorization、token passthrough 禁止をどう運用設計に落とすかだけを扱います。

先に結論: MCP authorization は「ログイン」ではなく「どの resource へ何を許すか」

私なら、remote MCP の authorization は次の5点で設計します。

設計項目決めること事故りやすい状態
resourceMCP endpoint の正規 URL同じ token を複数 server で使い回す
authorization serverどの IdP / tenant が token を発行するかserver ごとに issuer が曖昧
scoperead / draft / write / admin の最小権限mcp:* のような広い scope
audience validationtoken の aud がその MCP server 宛てか下流 API token をそのまま受ける
step-up追加権限が必要なときの 403 と再承認write tool が黙って失敗または通る

OAuth によるログインは入口でしかありません。MCP authorization の本体は、MCP server がどの resource で、どの token なら受け付け、どの操作で追加 scope を要求するかです。

現行仕様で押さえるべき4つの部品

2026-07-28 の MCP authorization 仕様では、protected MCP server は OAuth 2.1 の resource server として扱われます。authorization server は user interaction と token 発行を担い、MCP client は resource owner の代理で protected resource request を投げます。

実装で見るべき部品は4つです。

1. Protected Resource Metadata

MCP server は OAuth 2.0 Protected Resource Metadata を実装し、どの authorization server を使うかを client に示します。client は 401 応答の WWW-Authenticate header にある resource_metadata を優先し、なければ well-known URI を探します。

実務では、ここを「MCP server の名刺」として扱います。

{
  "resource": "https://mcp.example.com/github",
  "authorization_servers": ["https://idp.example.com"],
  "scopes_supported": ["repo:read", "issues:read", "pull_requests:write"]
}

この metadata がない remote MCP は、どの authorization server と組み合わせる前提なのかが見えません。個人検証なら手元設定で逃げられても、組織配布では catalog に載せにくいです。

2. WWW-Authenticate による 401 challenge

未認証の client が protected MCP endpoint に来たら、server は 401 と WWW-Authenticate で authorization 情報を返します。MCP 仕様では、resource_metadata に加えて scope を返す設計も示されています。

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
                  scope="repo:read issues:read"

これにより client は、最初から過大な scope を要求せず、今の resource に必要な scope だけを選びやすくなります。

3. resource indicator と audience validation

MCP authorization で特に重要なのは、token がその MCP server 宛てに発行されたものかを確認することです。MCP 仕様は、client が authorization / token request に resource parameter を含め、server が token の audience を検証する前提を置いています。

ここを省くと、別 API 用の token、別 tenant 用の token、別 MCP server 用の token が通ってしまう可能性があります。

私なら、remote MCP server では最低限これを検証します。

type TokenClaims = {
  iss: string;
  aud: string | string[];
  scope?: string;
  exp: number;
  sub?: string;
};

function assertTokenForMcpServer(claims: TokenClaims, expected: URL) {
  const audiences = Array.isArray(claims.aud) ? claims.aud : [claims.aud];
  if (!audiences.includes(expected.toString())) {
    throw new Error("access token audience does not match this MCP resource");
  }

  if (claims.exp * 1000 < Date.now()) {
    throw new Error("access token expired");
  }
}

本番では JWT 検証、introspection、issuer / key rotation、clock skew も見ます。ここでの要点は、認証済み token かどうかではなく、この MCP resource 用の token かどうかを見ることです。

4. 403 insufficient_scope と step-up authorization

初回は read-only でつながり、write tool を使う段階で追加 scope が必要になる。これは remote MCP では自然な流れです。

このとき、server は黙って generic error を返すのではなく、403 と insufficient_scope を返します。

HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope",
                  scope="pull_requests:write",
                  resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"

client はこの情報をもとに step-up authorization を試みます。実務では、ここを human approval とつなげるのが重要です。write scope が必要になった瞬間に、人間へ「どの tool が、どの resource に、どの scope を追加要求しているか」を見せます。

token passthrough を禁止する

remote MCP の実装で一番やってはいけないのは、client が持っている下流 SaaS の access token を MCP server にそのまま渡し、MCP server がそれをさらに下流 API へ流すことです。

MCP 仕様では、client は MCP server の authorization server から発行された token 以外を MCP server に送るべきではなく、MCP server も自分の resource 用ではない token を受け入れたり転送したりしてはいけない、という境界が置かれています。

この禁止の意味は実務上かなり大きいです。

  • GitHub token を MCP server に丸投げしない
  • Google Drive token を汎用 proxy server に渡さない
  • IdP token を MCP server から別 API へ横流ししない
  • user token と service token の監査主体を混ぜない

token passthrough を許すと、誰が何を許可したのか、どの resource に向けた token なのか、下流 API での操作主体が誰なのかが崩れます。便利に見えますが、後から監査できません。

scope は tool risk tier から逆算する

OAuth scope は IdP や API の都合だけで決めると広くなります。MCP では、tool の危険度から scope を逆算した方が安全です。

私なら、MCP tool を次のように分けます。

tool tierMCP tool の例scope の考え方
readissue / docs / customer record の検索read:* だけ。write scope を混ぜない
inspectdiff / audit / config の確認read より狭く、対象 resource を限定
draftPR comment 下書き、CRM 更新案の生成API write ではなく draft 保存に限定
writePR comment 投稿、ticket 更新操作別 scope と human approval を要求
external action配信、課金、削除、本番変更原則禁止。必要なら個別承認と短命 token

この分け方は AIエージェント tool risk tier 設計ガイド と同じ考え方です。MCP authorization では、それを OAuth scope と 401/403 の設計に接続します。

たとえば GitHub MCP を1つだけ許可するのではなく、catalog と scope を分けます。

mcp_servers:
  github_readonly:
    resource: https://mcp.example.com/github-readonly
    scopes:
      - repo:read
      - issues:read
    allowed_tools:
      - search_issues
      - read_pull_request

  github_pr_writer:
    resource: https://mcp.example.com/github-pr-writer
    scopes:
      - pull_requests:write
    allowed_tools:
      - create_pr_comment
    approval:
      required: true
      approver: repo_owner

同じ vendor でも、read server と write server を分けると運用がかなり楽になります。scope も audit log も approval も、resource 単位で追えるからです。

401 と 403 を運用上の signal にする

MCP authorization では、401 と 403 をただの HTTP error として扱わない方がよいです。

status意味運用上の扱い
401token がない、無効、期限切れlogin / refresh / re-auth へ戻す
403token はあるが scope が足りないstep-up と human approval へ戻す
400request が壊れているclient 実装か tool schema を直す

特に 403 は、MCP server が「この操作には追加 scope が必要」と説明する signal です。ここを permission denied の一文で潰すと、client は再承認すべきか、ユーザーに聞くべきか、そもそも禁止すべきか判断できません。

私は 403 を監査ログにも残します。

{
  "event": "mcp_scope_challenge",
  "resource": "https://mcp.example.com/github-pr-writer",
  "tool": "create_pr_comment",
  "current_scopes": ["repo:read"],
  "required_scopes": ["pull_requests:write"],
  "decision": "waiting_human_approval"
}

このログがあると、後から「なぜ追加承認が出たのか」「どの scope が増えたのか」「誰が許可したのか」を追えます。

local stdio と remote HTTP で auth の前提を分ける

MCP authorization は HTTP transport 向けの話です。local stdio server は同じ OAuth flow を必ず使う前提ではありません。

ここを混ぜると設計が歪みます。

transport認証の主な置き場所向いている用途
stdioローカル環境変数、OS keychain、client 設定個人端末の補助 tool、閉じた開発補助
remote HTTPOAuth、Protected Resource Metadata、resource indicator組織配布、SaaS 連携、監査対象

stdio は簡単ですが、組織配布では「誰がどの token を使っているか」が端末に寄りやすいです。remote HTTP は実装が重い代わりに、authorization server、scope、audience、ログを中央で扱いやすい。

Claude Code から MCP を追加する具体手順は Claude Code MCP ガイド で扱っています。この記事では、remote HTTP を組織で許可するなら OAuth 境界まで持つべき、という設計判断だけを押さえます。

実務テンプレ: remote MCP を許可する前の authorization review

私なら、remote MCP server を組織に入れる前に次のチェックを通します。

  1. Protected Resource Metadata を公開しているか
  2. authorization_servers が明示されているか
  3. resource が MCP endpoint と一致しているか
  4. client が authorization / token request に resource parameter を付けるか
  5. server が token の audience を検証するか
  6. scope が read / draft / write / admin に分かれているか
  7. write tool で 403 insufficient_scope を返せるか
  8. step-up authorization に retry limit があるか
  9. token passthrough をしていないか
  10. scope challenge と承認結果を audit log に残すか

この10項目が見えない server は、個人検証までに留めます。組織標準に入れるなら、MCP サーバーカタログ設計ガイド の catalog 行にも同じ情報を持たせます。

ありがちな失敗

mcp:tools だけで全 tool をまとめる

最初の PoC では動きますが、read と write の差がなくなります。最低でも read / write / admin は分けます。

401 と 403 を同じエラーにする

401 は認証の問題、403 は scope の問題です。client 側の UX も監査ログも分けた方がよいです。

下流 API の token をそのまま受ける

token passthrough は避けます。MCP server 宛ての token を受け、必要なら server 側で適切な downstream credential を管理します。その credential も resource / user / service account の責任境界を分けます。

scope を prompt で補う

「危険な操作はしないで」と prompt に書いても、OAuth scope にはなりません。prompt は意図を伝えるだけです。止める場所は authorization server、MCP server、tool policy、approval gate に置きます。

まとめ: MCP authorization は AI エージェントの実行境界になる

MCP authorization は、ログイン画面を出すためだけの仕様ではありません。remote MCP server を protected resource として扱い、scope、resource indicator、audience validation、401/403、step-up authorization を使って、AI エージェントがどこまで外部 system を操作できるかを決める実行境界です。

私なら、まず read-only の remote MCP を1つ選び、Protected Resource Metadata、audience validation、403 insufficient_scope、audit log まで通します。そこから write tool を足す。最初から広い scope を渡して「後で運用で縛る」は避けます。

MCP を組織で安全に広げるには、server catalog、prompt injection 防御、監査ログだけでは足りません。authorization を「ログインできるか」ではなく「どの resource に、どの scope で、どの操作を許したか」として設計することが必要です。

参考

WRITTEN BY nidoneko

Full-stack engineer with 8+ years of experience in TypeScript, React, Node.js, and cloud-native development across healthcare, finance, HR, and IoT domains.

View Profile →