Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

認可

最終更新 Markdown で表示Agent セットアップ

Model Context Protocol (MCP) サーバーを構築するときは、ユーザーのログイン(認証)と、MCP クライアントがアカウント上のリソースへアクセスする許可(認可)の両方が必要です。

Model Context Protocol は認可に OAuth 2.1 のサブセット を使います。OAuth により、ユーザーは API キーなどの資格情報を共有せずに、リソースへの限定アクセスを許可できます。

Cloudflare は OAuth Provider Library を提供します。OAuth 2.1 プロトコルのプロバイダー側を実装しており、MCP サーバーへ認可を簡単に追加できます。

OAuth Provider Library の使い方は 4 つです。

  1. Cloudflare Access を OAuth プロバイダーとして使います。
  2. GitHub や Google などのサードパーティ OAuth プロバイダーと直接連携します。
  3. 独自の OAuth プロバイダーと連携します。すでに使っている authorization-as-a-service(Stytch、Auth0、WorkOS など)も含みます。
  4. Worker 自身が認可と認証を扱います。Cloudflare 上の MCP サーバーが OAuth フロー全体を処理します。

以降のセクションで各オプションを説明し、実行可能なコード例へリンクします。

認可オプション

(1) Cloudflare Access OAuth プロバイダー

Cloudflare Access を使うと、MCP サーバーへシングルサインオン(SSO)を追加できます。ユーザーは 設定済みの ID プロバイダー または ワンタイム PIN で MCP サーバーに認証します。Access ポリシー に ID が一致する場合だけアクセスが許可されます。

Cloudflare Access を OAuth プロバイダーにした MCP サーバーの例 をデプロイするには、Access for SaaS で MCP サーバーを保護する を参照してください。

(2) サードパーティ OAuth プロバイダー

OAuth Provider Library は、GitHub や Google などのサードパーティ OAuth プロバイダーを使うよう設定できます。完全な例は GitHub の例 を参照してください。

サードパーティ OAuth プロバイダーを使う場合、そのプロバイダーの OAuth フローを実装するハンドラーを OAuthProvider に渡す必要があります。

import MyAuthHandler from "./auth-handler";

export default new OAuthProvider({
	apiRoute: "/mcp",
	// Your MCP server:
	apiHandler: MyMCPServer.serve("/mcp"),
	// Replace this handler with your own handler for authentication and authorization with the third-party provider:
	defaultHandler: MyAuthHandler,
	authorizeEndpoint: "/authorize",
	tokenEndpoint: "/token",
	clientRegistrationEndpoint: "/register",
});

Model Context Protocol 仕様の定義 どおり、サードパーティ OAuth プロバイダーを使うとき、MCP サーバー(Worker)は MCP クライアントへ独自のトークンを生成して発行します。

sequenceDiagram
    participant B as ユーザーエージェント(ブラウザ)
    participant C as MCP クライアント
    participant M as MCP サーバー(Worker)
    participant T as サードパーティ認証サーバー

    C->>M: 最初の OAuth リクエスト
    M->>B: サードパーティの /authorize へリダイレクト
    B->>T: 認可リクエスト
    Note over T: ユーザーが認可
    T->>B: MCP サーバーのコールバックへリダイレクト
    B->>M: 認可コード
    M->>T: コードをトークンと交換
    T->>M: サードパーティのアクセストークン
    Note over M: 紐付けた MCP トークンを生成
    M->>B: MCP クライアントのコールバックへリダイレクト
    B->>C: MCP 認可コード
    C->>M: コードをトークンと交換
    M->>C: MCP アクセストークン

詳細は Workers OAuth Provider Library のドキュメントを読んでください。

(3) 独自の OAuth プロバイダーを使う

アプリがすでに OAuth プロバイダーを実装している、または authorization-as-a-service を使っている場合は、(2) サードパーティ OAuth プロバイダー と同じ方法で使えます。

