Instrumentar um servidor MCP auto-hospedado com o OpenTelemetry

Este documento descreve as etapas para instrumentar e implantar um servidor do Protocolo de Contexto de Modelo (MCP) auto-hospedado, permitindo a coleta de telemetria. O exemplo neste documento cria um servidor MCP usando o FastMCP e o implanta usando o Cloud Run. O FastMCP inclui a instrumentação do OpenTelemetry que coleta telemetria de todas as operações do MCP.

Este documento descreve as seguintes etapas:

  1. Prepare seu projeto Python com o gerenciador de pacotes uv.
  2. Crie um servidor MCP para operações matemáticas.
  3. Implante no Cloud Run.
  4. Autentique o cliente MCP.
  5. Teste o servidor MCP auto-hospedado.
  6. Acesse seus dados de telemetria.

Antes de começar

  1. Faça login na sua Google Cloud conta do. Se você começou a usar o Google Cloudagora, crie uma conta para avaliar o desempenho dos nossos produtos em situações reais. Clientes novos também recebem US $300 em créditos para executar, testar e implantar cargas de trabalho.
  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. Ative as APIs Artifact Registry, Cloud Run, Cloud Build, Telemetry, Cloud Logging, Cloud Monitoring e Cloud Trace.

    Funções necessárias para ativar APIs

    Para ativar as APIs, é necessário ter o papel do IAM de administrador de uso do serviço (roles/serviceusage.serviceUsageAdmin), que contém a permissão serviceusage.services.enable. Saiba como conceder papéis.

    Ativar as APIs

  7. Configure o ambiente de desenvolvimento do Cloud Run no seu Google Cloud projeto do.
  8. Verifique se você tem as permissões adequadas para implantar serviços e os papéis de administrador do Cloud Run (roles/run.admin) e usuário da conta de serviço (roles/iam.serviceAccountUser) concedidos à sua conta.
  9. Conceda o papel de invocador do Cloud Run (roles/run.invoker) à sua conta. Esse papel permite que o servidor MCP auto-hospedado acesse o serviço do Cloud Run.
  10. Saiba como conceder os papéis

    Console

    1. No Google Cloud console, acesse a página IAM.

      Acessar IAM
    2. Selecione o projeto.
    3. Clique em CONCEDER ACESSO.
    4. No campo Novos principais, digite seu identificador de usuário. Normalmente, esse é o endereço de e-mail usado para implantar o serviço do Cloud Run.

    5. Na lista Selecionar papel, escolha um.
    6. Para conceder outros papéis, adicione-os clicando em Adicionar outro papel.
    7. Clique em Salvar.

    gcloud

    Para conceder os papéis do IAM necessários à sua conta no seu projeto:

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

    Substitua:

    • PROJECT_ID: o identificador do projeto.
    • PRINCIPAL: um identificador para o principal a quem você quer conceder o papel. Os identificadores principais geralmente têm o seguinte formato: PRINCIPAL-TYPE:ID. Por exemplo, user:my-user@example.com. Para uma lista completa dos formatos que PRINCIPAL pode ter, consulte Identificadores de principais.
    • ROLE: um papel do IAM.
  11. Se você precisa seguir uma política da organização de restrição de domínio que restringe invocações não autenticadas para seu projeto, será necessário acessar o serviço implantado, conforme descrito em Como testar serviços particulares.

  12. Instale o Uv, um gerenciador de pacotes e projetos do Python.

Preparar seu projeto Python

As etapas a seguir descrevem como configurar seu projeto Python com o gerenciador de pacotes uv.

  1. Crie uma pasta chamada mcp-on-cloudrun para armazenar o código-fonte da implantação:

      mkdir mcp-on-cloudrun
      cd mcp-on-cloudrun
    
  2. Crie um projeto Python com a ferramenta uv para gerar um arquivo pyproject.toml:

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

    O comando uv init cria o seguinte arquivo 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. Crie os seguintes novos arquivos adicionais:

    • server.py para o código-fonte do servidor MCP.
    • otel_setup.py para configurar o OpenTelemetry.
    • test_server.py para testar o servidor auto-hospedado.
    • Um Dockerfile para implantação no Cloud Run.
    touch server.py otel_setup.py test_server.py Dockerfile
    

    O diretório do projeto precisa conter a seguinte estrutura:

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

Criar um servidor MCP para operações matemáticas

Nesta seção, você vai configurar um servidor MCP matemático com FastMCP. O FastMCP oferece uma maneira rápida de criar servidores e clientes MCP com Python.

