2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FastMCPを使って認証つきリモートMCPサーバーを作ってみる

Last updated at Posted at 2025-12-22

はじめに

MCP(Model Context Protocol)は、AIアシスタントが外部ツールやデータソースと連携するためのプロトコルです。Claude DesktopやClaude Webから、自作のMCPサーバーに接続して機能を拡張できます。

ただし、MCPサーバーをインターネットに公開する場合、アクセス制御を行ったほうが無難です。誰でもアクセスできる状態では、セキュリティリスクが高いと思われます。

本記事では、FastMCPを使ってOIDC認証付きのリモートMCPサーバーを構築する方法を紹介します。

環境

  • Python 3.11+
  • FastMCP 2.14.1

FastMCPとは

FastMCPは、MCPサーバーを簡単に構築できるPythonライブラリです。

pip install fastmcp

FastMCPの特徴:

  • デコレータベースのシンプルなAPI
  • 複数の認証プロバイダーをサポート
  • HTTP/SSE/Stdioなど複数のトランスポートに対応

認証オプション

FastMCPは複数の認証方式をサポートしています:

方式 用途 特徴
OAuthProxy Google, GitHubなど サーバー側でclient_id/secretを管理
OIDCProxy Okta, Auth0など OIDC準拠のIdPと連携、JWT検証
RemoteAuthProvider DCR対応IdP クライアント側で認証情報を管理

今回はOIDCProxy + Oktaの組み合わせで実装します。Auth0やAzure ADなど、OIDC準拠のIdPでも同様に実装できます。

やること

1. Oktaの設定

アカウント作成

Okta Developerでアカウントを作成します(無料)。画面の指示に従って進めてください。

アプリケーション作成

  1. 左ペインから Applications > Applications を選択
  2. Create App Integration をクリック
  3. Sign-in method で OIDC - OpenID Connect を選択
  4. Application type で Web Application を選択
  5. Next をクリック

スクリーンショット 2025-12-17 17.06.05.png

アプリケーション設定

項目 設定値
App integration name 任意(例:MCP Server)
Grant type Authorization Code、Refresh Token にチェック
Sign-in redirect URIs https://your-server.com/auth/callback
Sign-out redirect URIs https://your-server.com
Controlled access 適宜選択(Skip group assignment for now でOK)

Save をクリックして保存します。

認証情報の取得

