OpenTelemetry を使用して自己ホスト型 MCP サーバーを計測する

このドキュメントでは、自己ホスト型の Model Context Protocol(MCP)サーバーを計測してデプロイし、テレメトリーを収集する手順について説明します。このドキュメントの 例では、FastMCP を使用して MCP サーバーを構築し、Cloud Run を使用して MCP サーバーを デプロイします。FastMCP には、すべての MCP オペレーションからテレメトリーを収集する OpenTelemetry 計測機能が組み込まれています。

このドキュメントでは、次の手順について説明します。

  1. Python プロジェクトを uv パッケージ マネージャー で準備します。
  2. 算術演算用の MCP サーバーを作成します
  3. Cloud Run にデプロイします
  4. MCP クライアントを認証します
  5. 自己ホスト型の MCP サーバーをテストします
  6. テレメトリー データを表示します

始める前に

  1. アカウントにログインします。 Google Cloud を初めて使用する場合は、 アカウントを作成して、実際のシナリオで Google プロダクトのパフォーマンスを評価してください。 Google Cloud新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. Artifact Registry、Cloud Run、Cloud Build、Telemetry、Cloud Logging、Cloud Monitoring、Cloud Trace API を有効にします。

    API を有効にするために必要なロール

    API を有効にするには、serviceusage.services.enable 権限を含む Service Usage 管理者 IAM ロール(roles/serviceusage.serviceUsageAdmin)が必要です。詳しくは、ロールを付与する方法をご覧ください。

    API を有効にする

  7. プロジェクトで Cloud Run 開発環境を設定します Google Cloud 。
  8. サービスをデプロイするための適切な権限があり、使用するアカウントに Cloud Run 管理者roles/run.admin)とサービス アカウント ユーザーroles/iam.serviceAccountUser)のロールが付与されていることを確認します。
  9. アカウントに Cloud Run 起動元(roles/run.invoker) ロールを付与します。このロールにより、自己ホスト型の MCP サーバーから Cloud Run サービスにアクセスできます。
  10. ロールの付与方法を確認する

    コンソール

    1. コンソールで、[IAM] ページに移動します。 Google Cloud

      [IAM] に移動
    2. プロジェクトを選択します。
    3. [ アクセスを許可] をクリックします。
    4. [新しいプリンシパル] フィールドに、ユーザー ID を入力します。これは通常、Cloud Run サービスのデプロイに使用されるメールアドレスです。

    5. [ロールを選択] リストでロールを選択します。
    6. 追加のロールを付与するには、[ 別のロールを追加] をクリックして各ロールを追加します。
    7. [保存] をクリックします。

    gcloud

    プロジェクトで自分のアカウントに必要な IAM ロールを付与するには:

       gcloud projects add-iam-policy-binding PROJECT_ID \
           --member=PRINCIPAL \
           --role=ROLE
       

    次のように置き換えます。

    • PROJECT_ID: プロジェクトの ID。
    • PRINCIPAL: ロールを付与するプリンシパルの ID。通常、プリンシパル ID の形式は PRINCIPAL-TYPE:ID です。例: user:my-user@example.com PRINCIPAL に使用できる形式の一覧については、プリンシパル ID をご覧ください。
    • ROLE: IAM ロール。
  11. ドメイン制限の組織 ポリシーでプロジェクトの未認証呼び出しが制限されている場合は、限定公開サービスのテストの説明に従って、デプロイされたサービスにアクセスする必要があります。

  12. Python のパッケージおよびプロジェクト管理ツールである uv をインストールします。

Python プロジェクトを準備する

以下の手順では、uv パッケージ マネージャーを使用して Python プロジェクトを設定する方法について説明します。

  1. デプロイ用のソースコードを保存する、mcp-on-cloudrun という名前のフォルダを作成します。

      mkdir mcp-on-cloudrun
      cd mcp-on-cloudrun
    
  2. uv ツールを使用して Python プロジェクトを作成し、pyproject.toml ファイルを生成します。

      uv init --name "mcp-on-cloudrun" --description "Example of deploying an MCP server on Cloud Run" --bare --python 3.10
    

    uv init コマンドにより、次の pyproject.toml ファイルが作成されます。

    [project]
    name = "mcp-server"
    version = "0.1.0"
    description = "Example of deploying an MCP server on Cloud Run"
    readme = "README.md"
    requires-python = ">=3.10"
    dependencies = []
    
  3. 次の新しいファイルを追加で作成します。

    • server.py: MCP サーバーのソースコード用
    • otel_setup.py: OpenTelemetry を構成する
    • test_server.py: 自己ホスト型サーバーをテストする
    • Cloud Run にデプロイするための Dockerfile
    touch server.py otel_setup.py test_server.py Dockerfile
    

    プロジェクト ディレクトリは次の構造になっている必要があります。

    ├── mcp-on-cloudrun
    │   ├── pyproject.toml
    │   ├── otel_setup.py
    │   ├── server.py
    │   ├── test_server.py
    │   └── Dockerfile
    

