Selbst gehosteten MCP-Server mit OpenTelemetry instrumentieren

In diesem Dokument wird beschrieben, wie Sie einen selbst gehosteten MCP-Server (Model Context Protocol) instrumentieren und bereitstellen, um die Erfassung von Telemetriedaten zu ermöglichen. Im Beispiel in diesem Dokument wird ein MCP-Server mit FastMCP erstellt und mit Cloud Run bereitgestellt. FastMCP enthält OpenTelemetry-Instrumentierung, mit der Telemetriedaten aus allen MCP-Vorgängen erfasst werden.

In diesem Dokument werden die folgenden Schritte beschrieben:

  1. Bereiten Sie Ihr Python-Projekt mit dem Paketmanager uv vor.
  2. MCP-Server für mathematische Operationen erstellen
  3. In Cloud Run bereitstellen
  4. MCP-Client authentifizieren:
  5. Selbst gehosteten MCP-Server testen
  6. Telemetriedaten ansehen

Hinweis

  1. Melden Sie sich in Ihrem Google Cloud -Konto an. Wenn Sie mit Google Cloudnoch nicht vertraut sind, erstellen Sie ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  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. Aktivieren Sie die APIs für Artifact Registry, Cloud Run, Cloud Build, Telemetry, Cloud Logging, Cloud Monitoring und Cloud Trace.

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die IAM-Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin), die die Berechtigung serviceusage.services.enable enthält. Weitere Informationen zum Zuweisen von Rollen

    APIs aktivieren

  7. Richten Sie Ihre Cloud Run-Entwicklungsumgebung in Ihrem Google Cloud Projekt ein.
  8. Achten Sie darauf, dass Sie die entsprechenden Berechtigungen zum Bereitstellen von Diensten haben und Ihrem Konto die Rollen Cloud Run-Administrator (roles/run.admin) und Dienstkontonutzer (roles/iam.serviceAccountUser) zugewiesen sind.
  9. Weisen Sie Ihrem Konto die Rolle Cloud Run Invoker (roles/run.invoker) zu. Mit dieser Rolle kann der selbst gehostete MCP-Server auf den Cloud Run-Dienst zugreifen.
  10. Rollen zuweisen

    Console

    1. Rufen Sie in der Google Cloud Console die Seite IAM auf.

      IAM aufrufen
    2. Wählen Sie das Projekt aus.
    3. Klicken Sie auf Zugriffsrechte erteilen.
    4. Geben Sie im Feld Neue Hauptkonten Ihre Nutzer-ID ein. Dies ist in der Regel die E-Mail-Adresse, die zum Bereitstellen des Cloud Run-Dienstes verwendet wurde.

    5. Wählen Sie in der Liste Rolle auswählen eine Rolle aus.
    6. Wenn Sie weitere Rollen zuweisen möchten, klicken Sie auf Weitere Rolle hinzufügen und fügen Sie weitere Rollen hinzu.
    7. Klicken Sie auf Speichern.

    gcloud

    So weisen Sie Ihrem Konto die erforderlichen IAM-Rollen für Ihr Projekt zu:

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

    Ersetzen Sie:

    • PROJECT_ID: Die Kennung des Projekts.
    • PRINCIPAL: Eine Kennzeichnung für das Hauptkonto, dem Sie die Rolle zuweisen möchten. Hauptkonto-Kennzeichnungen haben normalerweise das folgende Format: PRINCIPAL-TYPE:ID. Beispiel: user:my-user@example.com Eine vollständige Liste der Formate, die PRINCIPAL haben kann, finden Sie unter Hauptkonto-IDs.
    • ROLE: Eine IAM-Rolle.
  11. Wenn Sie einer Organisationsrichtlinie zur Domaineinschränkung nicht eingeschränkter Aufrufe für Ihr Projekt unterliegen, müssen Sie auf Ihren bereitgestellten Dienst zugreifen, wie unter Private Dienste testen beschrieben.

  12. Installieren Sie Uv, einen Python-Paket- und Projektmanager.

Python-Projekt vorbereiten

