mcp-builder について
mcp-builder は、必要な機能の説明から MCP サーバーを作る開発者向けスキルです。FastMCP の Python サーバー作成、テスト、デプロイを案内し、ツール、リソース、プロンプトの設計例を含みます。
主な機能
- 01ツール、リソース、プロンプトの定義
- 02FastMCP の Python サーバー作成
- 03ローカル実行と自動テスト
- 04デプロイ前確認と問題の診断
- 05クラウド、Docker、エッジへのデプロイ
- 06任意の連携コマンドラインスクリプト
活用シーン
- 01顧客データベース検索の要件を MCP サーバー化
- 02サーバーのツールとリソースをローカルで確認
- 03リモートクライアント向け HTTP サーバーのデプロイ
- 04サーバーツール用のコマンドラインスクリプト追加
MCP 対応
MCP クライアント向けのサーバー構築と、公開するツール、リソース、プロンプトの定義を案内します。FastMCP Client によるテストや stdio、HTTP トランスポートも扱います。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jezweb/ claude-skills --skill mcp-builderインストール後、Claude Code で/mcp-builderを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/api-client-pattern.pybasic-server.pyclient-example.pyerror-handling.pyopenapi-integration.pyprompts-examples.pypyproject.tomlrequirements.txtresources-examples.pyscript-template.tsSCRIPTS-TEMPLATE.mdself-contained-server.pytools-examples.pyreferences/integration-patterns.md詳細
MCP ビルダー
必要なツールの説明から、動作する MCP サーバーを構築します。FastMCP を使用した、デプロイ可能な Python サーバーを生成します。
ワークフロー
ステップ 1:公開する内容を定義する
サーバーが何を提供する必要があるかを確認します。
- ツール -- Claude が呼び出せる関数(API ラッパー、計算、ファイル操作)
- リソース -- Claude が読み取れるデータ(データベースのレコード、設定、ドキュメント)
- プロンプト -- パラメーター付きの再利用可能なプロンプトテンプレート
「顧客データベースを検索する MCP サーバー」のような簡単な説明で十分です。
ステップ 2:サーバーのひな形を作成する
pip install fastmcp
サーバーファイルを作成します。サーバーインスタンスは必ずモジュールレベルに置いてください。
from fastmcp import FastMCP
# MUST be at module level for FastMCP Cloud
mcp = FastMCP("My Server")
@mcp.tool()
async def search_customers(query: str) -> str:
"""Search customers by name or email."""
# Implementation here
return f"Found customers matching: {query}"
@mcp.resource("customers://{customer_id}")
async def get_customer(customer_id: str) -> str:
"""Get customer details by ID."""
return f"Customer {customer_id} details"
if __name__ == "__main__":
mcp.run()
ステップ 3:補助的な CLI スクリプトを追加する(任意)
Claude Code のターミナルで使用する場合は、MCP サーバーと同じ場所にスクリプトを追加します。
my-mcp-server/
├── src/index.ts # MCP server (for Claude.ai)
├── scripts/
│ ├── search.ts # CLI version of search tool
│ └── _shared.ts # Shared auth/config
├── SCRIPTS.md # Documents available scripts
└── package.json
CLI スクリプトを使うと、ファイルの入出力、バッチ処理、MCP では対応できない詳細な出力が可能になります。
TypeScript のテンプレートについては、assets/SCRIPTS-TEMPLATE.md と assets/script-template.ts を参照してください。
ステップ 4:ローカルでテストする
クイックテスト -- 直接実行:
python server.py
インスペクター UI を使った開発モード(推奨):
fastmcp dev server.py
# Opens inspector at http://localhost:5173
# Hot reload, detailed logging, tool/resource inspection
リモートクライアント用の HTTP モード:
python server.py --transport http --port 8000
FastMCP クライアントを使った自動テストスクリプト:
import asyncio
from fastmcp import Client
async def test_server(server_path):
async with Client(server_path) as client:
# List everything
tools = await client.list_tools()
resources = await client.list_resources()
prompts = await client.list_prompts()
print(f"Tools: {[t.name for t in tools]}")
print(f"Resources: {[r.uri for r in resources]}")
print(f"Prompts: {[p.name for p in prompts]}")
# Call first tool
if tools:
result = await client.call_tool(tools[0].name, {})
print(f"Tool result: {result}")
# Read first resource
if resources:
data = await client.read_resource(resources[0].uri)
print(f"Resource data: {data}")
asyncio.run(test_server("server.py"))
ステップ 5:デプロイ前のチェックリスト
デプロイ前に、以下のチェックを実行してください。必須のチェックはすべて合格する必要があります。
必須(デプロイ失敗の原因になります):
- サーバーファイルが存在する
- Python の構文が有効である:
python3 -m py_compile server.py - モジュールレベルにサーバーオブジェクトがある(関数内ではない):
grep -q "^mcp = FastMCP\|^server = FastMCP\|^app = FastMCP" server.py requirements.txtが存在し、PyPI パッケージのみが記載されている(git+、-e、.whl、.tar.gzは不可)- ハードコードされたシークレットがない(
os.getenv/os.environを除き、api_key = "..."のパターンを確認する)
参考(警告):
requirements.txtにfastmcpが記載されている.gitignoreに.envが含まれている- 循環インポートがない
- リモートを設定した Git リポジトリが初期化されている
- サーバーを読み込める:
timeout 5 fastmcp inspect server.py
ステップ 6:デプロイする
FastMCP Cloud(最も簡単):
git add . && git commit -m "Ready for deployment"
git push -u origin main
# Visit https://fastmcp.cloud, connect repo, add env vars, deploy
# URL: https://your-project.fastmcp.app/mcp
Cloud の要件:
mcp、server、appのいずれかという名前のモジュールレベルのサーバーオブジェクトrequirements.txtに記載するのは PyPI の依存関係のみ- 公開 GitHub リポジトリ
- シークレットには環境変数を使用(値をハードコードしない)
- main へのプッシュで自動デプロイ、PR のプレビュー環境をデプロイ
Docker(セルフホスト):
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "server.py", "--transport", "http", "--port", "8000"]
Cloudflare Workers(エッジ):
Cloudflare の agents SDK(McpAgent)を使って TypeScript で構築します。最新のテンプレートについては、Cloudflare のリモート MCP サーバーのドキュメントを参照してください。
重要なパターン
モジュールレベルのサーバーインスタンス
FastMCP Cloud では、サーバーインスタンスをモジュールレベルに置く必要があります。
# CORRECT
mcp = FastMCP("My Server")
@mcp.tool()
def my_tool(): ...
# WRONG -- Cloud can't find the server
def create_server():
mcp = FastMCP("My Server")
return mcp
# FIX for factory pattern -- export at module level
def create_server() -> FastMCP:
mcp = FastMCP("server")
return mcp
mcp = create_server()
型アノテーションが必須
FastMCP は、ツールのスキーマを生成するために型アノテーションを使用します。
@mcp.tool()
async def search(
query: str, # Required parameter
limit: int = 10, # Optional with default
tags: list[str] = [] # Complex types supported
) -> str:
"""Docstring becomes the tool description."""
...
エラー処理
例外を発生させず、エラーを文字列として返してください。
@mcp.tool()
async def get_data(id: str) -> str:
try:
result = await fetch_data(id)
return json.dumps(result)
except NotFoundError:
return f"Error: No data found for ID {id}"
Cloud 対応のサーバーパターン
import os
from fastmcp import FastMCP
mcp = FastMCP("production-server")
API_KEY = os.getenv("API_KEY")
@mcp.tool()
async def production_tool(data: str) -> dict:
if not API_KEY:
return {"error": "API_KEY not configured"}
return {"status": "success", "data": data}
if __name__ == "__main__":
mcp.run()
よくあるエラーと修正方法
以下のエラーが発生します。デプロイする前に修正してください。
| エラー | 原因 | 修正方法 |
|---|---|---|
RuntimeError: No server object found at module level | サーバーが関数内にある | モジュールレベルで mcp = FastMCP(...) をエクスポートします |
RuntimeError: no running event loop | async/await が不足している | 非同期処理には async def を使用します |
TypeError: missing required argument 'context' | Context に型ヒントが付いていない | 型ヒントとして context: Context を追加します |
ValueError: Invalid resource URI | URI スキームが不足している | data://、file://、info://、api:// を使用します |
| リソーステンプレートのパラメーター不一致 | 名前が一致していない | user://{user_id} には def get_user(user_id: str) が必要です |
| Pydantic の検証エラー | 型ヒントが誤っている | ヒントが実際のデータ型と一致していることを確認します |
| トランスポートの不一致 | クライアントとサーバーのプロトコルが異なる | 両方を stdio、または両方を http に揃えます |
| 編集可能パッケージでのインポートエラー | パッケージがインストールされていない | pip install -e . を実行するか、PYTHONPATH に追加します |
DeprecationWarning: mcp.settings | 古い API | 代わりに os.getenv() を使用します |
| ポートがすでに使用中 | 古いプロセスが残っている | lsof -ti:8000 | xargs kill -9 を実行します |
| スキーマ生成の失敗 | JSON 非対応の型 | JSON 互換の型を使用します(NumPy 配列は使用しません) |
| JSON シリアライズエラー | レスポンスに datetime/bytes が含まれている | .isoformat() または文字列に変換します |
| 循環インポート | __init__.py にファクトリーがある | 直接インポートを使用し、ファクトリーパターンは避けます |
| Python 3.12+ の datetime 警告 | datetime.utcnow() は非推奨 | datetime.now(timezone.utc) を使用します |
| インポート時の実行 | モジュールレベルに非同期リソースがある | 遅延初期化パターンを使用します |
本番環境向けパターン
自己完結型サーバー
循環インポートを避けるため、すべてのユーティリティを1つのファイルにまとめます。
from fastmcp import FastMCP
import os
mcp = FastMCP("my-server")
# Config
class Config:
API_KEY = os.getenv("API_KEY", "")
BASE_URL = os.getenv("BASE_URL", "https://api.example.com")
# Helpers
def format_success(data): return {"status": "success", "data": data}
def format_error(msg): return {"status": "error", "message": msg}
@mcp.tool()
async def my_tool(query: str) -> dict:
if not Config.API_KEY:
return format_error("API_KEY not configured")
return format_success({"query": query})
遅延初期化
モジュールレベルで非同期リソースを作成しないでください。初回使用時に初期化します。
_db = None
async def get_db():
global _db
if _db is None:
_db = await create_connection(Config.DB_URL)
return _db
ヘルスチェック用リソース
@mcp.resource("health://status")
async def health_check() -> dict:
return {
"status": "healthy",
"version": "1.0.0",
"checks": {
"api": "connected",
"database": "connected"
}
}
コネクションプーリング
import httpx
_client = None
def get_client() -> httpx.AsyncClient:
global _client
if _client is None:
_client = httpx.AsyncClient(
base_url=Config.BASE_URL,
headers={"Authorization": f"Bearer {Config.API_KEY}"},
limits=httpx.Limits(max_connections=20, max_keepalive_connections=5),
timeout=30.0
)
return _client
バックオフ付きリトライ
async def retry_with_backoff(func, max_retries=3, initial_delay=1.0):
for attempt in range(max_retries):
try:
return await func()
except Exception as e:
if attempt == max_retries - 1:
raise
delay = initial_delay * (2 ** attempt)
await asyncio.sleep(delay)
コンテキスト機能(上級)
コンテキストの注入
from fastmcp import Context
@mcp.tool()
async def tool_with_context(param: str, context: Context) -> dict:
# Context parameter MUST have type hint
pass
進行状況の追跡
@mcp.tool()
async def long_task(items: list[str], context: Context) -> str:
for i, item in enumerate(items):
await context.report_progress(i + 1, len(items), f"Processing {item}")
await process(item)
return "Done"
サンプリング(ツール内からの LLM 呼び出し)
@mcp.tool()
async def summarise(text: str, context: Context) -> str:
result = await context.request_sampling(
messages=[{"role": "user", "content": f"Summarise: {text}"}],
max_tokens=200
)
return result
CLI クイックリファレンス
fastmcp dev server.py # Dev mode with inspector UI
fastmcp run server.py # Run (stdio)
fastmcp run server.py --transport http --port 8000 # Run (HTTP)
fastmcp inspect server.py # Inspect without running
fastmcp install server.py # Install to Claude Desktop
fastmcp deploy server.py --name my-server # Deploy to Cloud
環境変数:FASTMCP_LOG_LEVEL(DEBUG/INFO/WARNING/ERROR)、FASTMCP_ENV(development/staging/production)。
統合パターン(任意)
具体的な統合方法については、references/integration-patterns.md を参照してください。
- 手動 API -- 再利用可能なクライアントを使った
httpx.AsyncClient - OpenAPI の自動生成 --
FastMCP.from_openapi(spec, client, route_maps=[...]) - FastAPI からの変換 --
FastMCP.from_fastapi(app)
アセットファイル
assets/basic-server.py-- FastMCP サーバーの最小テンプレートassets/self-contained-server.py-- ストレージとミドルウェアを備えたサーバーassets/tools-examples.py-- ツールのパターンと型アノテーションassets/resources-examples.py-- リソース URI のパターンassets/prompts-examples.py-- プロンプトテンプレートのパターンassets/client-example.py-- MCP クライアントの使用方法assets/SCRIPTS-TEMPLATE.md-- CLI 関連ドキュメントのテンプレートassets/script-template.ts-- TypeScript CLI スクリプトのテンプレート