初めてのMCPサーバーの構築方法:ステップバイステップチュートリアル

前提条件
開始する前に、以下を準備してください:
- Python 3.10以上がインストールされていること
- Python関数と非同期コードの基本的な理解
- uv(高速Pythonパッケージマネージャー )-
curl -LsSf https://astral.sh/uv/install.sh | shでインストール - Claude DesktopなどのMCPクライアント(claude.ai/downloadからダウンロードして最新版を維持)
- テキストエディタまたはIDE
MCPに関する事前知識は必要ありません。実用的な天気情報MCPサーバーを作成し、AIがNational Weather Service APIを通じてアメリカのリアルタイム天気警報と予報をクエリできるようにします。
ステップ1: 環境設定
クリーンなプロジェクトディレクトリを作成し、uvで初期化します:
mkdir weather-mcp-server
cd weather-mcp-server
uv init
uv venv
source .venv/bin/activate # Windowsの場合: .venv\Scripts\activate
uv add "mcp[cli]" httpx
これにより、公式MCP Python SDK(FastMCP)とAPI呼び出し用のhttpxがインストールされます。プロジェクトにpyproject.tomlと仮想環境が作成されます。
期待される出力: 新しい.venvフォルダと依存関係がuv.lockにリストされます。
ステップ2: MCPサーバーコードの作成
メインファイルを作成します:
touch weather.py
以下の完成した、実行可能なコードをweather.pyに貼り付けます:
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
# MCPサーバーの初期化
mcp = FastMCP("weather")
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
# NWS APIを安全に呼び出すヘルパー関数
async def make_nws_request(url: str) -> dict[str, Any] | None:
headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
# 天気警報をAI向けに整形
def format_alert(feature: dict) -> str:
props = feature["properties"]
return f"""
Event: {props.get("event", "Unknown")}
Area: {props.get("areaDesc", "Unknown")}
Severity: {props.get("severity", "Unknown")}
Description: {props.get("description", "No description available")}
Instructions: {props.get("instruction", "No specific instructions provided")}
"""
# ツール1: アメリカの州のアクティブな天気警報を取得
@mcp.tool()
async def get_alerts(state: str) -> str:
"""アメリカの州(例: "CA" または "TX")の現在の天気警報を取得します。"""
url = f"{NWS_API_BASE}/alerts/active/area/{state.upper()}"
data = await make_nws_request(url)
if not data or "features" not in data:
return "Unable to fetch alerts or no alerts found."
if not data["features"]:
return f"No active alerts for {state.upper()}."
alerts = [format_alert(f) for f in data["features"]]
return "\n---\n".join(alerts)
ツール2: 任意の緯度/経度の5日間予報を取得
@mcp.tool() async def get_forecast(latitude: float, longitude: float) -> str: """特定の緯度と経度の天気予報を取得する。""" points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}" points_data = await make_nws_request(points_url) if not points_data: return "この地点の予報データを取得できませんでした。" forecast_url = points_data["properties"]["forecast"] forecast_data = await make_nws_request(forecast_url) if not forecast_data: return "詳細な予報を取得できませんでした。" periods = forecast_data["properties"]["periods"][:5] forecasts = [] for period in periods: forecast = f""" {period["name"]}: 気温: {period["temperature"]}°{period["temperatureUnit"]} 風: {period["windSpeed"]} {period["windDirection"]} 予報: {period["detailedForecast"]} """ forecasts.append(forecast) return "\n---\n".join(forecasts)
def main(): mcp.run(transport="stdio")
if name == "main": main()
**主要な概念の説明:**
- `@mcp.tool()`デコレータは通常の非同期関数を、AIが発見して呼び出せるMCPツールに変換します。
- サーバーは**stdio**(標準入力/出力)経由で実行されます – ローカルMCPサーバーのデフォルトです。
- すべてのログはstderrに出力されるべきです(FastMCPがこれを自動的に処理します)。
## ステップ3: サーバーをローカルでテストする
サーバーを実行します:
```bash
uv run weather.py
期待される出力: ターミナルは開いたまま無音になります(stdioサーバーでは正常です)。MCPクライアントが接続したときにのみJSON-RPCメッセージが表示されます。
次のステップのために、このターミナルは実行したままにしてください。
ステップ4: MCPサーバーをClaude Desktopに接続する
- Claude Desktopを開きます。
- 設定ファイルを作成または編集します。場所:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
- macOS:
このエントリを正確に追加します(/ABSOLUTE/PATH/TO/weather-mcp-serverは実際のフォルダパスに置き換えてください):
{
"mcpServers": {
"weather": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/TO/weather-mcp-server",
"run",
"weather.py"
]
}
}
}
- Claude Desktopを完全に終了します(macOSではCmd+Q、Windowsではシステムトレイから閉じます)して再起動します。
- Claudeで、**「ファイル、コネクタなどを追加」**をクリック → コネクタにカーソルを合わせると → **「weather」**がリストに表示されるはずです。
ステップ5: AIと一緒にMCPサーバーを使用する
Claude Desktopで以下のプロンプトを試してみてください:
- 「テキサス州の現在の気象警報は何ですか?」
- 「サンフランシスコの予報を教えてください(緯度37.77、経度-122.41を使用)。」
- 「カリフォルニア州の警報を確認し、何か備える必要があるか教えてください。」
Claudeは自動的にツールを発見し、初回は承認を求め、フォーマットされた結果を返します。
期待される動作: AIは裏側でツールを呼び出し、自然言語での回答を表示します。
よくある問題とトラブルシューティング
-
Claude にサーバーが表示されない場合:
- JSON が有効か(末尾のカンマがないか)再確認してください。
- 設定で絶対パスを使用してください。
- Claude を完全に再起動してください。
- ログを確認してください:
~/Library/Logs/Claude/mcp*.log(macOS) または Windows の同等のログファイル。
-
API エラーまたはデータが取得できない場合:
- NWS API は米国の地域でのみ機能します。
- 2文字の州コード(CA、TX など)を使用してください。
- 座標は有効な緯度/経度である必要があります。
-
“コマンドが見つかりません” の場合:
- uv が PATH に含まれており、仮想環境が有効になっていることを確認してください。
uv --versionを実行してインストールを確認してください。
-
タイムアウトまたは応答が遅い場合:
- 必要に応じて
make_nws_requestのタイムアウト時間を増やしてください。 - NWS にはレート制限があります – 本番環境では大量のリクエストを避けてください。
- 必要に応じて
-
権限の問題の場合:
- macOS では、システム設定 → プライバシーとセキュリティで Claude Desktop にフルディスクアクセスを許可してください。
次のステップ
- さらにツールを追加: 同じ
@mcp.tool()パターンを使用して、データベース、GitHub、Slack、または独自の API 用のツールを作成します。 - リソースとプロンプトを追加: ファイルのようなデータと再利用可能な指示のために
mcp.resource()とmcp.prompt()を使用します。 -W リモートデプロイ: HTTP/SSE トランスポートに切り替えて AWS Lambda、Vercel、または任意のサーバーにホストします(FastMCP はstateless_http=Trueをサポートしています)。
複数言語をサポート: 同じ機能のために公式の TypeScript、Go、または Rust SDK を試してください。
- サーバーを共有: リポジトリを公開し、他の人が
npxや Docker 経由で追加できるようにします。
これで、互換性のある AI クライアントが使用できる完全に機能する MCP サーバーが完成しました。実験を重ね、ツールを拡張し、強力な AI 統合の構築を始めましょう!