fastmcp について
FastMCPは、LLMクライアントにツール、リソース、プロンプトを公開するMCPサーバーを構築するPythonフレームワークです。CLI、サーバー合成、ミドルウェア、デプロイのパターンを備えています。
主な機能
- 01デコレーターでツール、リソース、プロンプトを定義
- 02型ヒントとPydanticによる入力検証
- 03進捗報告とユーザー入力要求に対応
- 04組み込みおよびカスタムミドルウェア
- 05サーバーのインポートと動的マウント
活用シーン
- 01Python関数をMCPツールとして公開
- 02クライアントに静的または動的リソースを提供
- 03進捗更新付きのバッチ処理を構築
- 04CLIでサーバーの開発、テスト、デプロイ
MCP 対応
FastMCPは、MCPクライアントにツール、リソース、プロンプトを公開するMCPサーバーを構築します。ローカル実行とHTTPトランスポートに対応します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill fastmcpインストール後、Claude Code で/fastmcpを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/cli-commands.mdcloud-deployment.mdcommon-errors.mdcontext-features.mderror-catalog.mdintegration-patterns.mdproduction-patterns.mdscripts/check-versions.shdeploy-cloud.shtest-server.shtemplates/.env.exampleapi-client-pattern.pybasic-server.pyclient-example.pyerror-handling.pyopenapi-integration.pyprompts-examples.pypyproject.tomlrequirements.txtresources-examples.pyself-contained-server.pytools-examples.py詳細
FastMCP - Python で MCP サーバーを構築
FastMCP は、Claude のような大規模言語モデルにツール、リソース、プロンプトを公開する Model Context Protocol(MCP)サーバーを構築するための Python フレームワークです。
クイックスタート
インストール
pip install fastmcp
# or: uv pip install fastmcp
最小限のサーバー
from fastmcp import FastMCP
# MUST be at module level for FastMCP Cloud
mcp = FastMCP("My Server")
@mcp.tool()
async def hello(name: str) -> str:
"""Say hello to someone."""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run()
実行:
python server.py # Local development
fastmcp dev server.py # With FastMCP CLI
python server.py --transport http --port 8000 # HTTP mode
コピーして使えるテンプレート:templates/basic-server.py を参照してください。
主な概念
ツール
LLM が呼び出せる関数です。
@mcp.tool()
def calculate(operation: str, a: float, b: float) -> float:
"""Perform mathematical operations."""
operations = {
"add": lambda x, y: x + y,
"subtract": lambda x, y: x - y,
"multiply": lambda x, y: x * y,
"divide": lambda x, y: x / y if y != 0 else None
}
return operations.get(operation, lambda x, y: None)(a, b)
ベストプラクティス:
- 明確で説明的な関数名にする
- 包括的な docstring を記述する(LLM はこれを読みます!)
- 強い型ヒントを付ける(Pydantic が自動で検証します)
- 構造化データ(dict/list)を返す
- エラーを適切に処理する
リソース
静的または動的なデータを公開します。
@mcp.resource("data://config")
def get_config() -> dict:
"""Provide application configuration."""
return {"version": "1.0.0", "features": ["auth", "api"]}
# Dynamic resource with parameters
@mcp.resource("user://{user_id}/profile")
async def get_user_profile(user_id: str) -> dict:
"""Get user profile by ID."""
return {"id": user_id, "name": f"User {user_id}"}
URI スキーム:data://、file://、resource://、info://、api://、またはカスタムスキーム
プロンプト
LLM 用の事前設定済みプロンプトです。
@mcp.prompt("analyze")
def analyze_prompt(topic: str) -> str:
"""Generate analysis prompt."""
return f"""Analyze {topic} considering:
1. Current state
2. Challenges
3. Opportunities
4. Recommendations"""
コンテキスト機能
進行状況の追跡:
from fastmcp import Context
@mcp.tool()
async def batch_process(items: list, context: Context) -> dict:
"""Process items with progress updates."""
for i, item in enumerate(items):
await context.report_progress(i + 1, len(items), f"Processing {item}")
await process_item(item)
return {"processed": len(items)}
ユーザー入力:
@mcp.tool()
async def confirm_action(action: str, context: Context) -> dict:
"""Perform action with user confirmation."""
confirmed = await context.request_elicitation(
prompt=f"Confirm {action}? (yes/no)",
response_type=str
)
return {"confirmed": confirmed.lower() == "yes"}
ストレージバックエンド
デプロイ方法に合わせてストレージを選択します。
from key_value.stores import DiskStore, RedisStore
from key_value.encryption import FernetEncryptionWrapper
from cryptography.fernet import Fernet
# Memory (default) - Development only
mcp = FastMCP("Dev Server")
# Disk - Single instance
mcp = FastMCP(
"Production Server",
storage=FernetEncryptionWrapper(
key_value=DiskStore(path="/var/lib/mcp/storage"),
fernet=Fernet(os.getenv("STORAGE_ENCRYPTION_KEY"))
)
)
# Redis - Multi-instance
mcp = FastMCP(
"Production Server",
storage=FernetEncryptionWrapper(
key_value=RedisStore(
host=os.getenv("REDIS_HOST"),
password=os.getenv("REDIS_PASSWORD")
),
fernet=Fernet(os.getenv("STORAGE_ENCRYPTION_KEY"))
)
)
サーバーのライフスパン
サーバーの起動時にリソースを初期化します。
from contextlib import asynccontextmanager
@asynccontextmanager
async def app_lifespan(server: FastMCP):
"""Runs ONCE when server starts (v2.13.0+)."""
db = await Database.connect()
print("Server starting")
try:
yield {"db": db}
finally:
await db.disconnect()
print("Server stopping")
mcp = FastMCP("My Server", lifespan=app_lifespan)
重要:v2.13.0 以降では、ライフスパンはセッションごとではなく、サーバーごとに実行されます。セッションごとのロジックにはミドルウェアを使用してください。
ミドルウェアシステム
8 種類の組み込みミドルウェアがあります。
from fastmcp.middleware import (
LoggingMiddleware,
TimingMiddleware,
RateLimitingMiddleware,
ResponseCachingMiddleware
)
# Order matters!
mcp.add_middleware(LoggingMiddleware())
mcp.add_middleware(TimingMiddleware())
mcp.add_middleware(RateLimitingMiddleware(max_requests=100, window_seconds=60))
mcp.add_middleware(ResponseCachingMiddleware(ttl_seconds=3600))
カスタムミドルウェア:
from fastmcp.middleware import BaseMiddleware
class CustomMiddleware(BaseMiddleware):
async def on_call_tool(self, tool_name, arguments, context):
print(f"Before: {tool_name}")
result = await self.next(tool_name, arguments, context) # MUST call next()
print(f"After: {tool_name}")
return result
サーバーの構成
サーバーのインポート(静的、一度限りのコピー):
main_server.import_server(vendor_server) # Static bundle
サーバーのマウント(動的、実行時の委譲):
main_server.mount(api_server, prefix="api") # Changes appear immediately
クラウドへのデプロイ
FastMCP Cloud の要件:
- サーバーはモジュールレベルに MUST 配置する
- ディスク/Redis ストレージを使用する(メモリは使用しない)
- インポート時にコードを実行しない
# ✅ Cloud-ready pattern
mcp = FastMCP("My Server") # Module level
@mcp.tool()
async def my_tool(): pass
if __name__ == "__main__":
mcp.run()
デプロイ:
fastmcp deploy server.py
重大なエラー上位 5 件
1. サーバーオブジェクトがない
エラー: RuntimeError: No server object found at module level
修正方法:
# ❌ WRONG
def create_server():
return FastMCP("server")
# ✅ CORRECT
mcp = FastMCP("server") # At module level
2. Async/Await の混同
エラー: RuntimeError: no running event loop
修正方法:
# ❌ WRONG: Sync function calling async
@mcp.tool()
def bad_tool():
result = await async_function() # Error!
# ✅ CORRECT: Async tool
@mcp.tool()
async def good_tool():
result = await async_function()
return result
3. コンテキストが注入されない
エラー: TypeError: missing 1 required positional argument: 'context'
修正方法:
from fastmcp import Context
# ❌ WRONG: No type hint
@mcp.tool()
async def bad_tool(context): # Missing type!
await context.report_progress(...)
# ✅ CORRECT: Proper type hint
@mcp.tool()
async def good_tool(context: Context):
await context.report_progress(0, 100, "Starting")
4. ストレージバックエンドが設定されていない
エラー: RuntimeError: OAuth tokens lost on restart
修正方法: 本番環境ではディスクまたは Redis ストレージを使用してください(上記の「ストレージバックエンド」セクションを参照)。
5. 循環インポートエラー
エラー: ImportError: cannot import name 'X' from partially initialized module
修正方法:
# ❌ WRONG: Factory function creating circular dependency
# shared/__init__.py
def get_client():
from .api_client import APIClient # Circular!
return APIClient()
# ✅ CORRECT: Direct imports
# shared/__init__.py
from .api_client import APIClient
from .cache import CacheManager
# shared/monitoring.py
from .api_client import APIClient
client = APIClient()
エラー全 25 件を参照:references/error-catalog.md
クライアントの設定
Claude Desktop
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["/path/to/server.py"]
}
}
}
Claude Code CLI
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["server.py"]
}
}
}
CLI コマンド
fastmcp dev server.py # Development mode with hot reload
fastmcp run server.py # Production mode
fastmcp deploy server.py # Deploy to FastMCP Cloud
fastmcp test server.py # Run tests
ベストプラクティス
- サーバー構成:モジュールレベルにサーバーを置き、ツールは別のファイルに整理します
- 型ヒント:複雑な検証には Pydantic モデルを使用します
- ドキュメント:詳細な docstring を記述します(LLM はこれを読みます!)
- エラー処理:エラーを捕捉し、構造化された形式で返します
- ストレージ:本番環境では暗号化されたディスク/Redis を使用します
- ライフスパン:サーバーごとに接続を一度だけ初期化します
- ミドルウェア:順序が重要です(エラー処理 → タイミング計測 → ロギング → レート制限 → キャッシュ)
- テスト:
FastMCP.test_tool()でツールを単体テストします
同梱リソース
リファレンス(references/):
cli-commands.md- CLI コマンドの完全なリファレンス(dev、run、deploy、test)cloud-deployment.md- モジュールレベルの要件を含む FastMCP Cloud のデプロイガイドcommon-errors.md- 解決策と予防策を含む、文書化された25件のエラーすべてcontext-features.md- 進捗追跡、ユーザー入力、Context API のパターンerror-catalog.md- 修正方法を含む包括的なエラーカタログintegration-patterns.md- サーバーの合成(import/mount)、OAuth Proxy、OpenAPIproduction-patterns.md- ストレージバックエンド、ライフスパン、ミドルウェア、アーキテクチャパターン
テンプレート(templates/):
basic-server.py- ツール、リソース、プロンプトを備えた最小限の MCP サーバーclient-example.py- MCP クライアントの統合例api-client-pattern.py- API 統合パターンerror-handling.py- エラー処理のベストプラクティスopenapi-integration.py- OpenAPI スキーマの統合prompts-examples.py- プロンプトテンプレートのパターンresources-examples.py- リソース URI のパターンと例tools-examples.py- ツール定義のパターンself-contained-server.py- 本番環境に対応した、完全な自己完結型サーバー.env.example- 環境変数のテンプレートrequirements.txt- Python の依存関係pyproject.toml- Python プロジェクトの設定
依存関係
{
"dependencies": {
"fastmcp": ">=2.13.0",
"pydantic": ">=2.0.0"
},
"optionalDependencies": {
"py-key-value-aio": ">=0.1.0", // For storage backends
"cryptography": ">=41.0.0", // For encryption
"redis": ">=5.0.0" // For Redis storage
}
}
公式ドキュメント
- FastMCP GitHub:https://github.com/jlowin/fastmcp
- MCP Protocol:https://modelcontextprotocol.io
- FastMCP Cloud:https://fastmcp.com
検証チェックリスト
- FastMCP がインストールされている(
fastmcp>=2.13.0) - サーバーオブジェクトがモジュールレベルにある
- ツールの docstring が詳細に記述されている
- コンテキストパラメーターに Context の型ヒントがある
- リソース URI にスキームがある
- ストレージバックエンドが設定されている(本番環境)
- ライフスパンのパターンが適切である(v2.13.0+)
- ミドルウェアの順序に論理的な一貫性がある
- クライアント設定がテストされている
- 本番環境へのデプロイに成功している
トークンの節約:一から学ぶ場合と比べて90~95%
防止できるエラー:文書化された25件の問題
本番環境でのテスト:✅ 複数回のデプロイで検証済み