Remote-MCP-Server in Cloud Run erstellen und bereitstellen

In dieser Anleitung erfahren Sie, wie Sie einen Remote-Server für das Model Context Protocol (MCP) in Cloud Run mit dem streamable HTTP transport erstellen und bereitstellen. Beim streamfähigen HTTP-Transport läuft der MCP-Server als unabhängiger Prozess, der mehrere Clientverbindungen verarbeiten kann.

Hinweise

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure 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.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Richten Sie Ihre Cloud Run-Entwicklungsumgebung in Ihrem Google Cloud -Projekt ein.
  7. 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.
  8. Weisen Sie Ihrem Konto die Rolle Cloud Run Invoker (roles/run.invoker) zu. Mit dieser Rolle kann der Remote-MCP-Server auf den Cloud Run-Dienst zugreifen.
  9. 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 Zugriff erlauben.
    4. Geben Sie im Feld Neue Hauptkonten Ihre Nutzer-ID ein. Dies ist in der Regel die E-Mail-Adresse des Google-Kontos, das 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_NUMBER: Ihre Google Cloud -Projektnummer.
    • PROJECT_ID: Ihre Google Cloud -Projekt-ID.
    • PRINCIPAL: Die E-Mail-Adresse des Kontos, dem Sie die Rolle zuweisen.
    • ROLE: Die Rolle, die Sie dem Konto des Bereitstellers hinzufügen.
  10. Wenn Sie einer Domaineinschränkung zur Organisation nicht eingeschränkter Aufrufe für Ihr Projekt unterliegen, müssen Sie auf Ihren bereitgestellten Dienst zugreifen, wie unter Private Dienste testen beschrieben.

  11. Installieren Sie Uv, einen Python-Paket- und Projektmanager.
  12. 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
      • test_server.py, um den Remote-Server zu testen
      • Dockerfile für die Bereitstellung in Cloud Run
      touch server.py test_server.py Dockerfile
      

      Ihr Projektverzeichnis sollte die folgende Struktur haben:

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

    MCP-Server für mathematische Operationen erstellen

    Um wertvollen Kontext für die Verbesserung der Verwendung von LLMs mit MCP bereitzustellen, richten Sie einen mathematischen MCP-Server 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.8.0 --no-sync
      
    2. Fügen Sie der Datei server.py den folgenden Quellcode für den Math-MCP-Server hinzu:

      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),
              )
          )
      
    3. 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 remote-mcp-servers \
      --repository-format=docker \
      --location=us-central1 \
      --description="Repository for remote 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/remote-mcp-servers/mcp-server:latest
      
    3. Stellen Sie das MCP-Server-Container-Image in Cloud Run bereit:

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

    Quelle

    Sie können Remote-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 Remote-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 Remote-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 Remote-MCP-Server weiter.

    Remote-MCP-Server testen

    Sie testen und stellen eine Verbindung zum Remote-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:

      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[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[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
      

    Nächste Schritte