Crie e implemente um servidor MCP remoto no Cloud Run

Este tutorial mostra-lhe como criar e implementar um servidor do Protocolo de contexto do modelo (MCP) remoto no Cloud Run através do transporte HTTP streamable. Com o transporte HTTP por stream, o servidor MCP funciona como um processo independente que pode processar várias ligações de clientes.

Prepare o seu projeto Python

Os passos seguintes descrevem como configurar o seu projeto Python com o gestor de pacotes uv.

  1. Crie uma pasta denominada mcp-on-cloudrun para armazenar o código-fonte para a implementação:

      mkdir mcp-on-cloudrun
      cd mcp-on-cloudrun
    
  2. Crie um projeto Python com a ferramenta uv para gerar um ficheiro 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 ficheiro 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 ficheiros adicionais:

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

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

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

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

Para fornecer um contexto valioso para melhorar a utilização de MDIs com o MCP, configure um servidor do MCP matemático com o FastMCP. O FastMCP oferece uma forma rápida de criar servidores e clientes MCP com Python.

Siga estes passos 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 ficheiro pyproject.toml:

    uv add fastmcp==2.8.0 --no-sync
    
  2. Adicione o seguinte código-fonte do servidor MCP matemático no ficheiro 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 seguinte código no Dockerfile para usar a ferramenta uv para executar o ficheiro 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"]
    

Implemente no Cloud Run

Pode implementar o servidor MCP como uma imagem de contentor ou como código-fonte:

Imagem do contentor

Para implementar um servidor MCP incluído num pacote como uma imagem de contentor, siga estas instruções.

  1. Crie um repositório do Artifact Registry para armazenar a imagem de contentor:

    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 de contentor 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. Implemente a imagem do contentor do servidor da 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

Pode implementar servidores MCP remotos no Cloud Run a partir das respetivas origens.

Implemente a partir da origem executando o seguinte comando:

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

Autentique o cliente do MCP

Se implementou o seu serviço com a flag --no-allow-unauthenticated, qualquer cliente MCP que se ligue ao seu servidor MCP remoto tem de ser autenticado.

  1. Conceda a função Cloud Run Invoker (roles/run.invoker) à conta de serviço. Esta associação de políticas de gestão de identidades e acessos garante que é usado um mecanismo de segurança forte para autenticar o 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, este comando pede-lhe que transfira o proxy. Siga as instruções para transferir e instalar o proxy.

O Cloud Run autentica todo o tráfego para http://127.0.0.1:8080 e encaminha pedidos para o servidor MCP remoto.

Teste o servidor MCP remoto

Teste e estabeleça ligação ao servidor MCP remoto através do cliente FastMCP e acedendo ao URL http://127.0.0.1:8080/mcp.

Para testar e invocar o mecanismo de adição e subtração, siga estes passos:

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

  2. Crie um ficheiro de teste denominado 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. Num novo terminal, execute o servidor de teste:

    uv run test_server.py
    

    Deverá ver o seguinte resultado:

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