認証プロバイダーで次ができます。

  • メール、ソーシャルログイン、SSO(シングルサインオン)、MFA(多要素認証)で、ユーザーが MCP サーバーに認証できるようにします。
  • MCP ツールに直接対応するスコープと権限を定義します。
  • 要求された権限に対応する同意ページをユーザーに表示します。
  • 権限を強制し、エージェントが許可されたツールだけを呼べるようにします。

Stytch

ユーザーがメール、Google ログイン、またはエンタープライズ SSO でサインインし、AI エージェントに自社の OKR の閲覧と管理を許可できる Stytch を使うリモート MCP サーバー から始めます。Stytch は、組織内のユーザーのロールと権限に基づいて、AI エージェントへ付与するスコープを制限します。MCP クライアントを認可するとき、各ユーザーは同意ページを見ます。エージェントが要求する権限のうち、自分のロールで付与できるものが示されます。

Deploy to Cloudflare

コンシューマー向けには、認証と MCP クライアント認可に Stytch を使う To Do アプリのリモート MCP サーバーをデプロイします。ユーザーはメールでサインインし、アカウントに紐づく To Do リストへすぐアクセスできます。任意の AI アシスタントへ、タスク管理の手伝いを許可できます。

Deploy to Cloudflare

Auth0

Auth0 でユーザーをメール、ソーシャルログイン、またはエンタープライズ SSO で認証し、AI エージェント経由で To Do と個人データにアクセスするリモート MCP サーバーから始めます。MCP サーバーはユーザーの代わりに API エンドポイントへ安全に接続し、同意後にエージェントがアクセスできるリソースを明示します。この実装では、長時間のやり取り中にアクセストークンが自動更新されます。

セットアップでは、まず保護された API エンドポイントをデプロイします。

Deploy to Cloudflare

次に、Auth0 で認証を扱い、AI エージェントを API エンドポイントへ安全に接続する MCP サーバーをデプロイします。

Deploy to Cloudflare

WorkOS

WorkOS の AuthKit でユーザーを認証し、AI エージェントへ付与する権限を管理するリモート MCP サーバーから始めます。この例では、ユーザーのロールとアクセス権に応じて、MCP サーバーがツールを動的に公開します。認証済みユーザーは全員 add ツールを使えます。WorkOS で image_generation 権限を割り当てられたユーザーだけが、画像生成ツールへのアクセスを AI エージェントに許可できます。認証済みユーザーのロールと権限に基づいて、MCP サーバーが AI エージェントへ機能を条件付きで公開する例です。

Deploy to Cloudflare

Descope

Descope Inbound Apps でユーザーを認証・認可し(メール、ソーシャルログイン、SSO など)、AI エージェント経由でデータへアクセスするリモート MCP サーバーから始めます。Descope のカスタムスコープで権限を定義・管理し、より細かく制御できます。

Deploy to Cloudflare

(4) MCP サーバー自身が認可と認証を扱う

OAuth Provider Library を使う MCP サーバーは、サードパーティを介さず OAuth 認可フロー全体を扱えます。

Workers OAuth Provider Libraryfetch() ハンドラー を実装する Cloudflare Worker で、MCP サーバーへの受信リクエストを処理します。

MCP サーバーの API、認証と認可のロジック、OAuth エンドポイントの URI パスは、次のように自分で渡します。

export default new OAuthProvider({
	apiRoute: "/mcp",
	// Your MCP server:
	apiHandler: MyMCPServer.serve("/mcp"),
	// Your handler for authentication and authorization:
	defaultHandler: MyAuthHandler,
	authorizeEndpoint: "/authorize",
	tokenEndpoint: "/token",
	clientRegistrationEndpoint: "/register",
});

OAuthProvider の完全な使用例(モック認証フロー付き)は Getting started の例 を参照してください。

この場合の認可フローは次のとおりです。

sequenceDiagram
    participant B as ユーザーエージェント(ブラウザ)
    participant C as MCP クライアント
    participant M as MCP サーバー(Worker)

    C->>M: MCP リクエスト
    M->>C: HTTP 401 Unauthorized
    Note over C: code_verifier と code_challenge を生成
    C->>B: 認可 URL + code_challenge でブラウザを開く
    B->>M: GET /authorize
    Note over M: ユーザーがログインして認可
    M->>B: 認可コード付きでコールバック URL へリダイレクト
    B->>C: 認可コード付きコールバック
    C->>M: コード + code_verifier でトークンリクエスト
    M->>C: アクセストークン(+ リフレッシュトークン)
    C->>M: アクセストークン付き MCP リクエスト
    Note over C,M: 通常の MCP メッセージ交換を開始

