
FastMCP 入門 (8) - クライアントトランスポート
「FastMCP」の「クライアントトランスポート」についてまとめました。
前回
1. クライアントトランスポート
FastMCPクライアントは、MCPサーバへの接続と通信の詳細を処理するためにClientTransportオブジェクトを使用します。FastMCPは、一般的な接続方法に対応する複数のトランスポート実装を組み込みで提供しています。
クライアントは多くの場合、適切なトランスポートを自動的に推測しますが、より詳細な制御のためにトランスポートを明示的にインスタンス化することもできます。
2. Stdioトランスポート
これらのトランスポートは、サブプロセスとして実行されるMCPサーバを管理し、標準入力(stdin)と標準出力(stdout)を介してサーバと通信します。これは、Claude Desktopなどのクライアントで使用される標準的なメカニズムです。
2-1. Python Stdio
・クラス : fastmcp.client.transports.PythonStdioTransport
・推定元 : .py ファイルへのパス
・ユースケース : Python ベースの MCP サーバスクリプト (FastMCP やベース mcp ライブラリを使用したスクリプトなど) をサブプロセスで実行します。
これは、開発中、またはサーバ スクリプトを起動する必要があるツールと統合するときに、ローカル FastMCP サーバと対話する最も一般的な方法です。
from fastmcp import Client
from fastmcp.client.transports import PythonStdioTransport
server_script = "my_mcp_server.py" # Assumes this file exists and runs mcp.run()
# オプション1: 推定トランスポート
client_inferred = Client(server_script)
# オプション2: 明示的なトランスポート (特定のPython実行ファイルを使用する、または引数を追加するなど)
transport_explicit = PythonStdioTransport(
script_path=server_script,
python_cmd="/usr/bin/python3.11", # Pythonのバージョンを指定
# args=["--some-server-arg"], # 引数を指定
# env={"MY_VAR": "value"}, # 環境変数を指定
# cwd="/path/to/run/in" # 作業ディレクトリを指定
)
client_explicit = Client(transport_explicit)
async def use_stdio_client(client):
async with client:
tools = await client.list_tools()
print(f"Connected via Python Stdio, found tools: {tools}")
# asyncio.run(use_stdio_client(client_inferred))
# asyncio.run(use_stdio_client(client_explicit))2-2. Node.js Stdio
・クラス : fastmcp.client.transports.NodeStdioTransport
・推定元 : .js ファイルへのパス
・ユースケース : サブプロセスで Node.js ベースの MCP サーバースクリプトを実行する。
Pythonトランスポートに似ていますが、JavaScript サーバー用です。
from fastmcp import Client
from fastmcp.client.transports import NodeStdioTransport
node_server_script = "my_mcp_server.js" # Assumes this JS file starts an MCP server on stdio
# オプション1: 推定トランスポート
client_inferred = Client(node_server_script)
# オプション2: 明示的なトランスポート
transport_explicit = NodeStdioTransport(
script_path=node_server_script,
node_cmd="node" # またはNode実行ファイルへのパスを指定
)
client_explicit = Client(transport_explicit)
# 使い方は他のクライアントと同じ
# client_explicit を使用した非同期処理:
# tools = await client_explicit.list_tools()2-3. UVX Stdio (試験的)
・クラス : fastmcp.client.transports.UvxStdioTransport
・推定元 : 自動推定されません。明示的にインスタンス化する必要があります。
・ユースケース : uvx (uvツールチェーンの一部) を使用して、Pythonツールとしてパッケージ化された MCPサーバを実行します。これにより、現在の環境に明示的にインストールすることなくツールを実行できます。
これは、コマンドラインツールまたはパッケージとして配布された MCPサーバを実行する場合に便利です。
from fastmcp.client.transports import UvxStdioTransport
# 例: 仮想ツール「cloud-analyzer-mcp」を uvx経由で実行
# このツールを実行すると、stdio上で MCPサーバが起動すると仮定します
transport = UvxStdioTransport(
tool_name="cloud-analyzer-mcp",
# from_package="cloud-analyzer-cli", # ツール名が異なる場合はパッケージを任意で指定
# with_packages=["boto3", "requests"], # 必要に応じて依存関係を追加
# tool_args=["--config", "prod.yaml"] # ツール自体に引数を渡す
)
client = Client(transport)
# クライアントと非同期:
# analysis = await client.call_tool("analyze_bucket", {"name": "my-data"})2-4. NPX Stdio (試験的)
・クラス : fastmcp.client.transports.NpxStdioTransport
・推定元 : 自動推定されません。明示的にインスタンス化する必要があります。
・ユースケース : npxを使用して、NPMパッケージとしてパッケージ化された MCPサーバを実行します。
UvxStdioTransportに似ていますが、Node.js向けです。
from fastmcp.client.transports import NpxStdioTransport
# 例: npx経由で仮想的な「npm-mcp-server-package」を実行
transport = NpxStdioTransport(
package="npm-mcp-server-package",
# args=["--port", "stdio"] # パッケージスクリプトに渡される引数
)
client = Client(transport)
# クライアントと非同期:
# response = await client.call_tool("get_npm_data", {})3. ネットワークトランスポート
これらのトランスポートは、ネットワーク上で実行されているサーバ (通常はURL経由でアクセスできる長期実行サービス) に接続します。
3-1. SSE (Server-Sent Events)
・クラス : fastmcp.client.transports.SSETransport
・推定元 : http:// または https:// URL
・ユースケース : HTTP/S経由で公開される永続的なMCPサーバへの接続。多くの場合、FastMCPの mcp.run(transport="sse") モードを使用します。
SSEは、サーバが標準の HTTP 接続を介してクライアントにメッセージをプッシュする、シンプルな単方向プロトコルです。
from fastmcp import Client
from fastmcp.client.transports import SSETransport
sse_url = "http://localhost:8000/sse"
# オプション1: 推定トランスポート
client_inferred = Client(sse_url)
# オプション2: 明示的なトランスポート(カスタムヘッダーの追加など)
headers = {"Authorization": "Bearer mytoken"}
transport_explicit = SSETransport(url=sse_url, headers=headers)
client_explicit = Client(transport_explicit)
async def use_sse_client(client):
async with client:
tools = await client.list_tools()
print(f"Connected via SSE, found tools: {tools}")
# asyncio.run(use_sse_client(client_inferred))
# asyncio.run(use_sse_client(client_explicit))3-2. WebSocket
・クラス : fastmcp.client.transports.WSTransport
・推定元 : ws:// または wss:// URL
・ユースケース : 双方向通信のために WebSocket プロトコルを使用してMCPサーバに接続します。
WebSocketは、クライアントとサーバ間の永続的な全二重接続を提供します。
from fastmcp import Client
from fastmcp.client.transports import WSTransport
ws_url = "ws://localhost:9000"
# オプション1: 推定トランスポート
client_inferred = Client(ws_url)
# オプション2: 明示的なトランスポート
transport_explicit = WSTransport(url=ws_url)
client_explicit = Client(transport_explicit)
async def use_ws_client(client):
async with client:
tools = await client.list_tools()
print(f"Connected via WebSocket, found tools: {tools}")
# asyncio.run(use_ws_client(client_inferred))
# asyncio.run(use_ws_client(client_explicit))4. インメモリトランスポート
4-1. FastMCP トランスポート
・クラス : fastmcp.client.transports.FastMCPTransport
・推定元 : fastmcp.server.FastMCP のインスタンス
・ユースケース : 同じ Pythonプロセスで実行されているFastMCPサーバインスタンスに直接接続します。
これは以下の場合に非常に便利です。
・テスト:サブプロセスやネットワーク接続を必要とせずに、FastMCPサーバの単体テストまたは統合テストを作成する。
・埋め込み:MCP サーバを大規模アプリケーション内のコンポーネントとして使用する。
from fastmcp import FastMCP, Client
from fastmcp.client.transports import FastMCPTransport
# 1. FastMCPサーバーインスタンスを作成
server = FastMCP(name="InMemoryServer")
@server.tool()
def ping(): return "pong"
# 2. サーバインスタンスを直接参照するクライアントを作成
# オプションA: 推定
client_inferred = Client(server)
# オプションB: 明示的
transport_explicit = FastMCPTransport(mcp=server)
client_explicit = Client(transport_explicit)
# 3. クライアントを使用する (サブプロセスやネットワークは使用しない)
async def test_in_memory():
async with client_inferred: # またはclient_explicit
result = await client_inferred.call_tool("ping")
print(f"In-memory call result: {result[0].text}") # Output: pong
# asyncio.run(test_in_memory())通信は効率的なメモリ内キューを通じて行われるため、非常に高速になります。
5. トランスポートの選択
・ローカル開発/テスト
PythonStdioTransport (.py ファイルから推測) または FastMCPTransport (同一プロセステスト用) を使用します。
・リモート/永続サーバへの接続
SSETransport (http/s の場合) または WSTransport (ws/s の場合) を使用します。
・パッケージツールの実行
ローカルインストールなしで MCPサーバを実行する必要がある場合は、UvxStdioTransport (Python/uv) または NpxStdioTransport (Node/npm) を使用します。
・Claude Desktop (または類似のツール) との統合
これらのツールは通常、Python スクリプトの実行を想定しているため、サーバは python your_server.py 経由で実行可能である必要があります。その場合、クライアント側では PythonStdioTransport が適切なメカニズムとなります。