Open6

【FastAPI-MCP】Python/FastAPIをMCP Serverにする方法について📝

ピン留めされたアイテム
まさぴょん🐱まさぴょん🐱

PythonでMCP Serverを構築する方法について📝

初期プロジェクトの作成

mkdir mcp-server-name

cd mcp-server-name
# uvがlocalになければ、installする。
curl -LsSf https://astral.sh/uv/install.sh | sh

# Project作成
uv init

仮想環境の構築

# 仮想環境の構築 & 有効化
uv venv
source .venv/bin/activate

パッケージの追加

# パッケージを追加する。
uv add "mcp[cli]" httpx

https://modelcontextprotocol.io/quickstart/server

https://zenn.dev/makumaaku/articles/85fc9e17f5bd5f

ピン留めされたアイテム
まさぴょん🐱まさぴょん🐱

FastAPI-MCP における認証実装の全体像について📝

https://github.com/tadata-org/fastapi_mcp/blob/main/docs/advanced/auth.mdx

https://github.com/tadata-org/fastapi_mcp/blob/main/examples/08_auth_example_token_passthrough.py

以下は FastAPI-MCP における認証実装の全体像 と具体的な実装パターンをまとめたものです。
最初に要点を一段落で整理し、その後に詳しい表・コード・内部フローを示します。

FastAPI-MCP では ①既存 FastAPI の Depends() 依存解決をそのまま使う「トークン透過」方式②OAuth 2/OIDC を MCP 仕様(2025-03-26)準拠で自動セットアップする方式 の2通りを軸に実装します。
どちらも FastApiMCP(app, auth_config=AuthConfig(...)) に AuthConfig を渡すだけで、
MCP クライアントからの呼び出しに対して ASGI 直結 かつ MCP が要求するメタデータ/プロキシ を自動生成し、権限チェックは FastAPI 標準の Depends() 側に集約されます。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub, fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub)

1. 認証方式別チートシート

方式 使う AuthConfig コード例 特徴 主な利用局面
トークン透過 (Bearer/PAT) AuthConfig(dependencies=[Depends(token_scheme)]) のみ HTTPBearer() など FastAPI Security を流用 クライアントが渡すヘッダをそのまま FastAPI へ。OAuth フローなしで最速。 (fastapi_mcp/examples/08_auth_example_token_passthrough.py at main · tadata-org/fastapi_mcp · GitHub, Security - First Steps - FastAPI) 社内ツール・既存 API Gateway でトークン発行済みの場合
OAuth2 / OIDC (自動プロキシ付き) AuthConfig(issuer=..., authorize_url=..., client_id=..., setup_proxies=True, dependencies=[Depends(verify)]) 下記「ステップ②」参照 MCP が期待する動的登録・audience・scope をプロキシで補完。Auth0, Keycloak 等に最適。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub, fastapi_mcp/examples/09_auth_example_auth0.py at main · tadata-org/fastapi_mcp · GitHub) 外部 IdP に接続しつつ LLM ツールを公開したい場合
カスタム OAuth メタデータ AuthConfig(custom_oauth_metadata={...}, dependencies=[Depends(verify)]) フルメタデータを辞書で指定 IdP 側が既に MCP 互換メタデータを返せるときに軽量。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub) 独自 OAuth 実装/プロキシ不要の場合

2. 実装ステップ

① トークン透過(最小構成)

from fastapi import FastAPI, Depends
from fastapi.security import HTTPBearer
from fastapi_mcp import FastApiMCP, AuthConfig

app = FastAPI()
token_scheme = HTTPBearer()

@app.get("/private")
async def private(payload = Depends(token_scheme)):
    return {"token": payload.credentials}

mcp = FastApiMCP(
    app,
    name="Protected MCP",
    auth_config=AuthConfig(dependencies=[Depends(token_scheme)])
)
mcp.mount()

この構成では Authorization ヘッダが無いと 401/403 を返す ため、MCP クライアント側では --header "Authorization:Bearer XXX" を添えて呼び出します。 (fastapi_mcp/examples/08_auth_example_token_passthrough.py at main · tadata-org/fastapi_mcp · GitHub, fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub)

② OAuth2 / OIDC(プロキシ自動生成)

from fastapi import FastAPI, Depends, Request
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from fastapi_mcp import FastApiMCP, AuthConfig

app = FastAPI()
oauth_scheme = HTTPBearer()