算術演算用の MCP サーバーを作成します。

このセクションでは、 FastMCP を使用して数学 MCP サーバーを設定します。 FastMCP は、Python で MCP のサーバーとクライアントを迅速に構築するためのツールです。

加算や減算などの数学演算用の MCP サーバーを作成する手順は次のとおりです。

  1. 次のコマンドを実行して、pyproject.toml ファイルに FastMCP を依存関係として追加します。

    uv add fastmcp==2.13.1 --no-sync
    
  2. otel_setup.py ファイルに次の OpenTelemetry セットアップ コードを追加します。

    import logging
    import google.auth
    import google.auth.transport.requests
    import grpc
    from google.auth.transport.grpc import AuthMetadataPlugin
    from opentelemetry import trace
    from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
        OTLPSpanExporter,
    )
    from opentelemetry.sdk.resources import SERVICE_NAME, Resource
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    
    logger = logging.getLogger(__name__)
    
    
    def setup_opentelemetry(service_name: str) -> None:
        """Sets up OpenTelemetry to send traces to Google Cloud Observability."""
        credentials, project_id = google.auth.default()
        if not project_id:
            raise Exception("Could not determine Google Cloud project ID.")
    
        resource = Resource.create(
            attributes={
                SERVICE_NAME: service_name,
                "gcp.project_id": project_id,
            }
        )
    
        # Set up OTLP auth
        request = google.auth.transport.requests.Request()
        auth_metadata_plugin = AuthMetadataPlugin(credentials=credentials, request=request)
        channel_creds = grpc.composite_channel_credentials(
            grpc.ssl_channel_credentials(),
            grpc.metadata_call_credentials(auth_metadata_plugin),
        )
    
        # Set up OpenTelemetry Python SDK
        tracer_provider = TracerProvider(resource=resource)
        tracer_provider.add_span_processor(
            BatchSpanProcessor(
                OTLPSpanExporter(
                    credentials=channel_creds,
                    endpoint="https://telemetry.googleapis.com:443/v1/traces",
                )
            )
        )
        trace.set_tracer_provider(tracer_provider)
        logger.info("OpenTelemetry successfully initialized.")
    
    
  3. server.py ファイルに次の数学 MCP サーバーのソースコードを追加します。

    from otel_setup import setup_opentelemetry
    setup_opentelemetry("mcp-server")
    
    import asyncio
    import logging
    import os
    
    from fastmcp import FastMCP 
    
    logger = logging.getLogger(__name__)
    logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
    
    mcp = FastMCP("MCP Server on Cloud Run")
    
    @mcp.tool()
    def add(a: int, b: int) -> int:
        """Use this to add two numbers together.
    
        Args:
            a: The first number.
            b: The second number.
    
        Returns:
            The sum of the two numbers.
        """
        logger.info(f">>> 🛠️ Tool: 'add' called with numbers '{a}' and '{b}'")
        return a + b
    
    @mcp.tool()
    def subtract(a: int, b: int) -> int:
        """Use this to subtract two numbers.
    
        Args:
            a: The first number.
            b: The second number.
    
        Returns:
            The difference of the two numbers.
        """
        logger.info(f">>> 🛠️ Tool: 'subtract' called with numbers '{a}' and '{b}'")
        return a - b
    
    if __name__ == "__main__":
        logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}")
        # Could also use 'sse' transport, host="0.0.0.0" required for Cloud Run.
        asyncio.run(
            mcp.run_async(
                transport="streamable-http",
                host="0.0.0.0",
                port=os.getenv("PORT", 8080),
            )
        )
    
  4. uv ツールを使用して server.py ファイルを実行するため、Dockerfile に次のコードを追加します。

    # Use the official Python image
    FROM python:3.13-slim
    
    # Install uv
    COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
    
    # Install the project into /app
    COPY . /app
    WORKDIR /app
    
    # Allow statements and log messages to immediately appear in the logs
    ENV PYTHONUNBUFFERED=1
    
    # Install dependencies
    RUN uv sync
    
    EXPOSE $PORT
    
    # Run the FastMCP server
    CMD ["uv", "run", "server.py"]
    

Cloud Run にデプロイします。

MCP サーバーは、 コンテナ イメージ または ソースコード:としてデプロイできます。

コンテナ イメージ

コンテナ イメージとしてパッケージ化された MCP サーバーをデプロイするには、次の手順を行います。

  1. コンテナ イメージを保存する Artifact Registry リポジトリを作成します。

    gcloud artifacts repositories create self-hosted-mcp-servers \
    --repository-format=docker \
    --location=us-central1 \
    --description="Repository for self-hosted MCP servers" \
    --project=PROJECT_ID
    
  2. Cloud Build を使用してコンテナ イメージをビルドし、Artifact Registry に push します。

    gcloud builds submit --region=us-central1 --tag us-central1-docker.pkg.dev/PROJECT_ID/self-hosted-mcp-servers/mcp-server:latest
    
  3. MCP サーバーのコンテナ イメージを Cloud Run にデプロイします。

    gcloud run deploy mcp-server \
    --image us-central1-docker.pkg.dev/PROJECT_ID/self-hosted-mcp-servers/mcp-server:latest \
    --region=us-central1 \
    --no-allow-unauthenticated
    

