サードパーティ AI エージェントによる MCP サーバーへのアクセスを有効化
Logto の AI ソリューション をご覧ください:MCP サーバー、AI エージェント、およびアプリ向けの認証 (Authentication) と認可 (Authorization)。
このガイドでは、 mcp-auth および MCP 公式 SDK v2 を使用して Logto を MCP サーバーと統合し、サードパーティ AI エージェントがユーザーの同意のもとで認証 (Authentication) を行い、安全に MCP サーバーへアクセスできるようにする手順を説明します。
このガイドで学べること:
- MCP サーバーの認可 (Authorization) サーバーとして Logto を設定する方法
- サードパーティ AI エージェントのオンボーディング(サードパーティアプリの登録、または ダイナミックアプリ を有効にして事前登録なしで任意のエージェントが接続できるようにする)
- MCP サーバーに「whoami」ツールをセットアップし、現在のユーザーのクレーム (Claims) を返す方法
- サードパーティ AI エージェント(MCP クライアント)でフローをテストする方法
このチュートリアルの完了後、MCP サーバーは次のようになります:
- Logto テナントでユーザーを認証 (Authentication) し、サードパーティ AI エージェントへの同意を取得
- Logto が発行した JWT アクセストークン(署名、発行者 (Issuer)、オーディエンス (Audience)、有効期限)を検証
- 「whoami」ツール呼び出し時に検証済みのクレーム (Claims)(
sub,iss,audなど)を返す
このガイドの完全な実行可能サンプルコードは、 mcp-auth/js リポジトリで確認できます:
whoami-express:このガイドで紹介している「whoami」サーバー(Node.js + Express)。whoami:同じサーバーを fetch-native(Web 標準のRequest/Responseと Hono)で構築し、Cloudflare Workers へデプロイ可能。
サードパーティ AI エージェント(MCP クライアント)と自分の MCP クライアントの違い
例を見てみましょう。あなたが MCP サーバーを運用し、メールアクセスと自動化を管理している開発者だとします。
公式メールアプリ(自分の MCP クライアント)
- ユーザーがメールを閲覧・管理できる公式メールアプリを提供します。
- 仕組み:公式メールアプリは Logto を使って MCP サーバーに接続し、ユーザーを認証 (Authentication) します。Alice がサインインすると、自動的にメールへアクセスでき、追加の同意画面は不要です(信頼されたアプリのため)。
サードパーティ AI エージェント(サードパーティ MCP クライアント)
- MCP サーバーを中心にエコシステムを構築しているため、他の開発者が「SmartMail AI」(メール要約や会議自動スケジューリングができる AI アシスタント)をサードパーティクライアントとして統合します。
- 仕組み:SmartMail AI(サードパーティ MCP クライアント)は、MCP サーバー経由でユーザーのメールへアクセスしたいと考えています。Alice が自身のアカウントで SmartMail AI にサインインすると:
- SmartMail AI がメールやカレンダーを閲覧する許可を求める同意画面が表示されます。
- Alice はこのアクセスを許可または拒否できます。
- Alice が同意したデータのみが SmartMail AI と共有され、明示的な再同意なしに追加データへアクセスすることはできません。
このアクセス(権限)制御により、MCP サーバーがすべてのデータを管理していても、サードパーティアプリ(SmartMail AI など)はユーザーが明示的に許可した範囲のみアクセスできます。このプロセスは MCP サーバーのアクセス制御実装によって強制され、回避できません。
まとめ
| クライアント種別 | 例 | 同意画面は必要? | 誰が管理? |
|---|---|---|---|
| 公式メールアプリ | 自分のメールアプリ | いいえ | 開発者本人 |
| サードパーティ AI エージェント | SmartMail AI アシスタント | はい | 他の開発者 |
自分の AI エージェントやアプリと MCP サーバーを統合したい場合は、 Logto で MCP 対応アプリに認証 (Authentication) を追加する ガイドを参照してください。
前提条件
- Logto Cloud (またはセルフホスト型)テナント
- Node.js >= 20 の環境
アーキテクチャの理解
- MCP サーバー:MCP クライアントにツールやリソースを提供するサーバーです。最新の MCP 仕様 に従い、Logto が発行するアクセス トークン (Access token) を検証する OAuth 2.0 リソースサーバーとして動作します。
- MCP クライアント:認証 (Authentication) フローを開始し、統合をテストするためのクライアントです。このガイドではサードパーティの AI エージェントをクライアントとして使用します。
- Logto:OpenID Connect プロバイダー(認可 (Authorization) サーバー)として機能し、ユーザーアイデンティティを管理し、MCP サーバー向けにオーディエンスバウンドの JWT アクセス トークン (Access token) を発行します。
規範的でないシーケンス図で全体の流れを示します:
MCP は急速に進化しているため、上記の図は最新でない場合があります。最新情報は mcp-auth ドキュメントを参照してください。
Logto でサードパーティ AI エージェントを設定する
サードパーティ AI エージェントが MCP サーバー にアクセスできるようにするには、Logto で サードパーティアプリ をセットアップする必要があります。このアプリは AI エージェントを表し、認証 (Authentication) と認可 (Authorization) に必要なクレデンシャルを取得するために使用されます。
サードパーティアプリ とは、外部開発者(リソース所有者ではない)が作成し、保護されたリソースへアクセスするためにユーザーの同意が必要なアプリケーションです。ファーストパーティアプリ(自社アプリ)とは異なり、サードパーティアプリはユーザーのデータへアクセスする前に、特定の権限を承認する同意画面を表示します。これにより、ユーザーは外部サービスと共有するデータをコントロールできます。
詳細は サードパーティアプリケーション を参照してください。
AI エージェントをオンボードする方法は 3 つあります:
- コンソールで手動作成:テストや既知の少数エージェント向け。
- Management API で登録サービスを構築:クレデンシャル発行をコントロールしたい場合。
- ダイナミックアプリを有効化:どのエージェントも事前登録なしで接続できるようにしたい場合。
開発者が Logto でサードパーティアプリを作成できるようにする
マーケットプレイスを構築したり、開発者が Logto でサードパーティアプリを作成できるようにしたい場合は、Logto Management API を活用してプログラム的にサードパーティアプリを作成できます。これにより、開発者は自分のアプリケーションを登録し、認証 (Authentication) に必要なクレデンシャルを取得できます。
クライアント登録プロセスを処理する独自サービスをホストする必要があります。このサービスは Logto Management API と連携し、開発者の代わりにサードパーティアプリを作成します。
または、Logto コンソールで手動でサードパーティアプリを作成し、プロセスに慣れることもできます。
事前登録なしで任意の AI エージェントを接続させる
オープンな MCP エコシステムでは、事前にエージェントを把握できないことが一般的です。ダイナミックアプリ を利用すると、登録ステップが不要になります。エージェントは自身のクライアントメタデータドキュメントを公開する HTTPS URL を client_id として使用し、認可リクエストが届いた際に Logto がそれを解決します。
ダイナミックアプリに付与した権限を通じて、エージェントがリクエストできる内容をコントロールできます。また、すべての認可はユーザーの同意画面を経由します。
Logto でサードパーティアプリを手動作成する
テストやアドホックな連携のために、Logto コンソールでサードパーティアプリを手動作成できます。これは、クライアント登録フローを実装せずに素早く連携を試したい場合に便利です。
-
Logto コンソールにサインインします。
-
アプリケーション→ アプリケーションを作成 → サードパーティアプリ → OIDC を選択します。
-
アプリ名やその他の必須項目を入力し、アプリケーションを作成 をクリックします。
-
権限 タブでアプリに 権限 を付与します:
- ユーザー セクション:
profileやemailなど、基本的なアイデンティティクレーム用のユーザーデータ権限。 - API リソース セクション:Logto で定義した API リソース の権限(スコープ)。例:MCP サーバー を表す API リソース。
- 組織 セクション:Logto 組織を利用している場合の組織権限。
- ユーザー セクション:
-
サードパーティアプリ側で、付与した権限をリクエストするスコープを設定します。例:
openid profile emailに加え、API リソースのスコープ。注意:OIDC では
openidが必須です。API リソースに紐づくアクセス トークン (Access token) を受け取るには、認可リクエストにresourceパラメータも含める必要があります。最新の MCP 仕様に準拠した MCP クライアントは、保護リソースのメタデータに基づきこれを自動で行います。 -
サードパーティアプリの リダイレクト URI を適切に設定します。Logto 側のリダイレクト URI も忘れずに更新してください。
内部的には、サードパーティアプリは標準的な OAuth 2.0 / OIDC クライアントです。つまり、Logto との統合には、任意の OAuth 2.0 / OIDC ライブラリやフレームワークを利用できます(開発者またはサードパーティ開発者が選択可能)。
注意すべき点は以下の通りです:
- サードパーティアプリを作成する際は、アプリのアーキテクチャに応じて適切なアプリケーションタイプを選択してください:
- 従来型ウェブ:クライアントシークレットを使って認証します。
- シングルページアプリ / ネイティブ:クライアントシークレットなしで安全な認可を行うために PKCE を使用します。
- クイックスタートガイドの多くはファーストパーティアプリ向けに書かれていますが、サードパーティアプリの統合時にも参考にできます。
- 主な違いは、サードパーティアプリでは同意画面 (Consent screen) が表示され、ユーザーにデータアクセスの明示的な許可を求める点です。
統合ガイドの詳細は サードパーティアプリケーション をご覧ください。
MCP サーバーのセットアップ
MCP 公式 SDK v2 と mcp-auth を使用して、現在のユーザーのアイデンティティクレームを返す "whoami" ツール付きの MCP サーバーを作成します。
プロジェクトの作成と依存関係のインストール
mkdir mcp-server
cd mcp-server
npm init -y
npm pkg set type="module"
npm pkg set main="whoami.js"
npm pkg set scripts.start="node whoami.js"
npm install @modelcontextprotocol/server @modelcontextprotocol/express @modelcontextprotocol/node express mcp-auth
@modelcontextprotocol/serverは MCP SDK v2 のコアであり、Web 標準のRequest/Responseを扱います。@modelcontextprotocol/expressおよび@modelcontextprotocol/nodeは、これを Node.js の Express に適応させます。mcp-authは、トークン検証機能と MCP SDK 用の OAuth ディスカバリーメタデータを提供します。
MCP SDK v2 および mcp-auth は ESM のみ対応で、Node.js >= 20 が必要です。
MCP サーバーを API リソースとして登録する
最新の MCP 仕様 では、アクセストークンが発行対象のリソースにバインドされている必要があります(RFC 8707)。mcp-auth もこれを強制します:トークンの aud クレームは MCP サーバーのリソース識別子と一致しなければなりません。Logto では、MCP サーバーの URL と一致するインジケーターを持つ API リソースを作成することで対応します:
- Logto コンソールにサインインします。
- API リソース → API リソースの作成 に進みます。
- 詳細を入力し、API リソースの作成 をクリックします:
- API 名:例として「Who am I」など任意の名前を入力します。
- API 識別子:
http://localhost:3001/を入力します。これは後で MCP サーバーで設定するリソース識別子と一致している必要があります。
リソースインジケーターには必ず末尾にスラッシュ(/)を含めてください。MCP 公式 SDK の現在のバグにより、SDK を利用するクライアントは認証リクエスト時にリソース識別子へ自動的に末尾スラッシュを付与します。リソースインジケーターにスラッシュが含まれていない場合、これらのクライアントでリソース検証が失敗します。
MCP Auth を Logto で設定する
MCP サーバーを保護されたリソースとして宣言します:リソース識別子と、信頼する認可サーバーを指定します。<your-logto-issuer-endpoint> は、先ほどコピーした発行者エンドポイント(アプリケーション詳細ページの Endpoints & Credentials に記載、例: https://my-project.logto.app/oidc)に置き換えてください。
whoami.js 内:
import { MCPAuth } from 'mcp-auth';
const authIssuer = '<your-logto-issuer-endpoint>';
const mcpAuth = new MCPAuth({
protectedResourceMetadata: {
// リソース識別子。Logto で登録した API リソースインジケーターと一致させる必要があります
resource: 'http://localhost:3001/',
// この MCP サーバーが信頼する認可サーバー
authorizationServer: { issuer: authIssuer, type: 'oidc' },
},
});
認可サーバーメタデータは初回利用時に遅延取得され、その後キャッシュされます。MCPAuth インスタンスは、Logto の JWKS を使って JWT アクセストークンを検証します ― 署名、発行者、オーディエンス、有効期限すべてが強制されます。手書きのトークン検証は不要です。
"whoami" ツールの実装
次に、検証済みアクセストークンから現在のユーザーのアイデンティティクレームを返す "whoami" ツールを実装します。getAuthInfo を使って、mcp-auth が検証した認証情報をツールのコールバックコンテキストから取得します。
import { McpServer } from '@modelcontextprotocol/server';
import { getAuthInfo } from 'mcp-auth';
// MCP サーバーインスタンスを作成するファクトリ関数
// 各リクエストごとに独立したサーバーインスタンスを生成し、リクエストを分離します
const createMcpServer = () => {
const mcpServer = new McpServer({
name: 'WhoAmI',
version: '0.0.0',
});
// 現在のユーザー情報を返すツールをサーバーに追加
mcpServer.registerTool(
'whoami',
{
description: '現在のユーザー情報を取得',
},
(context) => {
const { claims } = getAuthInfo(context);
return {
content: [{ type: 'text', text: JSON.stringify(claims) }],
};
}
);
return mcpServer;
};
サーバーの起動
最後に、OAuth ディスカバリードキュメント(RFC 9728 / RFC 8414)を公開し、MCP クライアントが認可サーバーを見つけられるようにします。また、SDK の Bearer 認証ミドルウェアで MCP エンドポイントを保護します。
import {
createMcpExpressApp,
mcpAuthMetadataRouter,
requireBearerAuth,
} from '@modelcontextprotocol/express';
import { toNodeHandler } from '@modelcontextprotocol/node';
import { createMcpHandler } from '@modelcontextprotocol/server';
const PORT = 3001;
// MCP ハンドラーは Web 標準の Request / Response を扱います。`toNodeHandler` で Express に適応
const mcpNodeHandler = toNodeHandler(createMcpHandler(createMcpServer));
const app = createMcpExpressApp();
// OAuth ディスカバリードキュメント(`/.well-known/...`)を公開。設計上パブリックです
app.use(mcpAuthMetadataRouter(await mcpAuth.getAuthMetadataOptions()));
app.all(
'/',
// 有効な Bearer トークンを要求。検証済み認証情報は `req.auth` 経由でハンドラーに渡されます
requireBearerAuth(mcpAuth.getBearerAuthOptions()),
// `createMcpExpressApp` は `express.json()` を適用し、リクエストストリームを消費するため
// パース済みボディを明示的に渡します
async (request, response) => mcpNodeHandler(request, response, request.body)
);
app.listen(PORT);
サーバーの起動は次のコマンドで行います:
npm start
統合をテストする
- MCP サーバーを起動します。
- サードパーティ AI エージェントを MCP サーバーに接続し、
whoamiツールを呼び出します。 - エージェントは 401 Unauthorized レスポンスを受け取り、MCP サーバーの保護リソースメタデータから Logto を検出し、ユーザーを Logto へリダイレクトして認証 (Authentication) します。
- ユーザーはサインインし、エージェントが要求する権限がリストされた同意画面を確認し、アクセスを承認(または拒否)します。
- エージェントはオーディエンスバウンドな JWT アクセストークンを受け取り、それを使って再度ツールを呼び出します。
- MCP サーバーは Logto の JWKS でアクセストークンを検証し、検証済みのクレーム (Claims) をエージェントに返します。
さらに学ぶ
これで MCP サーバーはサードパーティ AI エージェントからのアクセストークンを検証できるようになりました。次のステップとして、トークンのパススルーやユーザーコンテキストの喪失なしに、ユーザーの代理でダウンストリームのビジネス API を安全に呼び出す方法を学びましょう:
MCP サーバーがユーザーの代理で API を呼び出す:本番運用向けトークン戦略