async def verify_auth(request: Request, cred: HTTPAuthorizationCredentials = Depends(oauth_scheme)):
    # JWT 検証などを行い、失敗なら HTTPException(401)
    return {"sub": "user123"}

mcp = FastApiMCP(
    app,
    name="MCP with OAuth",
    auth_config=AuthConfig(
        issuer="https://auth.example.com",
        authorize_url="https://auth.example.com/authorize",
        oauth_metadata_url="https://auth.example.com/.well-known/oauth-authorization-server",
        audience="my-api",
        client_id="mcp-client",
        client_secret="super-secret",
        dependencies=[Depends(verify_auth)],
        setup_proxies=True          # ← 重要:MCP 互換プロキシを自動生成
    )
)
mcp.mount()

Auth0 での動作例は examples/09_auth_example_auth0.py が参考になります。 (fastapi_mcp/examples/09_auth_example_auth0.py at main · tadata-org/fastapi_mcp · GitHub)

③ カスタム OAuth メタデータ

IdP がすでに MCP 互換メタデータを返せる場合は、custom_oauth_metadata に辞書(または OAuthMetadata モデル)を渡すだけです。プロキシは不要です。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub)

3. AuthConfig 主なフィールド一覧

フィールド 必須? 意味/補足
dependencies 401/403 を発生させる FastAPI Depends() リスト。無認証リクエストをキャッチし、MCP クライアントにフロー開始を知らせる。 (fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub)
issuer / authorize_url / oauth_metadata_url OAuth 時 IdP の URL 群。oauth_metadata_url が省略されると issuer+metadata_path から推測。 (fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub)
client_id / client_secret OAuth+プロキシ プロキシが「疑似動的登録」を返す際に利用。setup_fake_dynamic_registration=True なら両方必須。 (fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub)
audience / default_scope 任意 一部 MCP クライアントが送らないパラメータを補完するワークアラウンド。 (fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub)
custom_oauth_metadata 代替 フル JSON/OIDC メタデータを手動で与える場合用。 (fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub)
setup_proxies / setup_fake_dynamic_registration bool MCP クライアント互換のためのプロキシやダミー登録エンドポイントを生成するトグル。 (fastapi_mcp/fastapi_mcp/auth/proxy.py at main · tadata-org/fastapi_mcp · GitHub)

4. 内部フロー解説

  1. ASGI トランスポート
    FastApiMCP が受けた MCP Tool 呼び出しは await app(scope, receive, send)HTTP ラウンドトリップ無しに 元 FastAPI へ直結されます。 (fastapi_mcp/fastapi_mcp/auth/proxy.py at main · tadata-org/fastapi_mcp · GitHub)
  2. 依存解決による認可
    dependencies で登録した Depends()先に実行 され、失敗時は HTTPException(401/403) → MCP クライアントにエラー JSON が返り、自動的に OAuth フローやリトライが促されます。 (fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub)
  3. OAuth プロキシ
    setup_proxies=True の場合、/oauth/authorize, /oauth/token, /register, /userinfo 等の 薄い転送エンドポイント を FastAPI に差し込み、必要なクエリ変換・パラメータ追加を実施します。 (fastapi_mcp/fastapi_mcp/auth/proxy.py at main · tadata-org/fastapi_mcp · GitHub)
  4. メタデータ供給
    /\.well-known/oauth-authorization-server に OIDC メタ JSON を配信。AuthConfig で未指定の項目はデフォルト値(code 応答タイプなど)が自動補完されます。 (fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub)

5. ベストプラクティス & 注意点


これで FastAPI-MCP における認証機能の選択肢・設定方法・内部動作 を俯瞰できるはずです。まずは「トークン透過」で動作確認し、将来的に公開する場合は AuthConfig(setup_proxies=True) で OAuth 2 を段階的に導入するのが現実的な流れです。

ピン留めされたアイテム
まさぴょん🐱まさぴょん🐱

FastAPI-MCP で、Token認証を実施する際のToken発行について📝

以下では 「FastAPI-MCP で Bearer トークン認証を採用する場合、そもそも “トークンをどこでどう発行するか?」 を 3 つの代表パターン(①固定トークン、②Opaque ランダムトークン、③JWT アクセストークン)に分けて整理し、実装例・使い分け早見表・セキュリティ勘所をまとめました。