ソース

自己ホスト型の MCP サーバーは、ソースから Cloud Run にデプロイできます。

ソースからデプロイするには、次のコマンドを実行します。

gcloud run deploy mcp-server --no-allow-unauthenticated --region=us-central1 --source .

MCP クライアントを認証する

--no-allow-unauthenticated フラグを使用してサービスをデプロイした場合、自己ホスト型の MCP サーバーに接続する MCP クライアントには認証が必要です。

  1. サービス アカウントに Cloud Run 起動元 ロール(roles/run.invoker)を付与します。この Identity and Access Management のポリシー バインディングにより、ローカル MCP クライアントの認証に強力なセキュリティ メカニズムが使用されます。

  2. ローカルマシンで Cloud Run プロキシ を実行して、自己ホスト型の MCP サーバーへの認証済みトンネルを作成します。

    gcloud run services proxy mcp-server --region=us-central1
    

    Cloud Run プロキシがまだインストールされていない場合、このコマンドを実行すると、プロキシのダウンロードを求めるプロンプトが表示されます。プロンプトに従ってプロキシのダウンロードとインストールを行ってください。

Cloud Run は http://127.0.0.1:8080 へのすべてのトラフィックを認証し、リクエストを自己ホスト型の MCP サーバーに転送します。

自己ホスト型の MCP サーバーをテストする

自己ホスト型の MCP サーバーに接続してテストするため、FastMCP クライアントを使用して URL http://127.0.0.1:8080/mcp にアクセスします。

加算と減算のメカニズムをテストして呼び出す手順は次のとおりです。

  1. テストサーバーを実行する前に、Cloud Run プロキシを実行します。

  2. test_server.py というテストファイルを作成し、次のコードを追加します。

    from otel_setup import setup_opentelemetry
    setup_opentelemetry("test-server")
    
    import asyncio
    
    from fastmcp import Client
    
    
    async def test_server():
        # Test the MCP server using streamable-http transport.
        # Use "/sse" endpoint if using sse transport.
        async with Client("http://localhost:8080/mcp") as client:
            # List available tools
            tools = await client.list_tools()
            for tool in tools:
                print(f">>> 🛠️  Tool found: {tool.name}")
            # Call add tool
            print(">>> 🪛  Calling add tool for 1 + 2")
            result = await client.call_tool("add", {"a": 1, "b": 2})
            print(f"<<< ✅ Result: {result.content[0].text}")
            # Call subtract tool
            print(">>> 🪛  Calling subtract tool for 10 - 3")
            result = await client.call_tool("subtract", {"a": 10, "b": 3})
            print(f"<<< ✅ Result: {result.content[0].text}")
    
    
    if __name__ == "__main__":
        asyncio.run(test_server())
  3. 新しいターミナルで、テストサーバーを実行します。

    uv run test_server.py
    

    次の出力が表示されます。

     🛠️ Tool found: add
     🛠️ Tool found: subtract
     🪛 Calling add tool for 1 + 2
     ✅ Result: 3
     🪛 Calling subtract tool for 10 - 3
     ✅ Result: 7
    

テレメトリー データを表示する

このセクションでは、自己ホスト型の MCP サーバーが生成するログ、指標、トレースデータを表示する方法について説明します。

始める前に

ログ、指標、トレースデータを表示するために必要な権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。

ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

テレメトリーを表示する

ログ、指標、トレースデータを表示する方法については、以下をご覧ください。

ログデータ

コンソールで、セグメント [] ページに移動します。 Google Cloud

[ログ エクスプローラ] に移動

検索バーを使用してこのページを検索する場合は、小見出しが [Logging] の結果を選択します。

[ログ エクスプローラ] ページの使用方法については、 ログを表示して分析するをご覧ください。

指標データ

コンソールで、 [**Metrics Explorer**] ページに移動します。 Google Cloud

[Metrics Explorer] に移動

検索バーを使用してこのページを検索する場合は、小見出しが [Monitoring] である結果を選択します。

[Metrics Explorer] ページの使用方法については、 Metrics Explorer でグラフを作成するをご覧ください。

トレース データ

コンソールで、 [ Trace エクスプローラ] ページに移動します。 Google Cloud

[Trace エクスプローラ] に移動

このページは、検索バーを使用して見つけることもできます。

次のスクリーンショットは、[Trace エクスプローラ] ページの [詳細] ペインを示しています。このペインには、tools/call オペレーションから生成されたトレース スパンが表示されます。

トレースと関連するスパンが表示されている詳細ウィンドウ。

[Trace エクスプローラ] ページの使用方法については、 トレースを検索して調査するをご覧ください。

次のステップ