本記事では、Anthropic社が策定したModel Context Protocol(MCP)のPython実装フレームワークFastMCPを使い、本番レベルのMCPサーバーを構築する方法を解説します。私は過去に3つのMCPサーバーを本番運用してきた経験から、単なるHello Worldではなく、アーキテクチャ設計・認証・パフォーマンス計測・コスト最適化まで踏み込んだ内容をお届けします。
MCPとFastMCPの位置づけ
MCP(Model Context Protocol)は、大規模言語モデル(LLM)に対して構造化されたツール呼び出しとコンテキスト供給を標準化するプロトコルです。2024年末に公開されて以降、Cursor・Claude Desktop・Cline・Roo Codeなど主要クライアントが対応し、エコシステムが急成長しています。
FastMCPは、Pythonの型ヒントとデコレータを最大限活用してMCPサーバーを書けるようにする高水準フレームワークです。トランスポート層(stdio / SSE / Streamable HTTP)の詳細を抽象化してくれるため、私はツールロジックの実装に集中できます。
アーキテクチャ設計:3層構成
私が本番で採用しているのは、以下の3層構成です。
- Edge層:nginxでTLS終端とレート制限
- App層:FastMCP本体 + 非同期ツール実装(asyncio)
- Storage層:Redis(セッション・キャッシュ) + PostgreSQL(永続データ)
認証はBearer Token方式を基本とし、ツール単位でスコープを絞ります。例えば「DB読み取り専用ツール」と「DB書き込みツール」で別スコープを割り当て、最小権限の原則を徹底します。
実装:本番レベルのFastMCPサーバー
まず、依存関係をインストールします。
pip install fastmcp uvicorn redis asyncpg python-jose[cryptography] httpx
次に、server.py本体です。HolySheep AIのLLM API(base_urlは https://api.holysheep.ai/v1)をMCPのcompleteツール経由で利用できるようにします。
import os
import asyncio
import time
import httpx
from fastmcp import FastMCP, Context
from jose import jwt, JWTError
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"
HOLYSHEEP_API_KEY = os.environ["YOUR_HOLYSHEEP_API_KEY"]
JWT_SECRET = os.environ["MCP_JWT_SECRET"]
JWT_ALG = "HS256"
mcp = FastMCP("HolySheep-MCP-Server")
---- 認証ミドルウェア相当(ツール実行前に毎回呼ぶ) ----
def require_scope(required: str):
def decorator(tool_fn):
async def wrapper(ctx: Context, *args, **kwargs):
token = ctx.request.headers.get("authorization", "").replace("Bearer ", "")
try:
claims = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALG])
except JWTError:
raise PermissionError("invalid_token")
if required not in claims.get("scopes", []):
raise PermissionError(f"missing_scope:{required}")
ctx.state["user_id"] = claims["sub"]
return await tool_fn(ctx, *args, **kwargs)
wrapper.__name__ = tool_fn.__name__
return wrapper
return decorator
---- LLM呼び出し(HolySheepへの中継) ----
async def call_holysheep(model: str, prompt: str, max_tokens: int = 512) -> dict:
async with httpx.AsyncClient(timeout=30.0) as client:
t0 = time.perf_counter()
resp = await client.post(
f"{HOLYSHEEP_BASE_URL}/chat/completions",
headers={"Authorization": f"Bearer {HOLYSHEEP_API_KEY}"},
json={
"model": model,
"messages": [{"role": "user", "content": prompt}],
"max_tokens": max_tokens,
"temperature": 0.2,
},
)
resp.raise_for_status()
data = resp.json()
data["_latency_ms"] = round((time.perf_counter() - t0) * 1000, 2)
return data
---- MCPツール定義 ----
@mcp.tool()
@require_scope("llm:invoke")
async def complete(ctx: Context, model: str, prompt: str) -> dict:
"""HolySheep AI経由でテキスト生成するツール"""
result = await call_holysheep(model, prompt)
return {
"model": model,
"content": result["choices"][0]["message"]["content"],
"usage": result["usage"],
"latency_ms": result["_latency_ms"],
}
@mcp.tool()
async def list_models(ctx: Context) -> list:
"""利用可能モデルとoutput価格(USD / 1Mトークン)を返す"""
return [
{"id": "gpt-4.1", "output_usd_per_mtok": 8.00},
{"id": "claude-sonnet-4.5", "output_usd_per_mtok": 15.00},
{"id": "gemini-2.5-flash", "output_usd_per_mtok": 2.50},
{"id": "deepseek-v3.2", "output_usd_per_mtok": 0.42},
]
if __name__ == "__main__":
# Streamable HTTPで配信(本番推奨)
mcp.run(transport="streamable-http", host="0.0.0.0", port=8080)
デプロイとパフォーマンスチューニング
デプロイはsystemdユニット + nginxリバースプロキシの組み合わせが安定します。Streamable HTTPを使う場合、nginx側でproxy_buffering off;を必ず設定してください。これを忘れるとMCPのストリーミングが体感で3〜5倍遅くなります。
# /etc/nginx/sites-available/mcp.conf
server {
listen 443 ssl http2;
server_name mcp.example.com;
ssl_certificate /etc/letsencrypt/live/mcp.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mcp.example