覚えておいてください。認証と認可は異なります。MCP サーバーは認可を自分で扱いながら、最初のユーザー認証は外部の認証サービスに任せられます。Getting started の例 はモック認証フローです。認証ハンドラーは自分で実装する必要があります。自分で認証するか、外部の認証サービスを使います。

ツール内で認証コンテキストを使う

ユーザーが OAuth Provider 経由で認証すると、ツール内で ID 情報を使えます。アクセス方法は McpAgentcreateMcpHandler のどちらを使うかで変わります。

移行中の McpAgent

このパターンは、非推奨の既存 McpAgent ルートにだけ適用されます。第 3 型パラメーターが認証コンテキストの形を定義します。init() とツールハンドラー内では this.props 経由でアクセスします。

import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

type AuthContext = {
	claims: { sub: string; name: string; email: string };
	permissions: string[];
};

export class MyMCP extends McpAgent<Env, unknown, AuthContext> {
	server = new McpServer({ name: "Auth Demo", version: "1.0.0" });

	async init() {
		this.server.tool("whoami", "Get the current user", {}, async () => ({
			content: [{ type: "text", text: `Hello, ${this.props.claims.name}!` }],
		}));
	}
}

ステートレスな createMcpHandler

互換のある Workers OAuth Provider は、context.http.authInfo に標準のトークンメタデータを渡します。既存アプリの props には getMcpAuthContext() を使います。

import { createMcpHandler, getMcpAuthContext } from "agents/mcp/server";
import { McpServer } from "@modelcontextprotocol/server";

function createServer() {
	const server = new McpServer({ name: "Auth Demo", version: "1.0.0" });

	server.registerTool(
		"whoami",
		{ description: "Get the current user", inputSchema: {} },
		async (_args, context) => {
			const auth = getMcpAuthContext();
			const name = (auth?.props.name as string) ?? "anonymous";
			return {
				content: [
					{
						type: "text",
						text: `${name}: ${context.http?.authInfo?.clientId}`,
					},
				],
			};
		},
	);

	return server;
}

export default {
	fetch(request, env, ctx) {
		return createMcpHandler(createServer)(request, env, ctx);
	},
} satisfies ExportedHandler;

生のアクセストークンをログに出したり返したりしないでください。

権限に基づくツールアクセス

ユーザー権限に応じて、使えるツールを制御できます。方法は 2 つです。ツールハンドラー内で権限を確認する、または条件付きでツールを登録します。

export class MyMCP extends McpAgent<Env, unknown, AuthContext> {
	server = new McpServer({ name: "Permissions Demo", version: "1.0.0" });

	async init() {
		this.server.tool("publicTool", "Available to all users", {}, async () => ({
			content: [{ type: "text", text: "Public result" }],
		}));

		this.server.tool(
			"adminAction",
			"Requires admin permission",
			{},
			async () => {
				if (!this.props.permissions?.includes("admin")) {
					return {
						content: [
							{ type: "text", text: "Permission denied: requires admin" },
						],
					};
				}
				return {
					content: [{ type: "text", text: "Admin action completed" }],
				};
			},
		);

		if (this.props.permissions?.includes("special_feature")) {
			this.server.tool("specialTool", "Special feature", {}, async () => ({
				content: [{ type: "text", text: "Special feature result" }],
			}));
		}
	}
}

ハンドラー内で確認すると、LLM へエラーメッセージが返り、拒否理由をユーザーへ説明できます。条件付きでツールを登録すると、ユーザーが使えないツールは LLM から見えません。呼び出そうとすること自体がありません。

次のステップ

MCP ポータル

ガバナンスとセキュリティのための MCP ポータルを設定します。

役に立ちましたか?