Instrumenter un serveur MCP auto-hébergé avec OpenTelemetry

Ce document décrit les étapes à suivre pour instrumenter et déployer un serveur MCP (Model Context Protocol) auto-hébergé, ce qui permet de collecter des données de télémétrie. L' exemple présenté dans ce document crée un serveur MCP à l'aide de FastMCP et le déploie à l'aide de Cloud Run. FastMCP inclut une instrumentation OpenTelemetry qui collecte des données de télémétrie à partir de toutes les opérations MCP.

Ce document décrit les étapes suivantes :

  1. Préparer votre projet Python avec le gestionnaire de packages uv.
  2. Créer un serveur MCP pour les opérations mathématiques.
  3. Déployer une application sur Cloud Run.
  4. Authentifier le client MCP.
  5. Tester le serveur MCP auto-hébergé.
  6. Afficher vos données de télémétrie.

Avant de commencer

  1. Connectez-vous à votre Google Cloud compte. Si vous n'avez jamais utilisé Google Cloud, créez un compte pour évaluer les performances de nos produits dans des scénarios réels. Les nouveaux clients bénéficient également de 300 $ de crédits sans frais pour exécuter, tester et déployer des charges de travail.
  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. Activez les API Artifact Registry, Cloud Run, Cloud Build, Telemetry, Cloud Logging, Cloud Monitoring et Cloud Trace.

    Rôles requis pour activer les API

    Pour activer les API, vous avez besoin du rôle IAM Administrateur de l'utilisation des services (roles/serviceusage.serviceUsageAdmin), qui contient l'autorisation serviceusage.services.enable. Découvrez comment attribuer des rôles.

    Activer les API

  7. Configurez votre environnement de développement Cloud Run dans votre Google Cloud projet.
  8. Assurez-vous de disposer des autorisations appropriées pour déployer des services, et que les rôles Administrateur Cloud Run (roles/run.admin) et Utilisateur du compte de service (roles/iam.serviceAccountUser) sont attribués à votre compte.
  9. Attribuez le rôle Demandeur Cloud Run (roles/run.invoker) à votre compte. Ce rôle permet au serveur MCP auto-hébergé d'accéder au service Cloud Run.
  10. Découvrez comment attribuer les rôles

    Console

    1. Dans la console Google Cloud , accédez à la page IAM.

      Accéder à IAM
    2. Sélectionnez le projet.
    3. Cliquez sur Accorder l'accès.
    4. Dans le champ Nouveaux comptes principaux, saisissez votre identifiant utilisateur. Il s'agit généralement de l'adresse e-mail utilisée pour déployer le service Cloud Run.

    5. Dans la liste Sélectionner un rôle, sélectionnez un rôle.
    6. Pour attribuer des rôles supplémentaires, cliquez sur Add another role , puis ajoutez chaque rôle supplémentaire.
    7. Cliquez sur Enregistrer.

    gcloud

    Pour attribuer les rôles IAM requis à votre compte dans votre projet :

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

    Remplacez :

    • PROJECT_ID : identifiant du projet.
    • PRINCIPAL : identifiant du compte principal auquel vous souhaitez attribuer le rôle. Les identifiants principaux se présentent généralement comme suit : PRINCIPAL-TYPE:ID. Par exemple, user:my-user@example.com. Pour obtenir la liste complète des formats que PRINCIPAL peut prendre, consultez Identifiants de compte principal.
    • ROLE : rôle IAM.
  11. Si vous êtes soumis à une règle d'administration de restriction de domaine limitant les appels non authentifiés pour votre projet, vous devez accéder au service déployé comme décrit dans la section Tester les services privés.

  12. Installez Uv, un gestionnaire de packages et de projets Python.

Préparer votre projet Python