アプリケーション作成後、以下の情報をメモしておきます:

  • Client ID: アプリケーション詳細画面に表示
  • Client Secret: アプリケーション詳細画面に表示
  • Okta Domain: 画面右上のプロフィールアイコンから確認(例:dev-xxxxx.okta.com

2. トークンのaudience検証を有効にする

トークンのaudience(発行先)を検証できるようにします。これにより、他のサービス向けに発行されたトークンの流用を防げます。

Oktaのデフォルト設定では、audienceはapi://defaultになっています。これをMCPサーバーのURLに変更するには、Custom Authorization Serverを作成します。

  1. Authorization Serverを作成
    • Security > API > Authorization Servers
    • 「Add Authorization Server」をクリック
    • Name: 任意(例:MCP Server)
    • Audience: https://your-server.com

スクリーンショット 2025-12-17 17.07.44.png

  1. Access Policyを設定
    • 作成したサーバー > Access Policies > Add Policy
    • 「Add Rule」でルールを追加(デフォルト設定でOK)

3. サーバーコード

#!/usr/bin/env python3
"""
FastMCPサーバー(Okta OIDC認証)
"""
import os
from dotenv import load_dotenv

load_dotenv()

from fastmcp import FastMCP
from fastmcp.server.auth.oidc_proxy import OIDCProxy
from starlette.requests import Request
from starlette.responses import JSONResponse

# 環境変数
OKTA_DOMAIN = os.getenv("OKTA_DOMAIN")
OKTA_CLIENT_ID = os.getenv("OKTA_CLIENT_ID")
OKTA_CLIENT_SECRET = os.getenv("OKTA_CLIENT_SECRET")
BASE_URL = os.getenv("BASE_URL")

# Okta OIDC設定URL
OIDC_CONFIG_URL = f"https://{OKTA_DOMAIN}/.well-known/openid-configuration"

# OIDCProxy設定
auth = OIDCProxy(
    config_url=OIDC_CONFIG_URL,
    client_id=OKTA_CLIENT_ID,
    client_secret=OKTA_CLIENT_SECRET,
    base_url=BASE_URL,
    redirect_path="/auth/callback",
    required_scopes=["openid", "profile", "email"],
    audience=BASE_URL,
    allowed_client_redirect_uris=[
        "https://claude.ai/api/mcp/auth_callback"
    ],
)

mcp = FastMCP("my-mcp-server", auth=auth)


# ツール定義
@mcp.tool()
def echo(message: str) -> str:
    """メッセージをそのまま返す"""
    return f"Echo: {message}"


@mcp.tool()
def add(a: int, b: int) -> int:
    """2つの数を足す"""
    return a + b


# ヘルスチェック
@mcp.custom_route("/health", methods=["GET"])
async def health(request: Request) -> JSONResponse:
    return JSONResponse({"status": "ok"})


if __name__ == "__main__":
    mcp.run(transport="http", host="0.0.0.0", port=8000)

4. 環境変数

.envファイルを作成:

OKTA_DOMAIN=your-domain.okta.com
OKTA_CLIENT_ID=your-client-id
OKTA_CLIENT_SECRET=your-client-secret
BASE_URL=https://your-server.com

5. 起動

# ngrokでトンネリング(開発時)
ngrok http 8000

# サーバー起動
python server_okta.py

ngrokのURLが発行されたら、https://your-server.comの部分を書き換えてください:

  • .envBASE_URL
  • Oktaの「Sign-in redirect URIs」
  • (任意)Authorization ServerのAudience

6. Claude Webから繋いでみる

Claude Webの設定画面でMCPサーバーを追加:

スクリーンショット 2025-12-17 17.10.20.png

URL: https://your-ngrok-url.ngrok-free.app/mcp

注意: URLの末尾に/mcpを付けること

動作フロー

FastMCPで上記のように設定すると、いくつかのエンドポイントが自動生成されます。ログを確認したところ、Claudeはこれらを使って認証フローを実行していました。

生成されるエンドポイント

エンドポイント 役割
/.well-known/oauth-protected-resource/mcp リソースメタデータ(RFC 9728)
/.well-known/oauth-authorization-server 認可サーバーのメタデータ(RFC 8414)
/register クライアント登録(初回のみ)
/authorize 認可エンドポイント
/consent ユーザー同意画面(IdPへの転送前に表示)
/token トークンエンドポイント
/mcp MCPプロトコル本体

Claudeの認証フロー

ログインしてみる

Claude WebでMCPサーバーを追加すると、認証フローが始まります。

  1. 同意画面が表示される

    • MCPサーバーへのアクセス許可を求める画面が表示されます
    • 「Approve」をクリック
  2. Oktaのログイン画面にリダイレクト

    • Oktaのドメインでログインフォームが表示されます
    • ユーザー名とパスワードを入力
  3. 認証完了

    • ログイン成功後、自動的にClaude Webに戻ります
    • MCPサーバーが「接続済み」になれば成功です

使ってみる

接続が完了したら、Claudeに話しかけてツールを使ってみましょう。

echoツールを試す:

ツールを使ってhello worldを出力して

スクリーンショット 2025-12-17 17.12.17.png

Claudeがechoツールを呼び出し、Echo: hello world と返ってきます。

addツールを試す:

addツールを使って3+5をして

スクリーンショット 2025-12-17 17.12.56.png

Claudeがaddツールを呼び出し、8 と返ってきます。

まとめ

FastMCPとOktaなどのIdPを組み合わせれば、簡単に認証付きMCPサーバーを構築できます。

ぜひ、自分だけのMCPサーバーを作ってみてください!

参考リンク

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?