mcp-demo-server
MCP Demo — Python エージェントツールをゼロから
MCP とは?
MCP (Model Context Protocol) は、AI アプリケーションが外部の ツール、リソース、プロンプト を一貫したインターフェースを通じて発見・利用できるようにする標準化されたプロトコルです。
すべての AI フレームワークがデータベース、API、ファイルシステム、内部サービスごとに異なる統合を考案する代わりに、MCP ホストは MCP サーバーに接続し、同じプロトコルサーフェスを使用できます。
MCP が解決する問題
問題 | MCP による解決策 |
ベンダーロックイン | 統合は、単一のモデルプロバイダーやエージェントフレームワークに縛られるのではなく、MCP を通じて機能を公開します |
一貫性のないツール呼び出し | ツールは機械可読なスキーマと標準化された発見・呼び出しセマンティクスを持ちます |
コンテキストの永続化がない | MCP はコンテキスト/ツールプロバイダーをモデルから分離し、長期間の接続を可能にします |
動的データソース | データベース、API、ファイル、内部システムを、実装をモデルランタイムに埋め込むことなく MCP リソース/ツールとしてラップします |
ワイヤ上では、MCP は stdio や HTTP ベースのトランスポート (SSE/Streamable HTTP) などのトランスポートを介して JSON-RPC 2.0 メッセージ を使用します。このリポジトリは stdio を使用します。クライアントはサーバーをサブプロセスとして起動し、stdin を通じてプロトコルメッセージを送信し、stdout を通じて応答を受信します。
Related MCP server: Weather MCP Server
アーキテクチャ
flowchart TD
A[User: "What's the weather in London?"] --> B[AI Agent<br/>OpenAI Responses API]
B --> C[1. Discovers MCP tools]
B --> D[2. Decides whether to call]
B --> E[3. Emits function call]
E --> F[MCP Client<br/>ClientSession + stdio]
F --> G[initialize]
F --> H[tools/list]
F --> I[tools/call]
I --> J[JSON-RPC 2.0<br/>stdin/stdout]
J --> K[MCP Server subprocess]
K --> L[get_current_weather tool]
K --> M[greeting://{name} resource]公式 SDK を使う理由
このリポジトリは、プロトコルを再実装する代わりに公式 Python MCP SDK を使用しています。SDK は以下を提供します。
プロトコルのライフサイクルと検証
トランスポート抽象化 (stdio、HTTP/SSE)
型付きクライアント/サーバー API
アプリケーションコードは、サーバー登録、ツールスキーマ、initialize、tools/list、tools/call、リソース読み取り、stdio プロセス管理など、重要な MCP の概念を明示的にしています。
現在の SDK の安定版 v2 API は、サーバー構築に
MCPServerを、stdio クライアントにClientSession/stdio_clientを使用します。
プロジェクト構成
mcp-demo/
├── README.md
├── requirements.txt
├── .env.example
├── pyproject.toml
├── src/
│ ├── mcp_server/
│ │ ├── __init__.py
│ │ ├── server.py # MCP server entry point
│ │ ├── tools.py # Tool implementations
│ │ ├── handlers.py # Request handlers
│ │ └── utils.py # Shared utilities
│ ├── mcp_client/
│ │ ├── __init__.py
│ │ ├── client.py # MCP client wrapper
│ │ ├── agent.py # OpenAI agent integration
│ │ └── runner.py # Demo runner
│ └── shared/
│ ├── __init__.py
│ └── types.py # Shared Pydantic models
├── tests/
│ ├── test_server.py
│ └── test_client.py
├── examples/
│ └── demo.ipynb
└── scripts/
└── run_demo.sh必要条件
Python 3.10+
OpenAI API キー (AI エージェントデモ用)
天気 API キーは不要 — 天気ツールは決定論的なサンプルデータを使用するため、MCP パスはオフラインで動作します
クイックスタート
1. 仮想環境を作成
python -m venv .venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\Activate.ps1 # Windows PowerShell2. 依存関係をインストール
python -m pip install --upgrade pip
pip install -r requirements.txt3. OpenAI を設定
cp .env.example .env.env をあなたの認証情報で編集してください:
OPENAI_API_KEY=your_api_key_here
OPENAI_MODEL=gpt-4.1-miniサーバー自体は OpenAI キーを 必要としません。
デモを実行
リポジトリルートから
python src/mcp_client/runner.pyランナーが行うこと:
ステップ | 説明 |
1️⃣ |
|
2️⃣ | MCP 初期化ハンドシェイクを実行 |
3️⃣ |
|
4️⃣ | 発見した MCP スキーマを OpenAI 関数ツールに変換 |
5️⃣ | モデルに自然言語の質問への回答を依頼 |
6️⃣ | モデルが |
7️⃣ | MCP の結果をモデルに返送 |
8️⃣ | 最終回答を出力 |
9️⃣ | サーバーをクリーンにシャットダウン |
代替: シェルラッパー
bash scripts/run_demo.sh期待される出力
正確な文言はモデルによって異なりますが、ログの流れは次のようになります:
INFO mcp_client.client: -> MCP initialize
INFO mcp_client.client: <- MCP initialize: server=mcp-demo-server
INFO mcp_client.client: -> MCP tools/list
INFO mcp_client.client: <- MCP tools/list: ["get_current_weather"]
INFO mcp_client.agent: User: What's the weather in London?
INFO mcp_client.agent: OpenAI requested tool: get_current_weather {"city":"London","units":"metric"}
INFO mcp_client.client: -> MCP tools/call name=get_current_weather arguments={"city":"London","units":"metric"}
INFO mcp_server.tools: weather lookup city=London units=metric
INFO mcp_client.client: <- MCP tools/call result={"city":"London","temperature":18.0,...}
INFO mcp_client.agent: Final: London is 18°C and partly cloudy.ログは、アプリケーション境界で MCP セマンティックメッセージを意図的に表示します。SDK は JSON-RPC フレーミングを内部的に処理します。
MCP サーバーを単独で実行
python src/mcp_server/server.pystdio MCP サーバーは「ハング」しているように見えますが、これは 想定どおり です。stdin でプロトコルメッセージを待機します。ホスト/クライアントがそれを起動し、stdio パイプを所有する必要があります。
対話型プロトコル検査
pip install "mcp[cli]"
mcp dev src/mcp_server/server.py実演される MCP メソッド
公式 SDK は JSON-RPC ライフサイクルを処理します:
メソッド | 方向 | 目的 |
| Client → Server | ハンドシェイクと機能ネゴシエーション |
| Client → Server | 利用可能なツールを発見 |
| Client → Server | ツールを呼び出し |
| Client → Server | 利用可能なリソースを発見 |
| Client → Server | リソースを読み取り |
クライアントは、機能を一覧表示または呼び出す前に明示的に initialize() を呼び出します。サーバーのデコレータは、Python 型アノテーションからツール/リソーススキーマを生成します。
ツール: get_current_weather
get_current_weather(
city: str,
units: Literal["metric", "imperial"] = "metric"
) -> WeatherResponse構造化された Pydantic ベースのペイロードを返します:
{
"city": "London",
"temperature": 18.0,
"units": "metric",
"condition": "partly cloudy",
"humidity_percent": 72
}不明な都市は、サーバーをクラッシュさせるのではなく、制御された MCP ツールエラーで失敗します。
エージェント統合フロー
エージェントは、デモをシンプルに保つために プレーンな OpenAI 関数呼び出し (追加フレームワークなし) を使用します:
flowchart LR
A[MCP Tool Schema] --> B[OpenAI Function Tool]
B --> C[Model Chooses Function]
C --> D[MCP ClientSession.call_tool]
D --> E[MCP Server Executes Tool]
E --> F[Function Call Output]
F --> G[Final Model Answer]これはエージェントフレームワークがラップするのと同じパターンです: MCP ツールを発見 → モデルにスキーマを公開 → 選択した呼び出しを MCP 経由でルーティング → 結果を次のモデルターンにフィードします。
テスト
pytest -qテストスイートの対象:
✅ ツール実行 (メートル法の天気)
✅ ツール実行 (ヤード・ポンド法の天気)
✅ 検証/エラー動作 (不明な都市)
✅ プロセス内 MCP クライアントの発見とツール呼び出し
テストは可能な限り SDK のインメモリクライアントを使用します。実際の MCP プロトコルレイヤーを実行しながら、サブプロセスの不安定さを回避します。
フォーマットとリンティング
このプロジェクトは Ruff を使用しています:
# Check
ruff check .
ruff format --check .
# Format
ruff format .本番環境に関する注意点
このデモは意図的に小規模ですが、いくつかの本番環境の懸念事項を表しています:
懸念事項 | 実装 |
stdout の規律 | サーバーはアプリログを stdout に出力しません (MCP に属します)。ログは |
型付き I/O | Pydantic モデルはアプリケーション境界でツールの入力/出力を検証します。 |
制御された障害 | ツール例外はプロセスクラッシュではなく MCP エラー結果 (SDK) になります。 |
サブプロセスのライフサイクル | SDK の stdio コンテキストマネージャーがプロセスの起動/シャットダウンを管理します。 |
最小権限の環境 | MCP stdio クライアントは、子プロセスに必要な環境変数を明示的に渡します。 |
動的発見 | エージェントは天気ツールスキーマをハードコードせず、 |
実際の外部データソースの場合: 決定論的な天気を認証付き API/データベース呼び出しに置き換え、タイムアウト、リトライ、レート制限、可観測性、シークレット管理を追加してください。
プロトコルのメンタルモデル
簡略化された JSON-RPC シーケンス:
// Client -> Server
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}
// Server -> Client
{"jsonrpc":"2.0","id":1,"result":{...}}
// Client -> Server
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
// Server -> Client
{"jsonrpc":"2.0","id":2,"result":{"tools":[...]}}
// Client -> Server
{"jsonrpc":"2.0","id":3,"method":"tools/call",
"params":{"name":"get_current_weather","arguments":{"city":"London"}}}
// Server -> Client
{"jsonrpc":"2.0","id":3,"result":{"content":[...],"structuredContent":{...}}}正確なプロトコルスキーマは MCP 仕様 と SDK によって管理されています。上記は教育用に意図的に簡略化されています。
参考
公式 MCP Python SDK: https://py.sdk.modelcontextprotocol.io/
OpenAI 関数呼び出し: https://platform.openai.com/docs/guides/function-calling
This server cannot be deployed
Maintenance
Related MCP Connectors
Weather, code search, currency & Solana trust scoring as MCP tools. Free, no API key needed.
Hosted MCP server for Xweather weather data: conditions, forecasts, alerts, and more.
Geocoding, routing, isochrones, traffic, weather, and place search for AI agents. 19 MCP tools.
Pay-per-use tool marketplace for AI agents. Search, price-check, and call APIs via MCP.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables AI agents to retrieve real-time weather conditions and forecasts via OpenWeatherMap API. Supports interactive weather queries and travel planning through MCP tools, resources, and prompts.2-
- AlicenseNot gradedqualityDmaintenanceProvides weather data from OpenWeatherMap API through MCP tools and a REST API with OpenAPI support. Enables LLM agents to retrieve current weather, forecasts, and temperature ranges by city or coordinates.4 npmMIT
- AlicenseNot gradedqualityBmaintenanceWraps the OpenWeatherMap API to provide weather data through MCP, enabling AI agents to query current conditions, forecasts, and other weather information via natural language.452 npmMIT
- AlicenseNot gradedqualityBmaintenanceProvides weather data from WeatherAPI.com through MCP, enabling AI agents to query current conditions and forecasts via natural language.195 npmMIT