【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

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

FastAPI-MCP における認証実装の全体像について📝
以下は 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()
-
setup_proxies=True
で 動的クライアント登録(RFC 7591)のダミー実装 や audience/scope 補完 を/oauth/*
配下に生やします。 (fastapi_mcp/fastapi_mcp/auth/proxy.py at main · tadata-org/fastapi_mcp · GitHub, fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub) - MCP クライアント(例:
npx mcp-remote
)はmcp-remote http://localhost:8000/mcp 8080
のように固定ポートで起動し、IdP にはhttp://127.0.0.1:8080/oauth/callback
を登録します。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub)
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)
AuthConfig
主なフィールド一覧
3. フィールド | 必須? | 意味/補足 |
---|---|---|
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. 内部フロー解説
-
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) -
依存解決による認可
dependencies
で登録したDepends()
が 先に実行 され、失敗時はHTTPException(401/403)
→ MCP クライアントにエラー JSON が返り、自動的に OAuth フローやリトライが促されます。 (fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub) -
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) -
メタデータ供給
/\.well-known/oauth-authorization-server
に OIDC メタ JSON を配信。AuthConfig
で未指定の項目はデフォルト値(code
応答タイプなど)が自動補完されます。 (fastapi_mcp/fastapi_mcp/types.py at main · tadata-org/fastapi_mcp · GitHub)
5. ベストプラクティス & 注意点
-
DI 依存にロジックを集約 – 認証チェックは 必ず
Depends()
でラップし、ルート関数ではなく依存の中でエラーを返す。これが OAuth フロー開始トリガーになる。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub) -
クライアントが古い場合は
mcp-remote
を使う – 2025-03-26 版の MCP をフルに話せる実装がまだ少ないため、開発・テストでは公式サイドカーnpx mcp-remote
が無難。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub) -
IdP の callback URL –
mcp-remote
を固定ポートで起動し (8080
など)、IdP に同じ URL を事前登録する。ランダムポートのままではリダイレクトに失敗。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub) -
テスト用トークンの自動発行 – ローカル開発では FastAPI ルートで
/token
を用意し、テスト JWT を返すとクライアント設定が楽になる。FastAPI のOAuth2PasswordBearer
チュートリアルが流用可能。 (Simple OAuth2 with Password and Bearer - FastAPI)
これで 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_fixed
を AuthConfig(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()
- HTTPBearer 自体が Authorization ヘッダ欠如時に自動 403 を返す ため、検証依存を書かなくても「トークン必須」にはなります。 (Security Tools - FastAPI)
- MCP クライアント側は
--header "Authorization:Bearer <token>"
を付けるだけで通過します。 (fastapi_mcp/docs/03_authentication_and_authorization.md at main · tadata-org/fastapi_mcp · GitHub) - 例示コードは FastAPI-MCP リポジトリの
08_auth_example_token_passthrough.py
にもそのまま載っています。 (fastapi_mcp/examples/08_auth_example_token_passthrough.py at main · tadata-org/fastapi_mcp · GitHub)
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. 概要・特徴早見表
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 を走査し、各 APIRoute を MCP 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. 参考リンク(追加で読むと理解が深まる文書)
- GitHub README & Docs(公式) (GitHub - tadata-org/fastapi_mcp: Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!)
- PyPI パッケージ解説/リリース履歴 (fastapi-mcp · PyPI, fastapi-mcp - PyPI)
- Hugging Face Blog 「FastAPI MCP 完全ガイド」 (How to Use FastAPI MCP Server: A Complete Guide - Hugging Face)
- Medium 「FastAPI × MCP で天気通知ツールを作る」 (Implementing MCP(FastMCP) in a FastAPI Application - Medium)
- Medium 「MCP Server Framework 比較」 (Comparing Model Context Protocol (MCP) Server Frameworks)
これで 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” と明記されています。
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])
それぞれのスタータ実装
mcp.server.fastmcp.FastMCP
)
1. stdio サーバ(# 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 版に載せ替えるフローがスムーズです。