Les étapes suivantes décrivent comment configurer votre projet Python avec le gestionnaire de packages uv.

  1. Créez un dossier nommé mcp-on-cloudrun pour stocker le code source à déployer :

      mkdir mcp-on-cloudrun
      cd mcp-on-cloudrun
    
  2. Créez un projet Python avec l'outil uv pour générer un fichier pyproject.toml :

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

    La commande uv init crée le fichier pyproject.toml suivant :

    [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. Créez les fichiers supplémentaires suivants :

    • server.py pour le code source du serveur MCP.
    • otel_setup.py pour configurer OpenTelemetry.
    • test_server.py pour tester le serveur auto-hébergé.
    • Un fichier Dockerfile pour le déploiement sur Cloud Run.
    touch server.py otel_setup.py test_server.py Dockerfile
    

    La structure de votre répertoire de projet doit être la suivante :

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

Créer un serveur MCP pour les opérations mathématiques

Dans cette section, vous allez configurer un serveur MCP mathématique avec FastMCP. FastMCP permet de créer rapidement des serveurs et des clients MCP avec Python.

Suivez ces étapes pour créer un serveur MCP pour les opérations mathématiques telles que l'addition et la soustraction.

  1. Exécutez la commande suivante pour ajouter FastMCP et les dépendances OpenTelemetry requises dans le fichier pyproject.toml :

    uv add fastmcp==3.2.0 opentelemetry-api==1.40.0 opentelemetry-sdk==1.40.0 opentelemetry-exporter-otlp-proto-grpc==1.40.0 --no-sync
    
  2. Ajoutez le code de configuration OpenTelemetry suivant dans le fichier otel_setup.py :

    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. Ajoutez le code source du serveur MCP mathématique suivant dans le fichier server.py :

    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. Incluez le code suivant dans le fichier Dockerfile pour utiliser l'outil uv afin d'exécuter le fichier server.py :

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

Déployer une application sur Cloud Run

Vous pouvez déployer le serveur MCP en tant qu' image de conteneur ou en tant que code source:

Image de conteneur

Pour déployer un serveur MCP empaqueté en tant qu'image de conteneur, suivez ces instructions.

  1. Créez un dépôt Artifact Registry pour stocker l'image de conteneur :

    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. Créez l'image de conteneur et transférez-la vers Artifact Registry avec Cloud Build :

    gcloud builds submit --region=us-central1 --tag us-central1-docker.pkg.dev/PROJECT_ID/self-hosted-mcp-servers/mcp-server:latest
    
  3. Déployez l'image de conteneur serveur MCP sur 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
    

Source

Vous pouvez déployer des serveurs MCP auto-hébergés sur Cloud Run à partir de leurs sources.

Déployez votre code depuis la source en exécutant la commande suivante :

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

Authentifier le client MCP

Si vous avez déployé votre service avec l'indicateur --no-allow-unauthenticated, tout client MCP qui se connecte à votre serveur MCP auto-hébergé doit s'authentifier.

  1. Attribuez le rôle Demandeur Cloud Run (roles/run.invoker) au compte de service. Cette liaison de stratégie Identity and Access Management garantit qu'un mécanisme de sécurité renforcé est utilisé pour authentifier votre client MCP local.

  2. Exécutez le proxy Cloud Run pour créer un tunnel authentifié vers le serveur MCP auto-hébergé sur votre machine locale :

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

    Si le proxy Cloud Run n'est pas encore installé, cette commande vous invite à le télécharger. Suivez les instructions pour télécharger et installer le proxy.

Cloud Run authentifie tout le trafic vers http://127.0.0.1:8080 et transfère les requêtes au serveur MCP auto-hébergé.

Tester le serveur MCP auto-hébergé

Vous testez votre serveur MCP auto-hébergé et vous y connectez à l'aide du client FastMCP et en accédant à l'URL http://127.0.0.1:8080/mcp.

Pour tester et appeler le mécanisme d'ajout et de soustraction, procédez comme suit :

  1. Avant d'exécuter le serveur de test, exécutez le proxy Cloud Run.

  2. Créez un fichier de test nommé test_server.py et ajoutez le code suivant :

    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. Dans un nouveau terminal, exécutez le serveur de test :

    uv run test_server.py
    

    Vous devriez obtenir le résultat suivant :

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

Afficher vos données de télémétrie

Cette section explique comment afficher les données de journal, de métriques et de trace générées par votre serveur MCP auto-hébergé.

Avant de commencer

Pour obtenir les autorisations nécessaires pour afficher vos données de journal, de métriques et de trace, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :

Pour en savoir plus sur l'attribution de rôles, consultez Gérer l'accès aux projets, aux dossiers et aux organisations.

Vous pouvez également obtenir les autorisations requises avec des rôles personnalisés ou d'autres rôles prédéfinis.

Afficher les données de télémétrie

Pour savoir comment afficher vos données de journal, de métriques et de trace, consultez les ressources suivantes :

Données des journaux

Dans la Google Cloud console, accédez à la Explorateur de journaux :

Accéder à l'explorateur de journaux

Si vous utilisez la barre de recherche pour trouver cette page, sélectionnez le résultat dont le sous-titre est Logging.

Pour en savoir plus sur l'utilisation de la page Explorateur de journaux, consultez Afficher et analyser les journaux.

Données de métriques

Dans la Google Cloud console, accédez à la  page Explorateur de métriques :

Accéder à l'Explorateur de métriques

Si vous utilisez la barre de recherche pour trouver cette page, sélectionnez le résultat dont le sous-titre est Monitoring.

Pour en savoir plus sur l'utilisation de la page Explorateur de métriques, consultez Créer des graphiques avec l'explorateur de métriques.

Données de trace

Dans la Google Cloud console, accédez à la Explorateur Trace page :

Accéder à Explorateur Trace

Vous pouvez également accéder à cette page à l'aide de la barre de recherche.

La capture d'écran suivante illustre le volet Détails de la page Explorateur Trace, qui affiche les étendues de trace générées à partir des opérations tools/call :

Volet &quot;Détails&quot; affichant une trace et les spans associés.

Pour en savoir plus sur l'utilisation de la page Explorateur Trace, consultez Rechercher et explorer des traces.

Étape suivante