ざっくり言うと 開発中は “固定または secrets.token_urlsafe() で作った Opaque トークン” が最短、運用では “PyJWT で署名付き JWT にして有効期限も管理” が定番 です。
これらを FastAPI-MCP に組み込む際は HTTPBearer()AuthConfig(dependencies=[…]) を渡すだけで済みます。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub, fastapi_mcp/examples/08_auth_example_token_passthrough.py at main · tadata-org/fastapi_mcp · GitHub)

1. 発行方式の全体像

# トークン形式 発行方法/ライブラリ 典型的な /token 実装 主な用途
1 固定文字列 .env などで手動発行 発行エンドポイント不要 ローカル開発・CI
2 Opaque ランダム secrets.token_urlsafe() または uuid.uuid4() POST /token で生成して DB に保存 社内 API・簡易サービス
3 JWT (署名付) pyjwt もしくは python-jose POST /token で署名 & exp 付与 公開 API/モバイルアプリ

<small>※ どの方式でも FastAPI-MCP 側の設定は同じHTTPBearer + AuthConfig)なので途中で方式を差し替え可能。 (GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)</small>

2. 実装パターン別サンプル

2-1. 固定トークン(最速)

# settings.py
API_TOKEN = "super-secret-dev-token"  # .env などで管理
from fastapi.security import HTTPBearer
from fastapi import Depends, HTTPException, status

token_auth = HTTPBearer()

def verify_fixed(creds = Depends(token_auth)):
    if creds.credentials != settings.API_TOKEN:
        raise HTTPException(status.HTTP_401_UNAUTHORIZED, "Invalid token")

verify_fixedAuthConfig(dependencies=[Depends(verify_fixed)]) に渡すだけで、無効トークンを 401 にできます。 (fastapi_mcp/examples/08_auth_example_token_passthrough.py at main · tadata-org/fastapi_mcp · GitHub, Security Tools - FastAPI)

2-2. Opaque ランダムトークン

import secrets, datetime
from pydantic import BaseModel
from fastapi import FastAPI, Depends, HTTPException, status

app = FastAPI()
DB = {}                   # 例: {token: expire_at}

class TokenResp(BaseModel):
    access_token: str
    token_type: str = "bearer"
    expires_in: int       # 秒

@app.post("/token", response_model=TokenResp)
def issue_token():
    token = secrets.token_urlsafe(32)         # 256bit 相当 ([secrets — Generate secure random numbers for managing secrets ...](https://docs.python.org/3/library/secrets.html?utm_source=chatgpt.com))
    expire = datetime.datetime.utcnow() + datetime.timedelta(hours=2)
    DB[token] = expire
    return TokenResp(access_token=token, expires_in=7200)

検証側は DB で有効期限を確認するだけ。UUID を使う場合は uuid.uuid4().hex でも構いませんが、ビット長は 128bit なので URL-safe トークンより衝突耐性が低くなります。 (uuid — UUID objects according to RFC 4122 — Python 3.13.3 ..., How to generate a unique auth token in python? - Stack Overflow)

2-3. JWT アクセストークン

from datetime import datetime, timedelta, timezone
import jwt                # pip install PyJWT
from fastapi.security import OAuth2PasswordRequestForm

SECRET_KEY = "openssl rand -hex 32 で生成"
ALGORITHM   = "HS256"
EXPIRE_MIN  = 30

@app.post("/token", response_model=TokenResp)
def login(form_data: OAuth2PasswordRequestForm = Depends()):
    # ①ユーザ認証(省略)…
    to_encode = {
        "sub": form_data.username,
        "exp": datetime.now(timezone.utc) + timedelta(minutes=EXPIRE_MIN)
    }
    token = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return TokenResp(access_token=token, expires_in=EXPIRE_MIN*60)

検証は jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) で署名と exp をまとめて確認。FastAPI 公式チュートリアルと同一の流れなので学習コストが低いです。 (OAuth2 with Password (and hashing), Bearer with JWT tokens - FastAPI, Securing FastAPI with JWT Token-based Authentication | TestDriven.io)

3. FastAPI-MCP への組み込み手順

from fastapi_mcp import FastApiMCP, AuthConfig
from fastapi.security import HTTPBearer
from fastapi import Depends

app = FastAPI()
bearer = HTTPBearer()
mcp = FastApiMCP(
    app,
    name="Protected MCP",
    auth_config=AuthConfig(
        dependencies=[Depends(bearer)]   # ← トークン検証 Depends を渡す
    )
)
mcp.mount()

