Criar e implantar um servidor MCP remoto no Cloud Run

Neste tutorial, mostramos como criar e implantar um servidor remoto do Model Context Protocol (MCP) no Cloud Run usando o transporte HTTP transmitível. Com o transporte HTTP de streaming, o servidor MCP opera como um processo independente que pode processar várias conexões de clientes.

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 para implantação:

      mkdir mcp-on-cloudrun
      cd mcp-on-cloudrun
    
  2. Crie um projeto em 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 arquivos adicionais:

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

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

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

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

Para fornecer um contexto valioso para melhorar o uso de LLMs com o MCP, configure um servidor MCP de matemática com o 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 comando a seguir para adicionar o FastMCP como uma dependência no arquivo pyproject.toml:

    uv add fastmcp==2.8.0 --no-sync
    
  2. Adicione o seguinte código-fonte do servidor MCP de matemática ao arquivo server.py:

    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. Inclua o código a seguir no Dockerfile para usar a ferramenta uv e 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 de 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 remote-mcp-servers \
    --repository-format=docker \
    --location=us-central1 \
    --description="Repository for remote 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/remote-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/remote-mcp-servers/mcp-server:latest \
    --region=us-central1 \
    --no-allow-unauthenticated
    

Origem

É possível implantar servidores MCP remotos 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 remoto precisará se autenticar.

  1. Conceda o papel 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 seu cliente MCP local.

  2. Execute o proxy do Cloud Run para criar um túnel autenticado para o servidor MCP remoto na sua 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 dele. 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 remoto.

Testar o servidor MCP remoto

Teste e conecte-se ao servidor MCP remoto 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:

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