In den folgenden Schritten wird beschrieben, wie Sie Ihr Python-Projekt mit dem Paketmanager uv einrichten.

  1. Erstellen Sie einen Ordner mit dem Namen mcp-on-cloudrun, um den Quellcode für die Bereitstellung zu speichern:

      mkdir mcp-on-cloudrun
      cd mcp-on-cloudrun
    
  2. Erstellen Sie mit dem Tool uv ein Python-Projekt, um eine pyproject.toml-Datei zu generieren:

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

    Mit dem Befehl uv init wird die folgende Datei pyproject.toml erstellt:

    [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. Erstellen Sie die folgenden zusätzlichen neuen Dateien:

    • server.py für den MCP-Server-Quellcode.
    • otel_setup.py, um OpenTelemetry zu konfigurieren.
    • test_server.py, um den selbst gehosteten Server zu testen.
    • Ein Dockerfile für die Bereitstellung in Cloud Run.
    touch server.py otel_setup.py test_server.py Dockerfile
    

    Ihr Projektverzeichnis sollte die folgende Struktur haben:

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

MCP-Server für mathematische Operationen erstellen

In diesem Abschnitt richten Sie einen MCP-Server für Mathematik mit FastMCP ein. FastMCP bietet eine schnelle Möglichkeit, MCP-Server und ‑Clients mit Python zu erstellen.

So erstellen Sie einen MCP-Server für mathematische Operationen wie Addition und Subtraktion:

  1. Führen Sie den folgenden Befehl aus, um FastMCP als Abhängigkeit in der Datei pyproject.toml hinzuzufügen:

    uv add fastmcp==2.13.1 --no-sync
    
  2. Fügen Sie der Datei otel_setup.py den folgenden OpenTelemetry-Einrichtungscode hinzu:

    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. Fügen Sie der Datei server.py den folgenden MCP-Server-Quellcode für mathematische Funktionen hinzu:

    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. Fügen Sie der Dockerfile den folgenden Code hinzu, um das Tool uv zum Ausführen der Datei server.py zu verwenden:

    # 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"]
    

In Cloud Run bereitstellen

Sie können den MCP-Server als Container-Image oder als Quellcode>bereitstellen.

Container-Image

Folgen Sie dieser Anleitung, um einen MCP-Server bereitzustellen, der als Container-Image verpackt ist.

  1. Erstellen Sie ein Artifact Registry-Repository zum Speichern des Container-Images:

    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. Erstellen Sie das Container-Image und übertragen Sie es per Push mit Cloud Build in Artifact Registry:

    gcloud builds submit --region=us-central1 --tag us-central1-docker.pkg.dev/PROJECT_ID/self-hosted-mcp-servers/mcp-server:latest
    
  3. Stellen Sie das Container-Image des MCP-Servers in Cloud Run bereit:

    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
    

Quelle

Sie können selbst gehostete MCP-Server aus ihren Quellen in Cloud Run bereitstellen.

Stellen Sie es mit dem folgenden Befehl aus der Quelle bereit:

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

MCP-Client authentifizieren

Wenn Sie Ihren Dienst mit dem Flag --no-allow-unauthenticated bereitgestellt haben, muss sich jeder MCP-Client, der eine Verbindung zu Ihrem selbst gehosteten MCP-Server herstellt, authentifizieren.

  1. Weisen Sie dem Dienstkonto die Rolle Cloud Run Invoker (roles/run.invoker) zu. Diese Identity and Access Management-Richtlinienbindung sorgt dafür, dass ein starker Sicherheitsmechanismus zur Authentifizierung Ihres lokalen MCP-Clients verwendet wird.

  2. Führen Sie den Cloud Run-Proxy aus, um einen authentifizierten Tunnel zum selbst gehosteten MCP-Server auf Ihrem lokalen Computer zu erstellen:

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

    Wenn der Cloud Run-Proxy noch nicht installiert ist, werden Sie mit diesem Befehl aufgefordert, ihn herunterzuladen. Folgen Sie der Anleitung, um den Proxy herunterzuladen und zu installieren.

Cloud Run authentifiziert den gesamten Traffic zu http://127.0.0.1:8080 und leitet Anfragen an den selbst gehosteten MCP-Server weiter.

Selbst gehosteten MCP-Server testen

Sie testen und stellen eine Verbindung zu Ihrem selbst gehosteten MCP-Server her, indem Sie den FastMCP-Client verwenden und auf die URL http://127.0.0.1:8080/mcp zugreifen.

So testen und rufen Sie den Mechanismus zum Addieren und Subtrahieren auf:

  1. Bevor Sie den Testserver ausführen, führen Sie den Cloud Run-Proxy aus.

  2. Erstellen Sie eine Testdatei mit dem Namen test_server.py und fügen Sie den folgenden Code ein:

    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. Führen Sie in einem neuen Terminal den Testserver aus:

    uv run test_server.py
    

    Es sollte folgende Ausgabe angezeigt werden:

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

Telemetriedaten ansehen

In diesem Abschnitt wird beschrieben, wie Sie die Log-, Messwert- und Tracedaten ansehen können, die von Ihrem selbst gehosteten MCP-Server generiert werden.

Hinweis

Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen für Ihr Projekt zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Aufrufen Ihrer Log-, Messwert- und Tracedaten benötigen:

Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.

Telemetriedaten ansehen

Informationen zum Aufrufen Ihrer Log-, Messwert- und Trace-Daten finden Sie unter:

Logdaten

Rufen Sie in der Google Cloud Console das und die Seite Log-Explorer auf:

Zum Log-Explorer

Wenn Sie diese Seite über die Suchleiste suchen, wählen Sie das Ergebnis mit der Zwischenüberschrift Logging aus.

Weitere Informationen zur Verwendung der Seite Log-Explorer finden Sie unter Logs ansehen und analysieren.

Messwertdaten

Rufen Sie in der Google Cloud Console das auf der Seite des Metrics Explorer auf:

Zu Metrics Explorer

Wenn Sie diese Seite über die Suchleiste suchen, wählen Sie das Ergebnis aus, dessen Zwischenüberschrift Monitoring ist.

Weitere Informationen zur Verwendung der Seite Metrics Explorer finden Sie unter Diagramme mit dem Metrics Explorer erstellen.

Trace-Daten

Rufen Sie in der Google Cloud Console die Seite Trace Explorer auf:

Zum Trace Explorer

Sie können diese Seite auch über die Suchleiste finden.

Der folgende Screenshot zeigt den Bereich Details auf der Seite Trace Explorer, in dem Trace-Spans angezeigt werden, die aus tools/call-Vorgängen generiert wurden:

Der Detailbereich zeigt einen Trace und die zugehörigen Spans an.

Weitere Informationen zur Verwendung der Seite Trace-Explorer finden Sie unter Traces suchen und untersuchen.

Nächste Schritte