4. セキュリティ運用メモ

注意点 解説
秘密鍵/固定トークンは環境変数で管理 Git に残さず .env + secret manager を使う。 (How to Use FastAPI MCP Server: A Complete Guide - Hugging Face)
有効期限の短縮とリフレッシュ JWT は exp 付き、Opaque は DB で失効時間を管理し次回発行で更新。 (OAuth2 with Password (and hashing), Bearer with JWT tokens - FastAPI)
トークンの送信は常に TLS 上で Bearer トークンは窃取すると即再利用できるため。 ([Securing FastAPI with JWT Token-based Authentication
監査/失効リスト Opaque なら DB 削除、JWT なら JTI + deny-list か key rotation で対応。 (Generating UUID for API tokens in Python - Stack Overflow)
将来的な OAuth2 移行 FastAPI-MCP は AuthConfig(setup_proxies=True) で後付け OAuth2 にもスムーズに移行可。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub)

5. まとめ

  • とりあえず動かす → 固定トークン or secrets.token_urlsafe() を発行し、HTTPBearer で検証。
  • 長期運用 → PyJWT などで署名付き JWT を /token エンドポイントで発行し、期限切れ・署名検証を統合。
  • FastAPI-MCP 側の設定は一定──AuthConfig(dependencies=[Depends(bearer)]) とヘッダ透過だけで済むので、将来 OAuth2/OIDC に切り替える場合もアプリ側のトークン発行ロジックを置き換えるだけで完結します。 (GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)
まさぴょん🐱まさぴょん🐱

FastAPI-MCPの特徴や使い方📝

以下では FastAPI-MCP の 「何ができるか」「どう使うか」「内部でどう動いているか」を一望できるように、要点とコード/構成をまとめた表を交えつつ解説します。

ポイントだけ先に押さえると
①既存 FastAPI API をほぼコード変更なしで MCP ツール化できる
②ASGI 直結で高速
③FastAPI の依存解決や OAuth をそのまま活かせる

――という 3 つが最大の売りです。
これにより LLM/AI エージェントが “あなたの API” を即座にツールとして呼び出せるようになります。 (tadata-org/fastapi_mcp: Expose your FastAPI endpoints as ... - GitHub, GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)

1. 概要・特徴早見表

項目 内容 補足
主目的 FastAPI エンドポイントを Model Context Protocol (MCP) ツールとして自動公開 Swagger のスキーマ・説明も保持するため「ドキュメント → ツール」変換も同時に完了 (GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)
依存ライブラリ fastapi (>=0.110) / pydantic / httpx ほか PyPI では fastapi-mcp==0.3.3 が最新(2025-04-23 リリース) (fastapi-mcp · PyPI)
主要機能 * ASGI 直結トランスポート
* 認証ヘッダ・OAuth2 透過
* スキーマ保持
* 0 設定でのマウント
詳細は次章の「機能別まとめ」参照 (fastapi_mcp/docs/advanced/transport.mdx at main · tadata-org/fastapi_mcp · GitHub, fastapi_mcp/docs/advanced/auth.mdx at main · tadata-org/fastapi_mcp · GitHub)
導入コマンド pip install fastapi-mcp または uv add fastapi-mcp uv のほうが高速に依存解決 (GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)
最小実装 mcp = FastApiMCP(app); mcp.mount() の 2 行 既存の FastAPI app をそのまま利用 (fastapi_mcp/docs/getting-started/quickstart.mdx at main · tadata-org/fastapi_mcp · GitHub)
想定ユースケース 既存 REST を Claude、Cursor、Windsurf 等の LLM エージェントに即公開 既製 API 資産の “AI ツール化” に最短距離 (How to Use FastAPI MCP Server: A Complete Guide - Hugging Face, Comparing Model Context Protocol (MCP) Server Frameworks)
ライセンス MIT (GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)

1-A. 機能別まとめ

機能カテゴリ 具体的なサポート内容 参考
トランスポート ASGI 呼び出しをデフォルト採用=HTTP ループ無しで高速。必要に応じ httpx.AsyncClient で外部 API へ委譲可能 (fastapi_mcp/docs/advanced/transport.mdx at main · tadata-org/fastapi_mcp · GitHub)
認証 * 単純ヘッダ透過
* AuthConfig で OAuth2 / OIDC メタデータを宣言的に設定
* FastAPI の Depends() をそのまま流用
(fastapi_mcp/docs/advanced/auth.mdx at main · tadata-org/fastapi_mcp · GitHub)
スキーマ保持 入出力 BaseModel 型、Description、Examples をそのまま MCP Tool Schema に反映 (GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)
デプロイ形態 ①同一アプリにサブパス /mcp でマウント
FastApiMCP(app, …).run() で別プロセス起動
(Releases · tadata-org/fastapi_mcp - GitHub)
開発体験 CLI/設定不要。examples/ に OAuth, SSE, Token Passthrough など実装例多数 (fastapi_mcp/docs/getting-started/quickstart.mdx at main · tadata-org/fastapi_mcp · GitHub)

2. 基本的な使い方(クイックスタート)

ステップ サンプルコード 説明
1. インストール pip install fastapi-mcp PyPI 版を取得 (fastapi-mcp · PyPI)
2. アプリ作成 python\nfrom fastapi import FastAPI\napp = FastAPI()\n 既存アプリでも可
3. MCP 化 python\nfrom fastapi_mcp import FastApiMCP\nmcp = FastApiMCP(app)\nmcp.mount()\n これで /mcp エンドポイントが生成される (fastapi_mcp/docs/getting-started/quickstart.mdx at main · tadata-org/fastapi_mcp · GitHub)
4. 起動 uvicorn main:app --reload uvicorn / Hypercorn など ASGI サーバなら何でも可
5. クライアント接続 json\n{\n \"mcpServers\":{\n \"fastapi-mcp\":{\"url\":\"http://localhost:8000/mcp\"}\n }\n}\n Claude Desktop や Cursor の config 例 (fastapi_mcp/docs/getting-started/quickstart.mdx at main · tadata-org/fastapi_mcp · GitHub)

3. 内部処理アーキテクチャ

レイヤ 主なクラス/処理 役割 技術ポイント
Router 生成 FastApiMCP.__init__ FastAPI app.routes を走査し、各 APIRouteMCP Tool に変換 スキーマ・ドキュメントをそのまま移植 (GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)
Transport 層 ASGITransport (デフォルト) LLM からの Tool 呼び出し → await app(scope, receive, send) で直接 ASGI 実行 HTTP ラウンドトリップ無しで高速応答 (fastapi_mcp/docs/advanced/transport.mdx at main · tadata-org/fastapi_mcp · GitHub)
依存解決 FastAPI Depends() 元 API の DI をそのまま利用。request.state なども透過 認証・DB セッション共有が可能 (fastapi_mcp/docs/advanced/auth.mdx at main · tadata-org/fastapi_mcp · GitHub)
認証 / OAuth AuthConfig dataclass * ヘッダ検証
* OAuth メタデータ自動生成
* /oauth/authorize エンドポイント生成
MCP 仕様準拠のメタデータを自動配信 (fastapi_mcp/docs/advanced/auth.mdx at main · tadata-org/fastapi_mcp · GitHub)
Schema 出力 openapi_to_mcp() ユーティリティ FastAPI の OpenAPI スキーマ → MCP Tool Manifest へ変換 型コメント・例示も保持
クライアント互換 SSE と mcp-remote ブリッジ Cursor/Claude などの WebSocket 固定クライアントとも連携 ブリッジを通すことで OAuth 付きでも動作 (fastapi_mcp/docs/getting-started/quickstart.mdx at main · tadata-org/fastapi_mcp · GitHub)

4. 運用ベストプラクティス & 限界

推奨事項 背景・理由
スコープの狭い Depends() に切り出す DI を保つことで、MCP ツール呼び出しでも同じセキュリティ・DB コンテキストを共有可能 (fastapi_mcp/docs/advanced/auth.mdx at main · tadata-org/fastapi_mcp · GitHub)
ASGI トランスポートを第一選択に 最速だが、別サービスの API をまとめてツール化したい場合は httpx.AsyncClient でプロキシしても良い (fastapi_mcp/docs/advanced/transport.mdx at main · tadata-org/fastapi_mcp · GitHub)
OpenAPI の description を丁寧に書く LLM が Tool schema の説明をそのまま読みに行くため、プロンプト品質が上がる (GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)
既存 REST の置き換えではなく “公開” と割り切る REST → Tool 変換なので idempotency や認証等は元 API のポリシーに準拠させる必要がある。設計を変えずに AI 利用を広げるのがベター (Comparing Model Context Protocol (MCP) Server Frameworks)
規模が大きい場合は FastMCP も比較検討 FastMCP は OpenAPI からのバルク生成やプロキシ合成が得意。要件で使い分けを (jlowin/fastmcp: The fast, Pythonic way to build MCP servers and clients, fastmcp - PyPI)

5. 参考リンク(追加で読むと理解が深まる文書)


これで FastAPI-MCP の全体像・使い方・内部処理 を網羅的に俯瞰できるはずです。既存 FastAPI プロジェクトを AI ツール化したい場合は、まず FastApiMCP(app).mount() を付け足して試してみるのが最速の第一歩です。

まさぴょん🐱まさぴょん🐱

FastApiMCP Serverの設定について調査

FastApiMCPサーバーが標準で「stdio」か「SSE」かについて調査📝

FastApiMCP(app).mount()で呼ぶと「SSE」モードになる📝

FastApiMCP(app).mount() を呼び出すと、アプリのルート配下に自動で /mcp(イベントストリーム)、/mcp/schema/mcp/jsonrpc という 3 つのエンドポイントが生えます。
外部クライアントは Server-Sent Events (SSE)/mcp に接続し、双方向にメッセージをやり取りします。公式ドキュメントにも “Connect to the MCP Server using SSE” と明記されています。

https://pypi.org/project/fastapi-mcp/0.3.0/

stdio と SSE ― どちらを選ぶ?

項目 stdio (FastMCP) SSE (FastApiMCP)
通信経路 標準入出力(同一プロセス内) HTTP+SSE(ネットワーク越しにストリーミング)
想定クライアント ローカル CLI/LLM プラグイン
(Cursor など SSE 非対応 クライアントは mcp-proxy でラップ可)
Cursor, Claude Desktop†, 自作 Web UI 等
並列処理 1 接続(=1 LLM)を想定 複数同時接続・ブラウザからのイベント駆動
デプロイ Python スクリプト単体で実行可 ASGI サーバ(Uvicorn など)に載せて公開
典型パターン 👉 LLM をローカル起動し“ツール”として使いたい 👉 SaaS 型 API を公開したい、チーム/顧客と共有したい

†SSE 非対応のクライアント → mcp-proxy/mcp を stdio に変換すれば利用可能です。([PyPI][1])

それぞれのスタータ実装

1. stdio サーバ(mcp.server.fastmcp.FastMCP

# server_stdio.py
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Demo")

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

if __name__ == "__main__":
    mcp.run()         # 標準入出力で待ち受け

実行例

python server_stdio.py           # 直接起動
# あるいは
mcp run server_stdio.py          # CLI から起動

([GitHub][2])

2. SSE サーバ(FastAPI + FastApiMCP)

# main.py  ※ご質問のコードを簡略化
from fastapi import FastAPI, Depends
from fastapi_mcp import FastApiMCP, AuthConfig

app = FastAPI(title="FastAPI MCP Template")

# 認証 (API Key) を FastAPI 側で実装
async def verify_api_key():
    ...

# 既存ルート
@app.get("/hello", operation_id="say_hello")
async def hello():
    return {"message": "Hello World"}

# MCP サーバを FastAPI にマウント
mcp = FastApiMCP(
    app,
    name="FastAPI MCP Server",
    auth_config=AuthConfig(dependencies=[Depends(verify_api_key)])  # ← /mcp 系にも認証を付与したい場合
)
mcp.mount(prefix="/mcp")   # 省略時は '/mcp'

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

起動後:

  • GET /mcp   … SSE ストリーム
  • GET /mcp/schema … OpenAPI 相当の MCP スキーマ
  • POST /mcp/jsonrpc … JSON-RPC 呼び出し

クライアント設定例 (Cursor):

{
  "mcpServers": {
    "my-api": {
      "url": "http://localhost:8000/mcp"
    }
  }
}

SSE が使えないクライアントの場合は:

uv run mcp-proxy http://localhost:8000/mcp  # SSE→stdio 変換プロキシ

まとめ

  • FastApiMCP = SSE サーバ。ネットワーク公開・複数接続が欲しい場合はこちらを採用。
  • 単体バイナリ/ローカル利用が主目的なら FastMCP (stdio) が最小構成で便利。
  • どちらの実装でも ツール / リソース / プロンプト デコレータは共通なので、まずはローカルで stdio 版を作り、デプロイ段階で SSE 版に載せ替えるフローがスムーズです。