python-mcp-server-generator について
MCP Python SDK v2でPython製MCPサーバーを構築・テストするためのスキルです。プロジェクト設定から実装、テスト、クライアント設定までを案内し、SDK v2に沿った手順を示します。
主な機能
- 01Pythonサーバープロジェクトの設定
- 02型付きツールとスキーマの生成
- 03必要に応じたリソースとプロンプトの追加
- 04インメモリクライアントでのツールテスト
- 05MCPクライアントの設定
活用シーン
- 01新しいPython製MCPサーバーの作成
- 02ツールの動作とエラーのテスト
- 03VS CodeまたはClaude Desktopの設定
MCP 対応
MCP Python SDK v2を使ったMCPサーバー作成を案内し、標準のstdioと、必要に応じたStreamable HTTPを扱います。クライアント設定も説明します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ github/ awesome-copilot --skill python-mcp-server-generatorインストール後、Claude Code で/python-mcp-server-generatorを入力して読み込まれたか確認します。
同梱ファイルreferences/streamable-http.md
詳細
Python MCP サーバージェネレーター
公式の MCP Python SDK v2 を使用して、Python で Model Context Protocol (MCP) サーバーを作成します。SDK v2 は MCP 仕様リビジョン 2026-07-28 をサポートしています。同じサーバーは、以前のリビジョンを使用するクライアントにも対応します。
ワークフロー
このチェックリストをコピーして、進捗を追跡してください:
- ステップ 1: プロジェクトを作成します。
- ステップ 2: サーバーを記述します。
- ステップ 3: テストを記述します。
- ステップ 4: テストが成功するまで実行します。
- ステップ 5: クライアントを設定します。
ステップ 1: プロジェクトを作成します
次のコマンドを実行します:
uv init --app --no-package project-name
cd project-name
uv add "mcp[cli]>=2,<3"
uv add --dev pytest
次に main.py を削除します。サーバーは server.py に記述します。
--no-packageを指定しない場合、uv はsrc/パッケージレイアウトを作成するため、テストがserver.pyをインポートできません。uv initは.gitignoreファイルを作成します。別のものを記述しないでください。
ステップ 2: サーバーを記述します
このテンプレートから始めます:
from mcp.server import MCPServer
from mcp.server.mcpserver.exceptions import ToolError
mcp = MCPServer("Demo", version="0.1.0")
@mcp.tool()
def divide(a: float, b: float) -> float:
"""Divide a by b."""
if b == 0:
raise ToolError("b must not be zero.")
return a / b
if __name__ == "__main__":
mcp.run() # stdio is the default transport
次に、ユーザーのリクエストに合わせてテンプレートを変更します:
divideを、ユーザーが必要とするツールに置き換えます。- 各ツールに完全な型ヒントと docstring を付けます。SDK は型ヒントから入力スキーマを生成します。docstring はツールの説明になります。
- クライアントが機械可読なデータを必要とする場合は、Pydantic モデルまたは
TypedDictを返します。SDK は戻り値の型から出力スキーマを生成します。 - I/O には
async defを使用します。SDK は同期ツールをワーカースレッドで実行します。 - 読み取り専用ツールには
@mcp.tool(annotations=ToolAnnotations(read_only_hint=True))(mcp.typesから)を付けます。破壊的なツールにはdestructive_hint=Trueを使用します。 - リソース(
@mcp.resource("users://{user_id}"))とプロンプト(@mcp.prompt())は、ユーザーが要求した場合にのみ追加します。
デフォルトでは stdio を使用します。ユーザーがリモートサーバーまたは HTTP サーバーを要求した場合にのみ、references/streamable-http.md を参照してください。
ステップ 3: テストを記述します
test_server.py を server.py の隣に配置します。各ツールと各 ToolError に対してテストを記述します:
import pytest
from mcp import Client
from server import mcp
@pytest.mark.anyio
async def test_divide():
async with Client(mcp) as client:
result = await client.call_tool("divide", {"a": 6, "b": 3})
assert result.structured_content == {"result": 2.0}
@pytest.mark.anyio
async def test_divide_by_zero():
async with Client(mcp) as client:
result = await client.call_tool("divide", {"a": 1, "b": 0})
assert result.is_error
assert "must not be zero" in result.content[0].text
- インメモリの
Clientはサブプロセスもポートも必要としません。2026-07-28 リビジョンで接続します。 mcpパッケージはanyioをインストールし、これがanyioマーカーを提供します。pytest-asyncioを追加しないでください。
ステップ 4: テストが成功するまで実行します
uv run pytestを実行します。- テストが失敗した場合は、エラーを読みます。サーバーまたはテストを修正します。
uv run pytestを再度実行します。- すべてのテストが成功した場合にのみ続行します。
ステップ 5: クライアントを設定します
VS Code の場合は、.vscode/mcp.json を記述します:
{
"servers": {
"demo": {
"type": "stdio",
"command": "uv",
"args": ["--directory", "/absolute/path/to/project", "run", "server.py"]
}
}
}
Claude Desktop の場合は、uv run mcp install server.py を実行します。
ユーザーに次のコマンドを伝えます:
uv run server.pyは stdio サーバーを起動します。サーバーは stdin でホストを待機し、何も出力しません。uv run mcp dev server.pyは MCP Inspector を開きます。Inspector には Node.js が必要です。
注意点
SDK v2 と 2026-07-28 リビジョンでは、多くの SDK v1 のパターンが変更されました。SDK v1 の例をコピーしないでください。
- SDK v2 では
FastMCPとmcp.server.fastmcpが削除されました。サーバークラスはfrom mcp.server import MCPServerでインポートします。 Context、Image、Audio、Resolve、Elicit、ElicitationResult、AcceptedElicitation、Message、UserMessage、AssistantMessageはmcp.server.mcpserverからインポートします。- サーバー名は
MCPServerの最初の引数として指定します。その他のコンストラクター引数はすべてキーワード引数として指定します。これらの位置引数の順序は SDK v2 で変更されました。 versionを設定します。設定しない場合、サーバーは空のバージョンを報告します。- トランスポートオプション(
transport、host、port、json_response、stateless_http、transport_security)はMCPServer(...)ではなくrun()に指定します。 - SDK v2 の型は snake_case のフィールドを使用します。例えば
read_only_hint、structured_content、is_errorです。 - モデルが読む必要のあるエラーには
ToolErrorを発生させます。その他の例外の場合、モデルは一般的なエラーメッセージのみを受け取ります。 - ツールの失敗に対して
MCPErrorを発生させないでください。クライアントはis_errorを持つツール結果ではなく、プロトコルエラーを受け取ります。多くのホストはこのエラーをモデルに表示しません。 - stdio サーバーでは、stdout がプロトコルチャネルです。
print()を呼び出さないでください。loggingモジュールを使用して stderr にログを出力します。 ctx.elicit()を使用しないでください。2026-07-28 接続では失敗します。ツール呼び出し中のユーザー入力には、パラメーターにResolve(fn)を注釈として付けます。fnからElicit(message, Model)を返します。- リスト変更通知は
await ctx.notify_tools_changed()で送信します。2026-07-28 接続ではctx.session.send_tool_list_changed()が削除されています。 - stdio と HTTP では、lifespan はサーバーの起動時に一度だけ実行されます。テスト内の各インメモリ
Client(mcp)は lifespan を再度実行します。そのオブジェクトはctx.request_context.lifespan_contextで読み取ります。 - 2026-07-28 リビジョンでは、以下の機能が非推奨になりました(SEP-2577)。新しいサーバーにこれらを追加しないでください:
- Sampling(
ctx.session.create_message()): LLM プロバイダー API を直接呼び出してください。 - プロトコルログ(
ctx.log()、ctx.info()および同様のメソッド): 標準のloggingモジュールを使用してください。 - Roots(
ctx.session.list_roots()): ツールパラメーター、リソース URI、またはサーバー設定からパスを取得してください。
- Sampling(
- 2026-07-28 リビジョンには SSE トランスポートがありません。Streamable HTTP を使用してください。