Siga estas etapas para criar um servidor MCP para operações matemáticas, como adição e subtração.

  1. Execute o seguinte comando para adicionar o FastMCP como uma dependência no arquivo pyproject.toml:

    uv add fastmcp==2.13.1 --no-sync
    
  2. Adicione o seguinte código de configuração do OpenTelemetry no arquivo 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. Adicione o seguinte código-fonte do servidor MCP matemático no arquivo 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. Inclua o seguinte código no Dockerfile para usar a ferramenta uv para executar o arquivo 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"]
    

Implantar no Cloud Run

É possível implantar o servidor MCP como uma imagem do contêiner ou como código-fonte:

Imagem do contêiner

Para implantar um servidor MCP empacotado como uma imagem de contêiner, siga estas instruções.

  1. Crie um repositório do Artifact Registry para armazenar a imagem do contêiner:

    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. Crie a imagem do contêiner e envie-a para o Artifact Registry com o Cloud Build:

    gcloud builds submit --region=us-central1 --tag us-central1-docker.pkg.dev/PROJECT_ID/self-hosted-mcp-servers/mcp-server:latest
    
  3. Implante a imagem do contêiner do servidor MCP no 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
    

Origem

É possível implantar servidores MCP auto-hospedados no Cloud Run das origens deles.

Implante a partir da origem executando o seguinte comando:

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

Autenticar o cliente MCP

Se você implantou o serviço com a flag --no-allow-unauthenticated, qualquer cliente MCP que se conectar ao servidor MCP auto-hospedado precisará ser autenticado.

  1. Conceda o papel de invocador do Cloud Run (roles/run.invoker) à conta de serviço. Essa vinculação de política do Identity and Access Management garante que um mecanismo de segurança forte seja usado para autenticar o cliente MCP local.

  2. Execute o proxy do Cloud Run para criar um túnel autenticado para o servidor MCP auto-hospedado na máquina local:

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

    Se o proxy do Cloud Run ainda não estiver instalado, esse comando vai pedir que você faça o download do proxy. Siga as instruções para fazer o download e instalar o proxy.

O Cloud Run autentica todo o tráfego para http://127.0.0.1:8080 e encaminha solicitações para o servidor MCP auto-hospedado.

Testar o servidor MCP auto-hospedado

Você testa e se conecta ao servidor MCP auto-hospedado usando o cliente FastMCP e acessando o URL http://127.0.0.1:8080/mcp.

Para testar e invocar o mecanismo de adição e subtração, siga estas etapas:

  1. Antes de executar o servidor de teste, execute o proxy do Cloud Run.

  2. Crie um arquivo de teste chamado test_server.py e adicione o seguinte código:

    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. Em um novo terminal, execute o servidor de teste:

    uv run test_server.py
    

    Você verá esta resposta:

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

Acessar seus dados de telemetria

Esta seção descreve como acessar os dados de registro, métrica e trace gerados pelo servidor MCP auto-hospedado.

Antes de começar

Para receber as permissões necessárias para acessar os dados de registro, métrica e trace, peça que o administrador conceda a você os seguintes papéis do IAM no projeto:

Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias usando personalizados papéis ou outros predefinidos papéis.

Acessar a telemetria

Para saber como acessar os dados de registro, métrica e trace, consulte o seguinte:

Dados de registros

No Google Cloud console do, acesse a página Análise de registros:

Acessar a Análise de registros

Se você usar a barra de pesquisa para encontrar essa página, selecione o resultado com o subtítulo Logging.

Para mais informações sobre como usar a página Análise de registros, consulte Acessar e analisar registros.

Dados de métricas

No Google Cloud console, acesse a  Metrics explorer page:

Acesse o Metrics Explorer

Se você usar a barra de pesquisa para encontrar essa página, selecione o resultado com o subtítulo Monitoring.

Para mais informações sobre como usar a página Metrics Explorer, consulte Criar gráficos com o Metrics Explorer.

Rastrear dados

No Google Cloud console, acesse a página Explorador de traces:

Acessar o Explorador de traces

Também é possível encontrar essa página usando a barra de pesquisa.

A captura de tela a seguir ilustra o painel Detalhes na página Explorador de traces, que mostra os intervalos de trace gerados pelas operações tools/call:

Painel de detalhes mostrando um trace e os períodos associados.

Para mais informações sobre como usar a página Explorador de traces, consulte Encontrar e explorar traces.

A seguir