Crear y desplegar un servidor de MCP remoto en Cloud Run

En este tutorial se muestra cómo crear y desplegar un servidor de Model Context Protocol (MCP) remoto en Cloud Run mediante el transporte HTTP de flujo. Con el transporte HTTP de streaming, el servidor de MCP funciona como un proceso independiente que puede gestionar varias conexiones de clientes.

Preparar un proyecto de Python

En los siguientes pasos se describe cómo configurar tu proyecto de Python con el gestor de paquetes uv.

  1. Crea una carpeta llamada mcp-on-cloudrun para almacenar el código fuente de la implementación:

      mkdir mcp-on-cloudrun
      cd mcp-on-cloudrun
    
  2. Crea un proyecto de Python con la herramienta uv para generar un archivo pyproject.toml:

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

    El comando uv init crea el siguiente archivo 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. Crea los siguientes archivos adicionales:

    • server.py para el código fuente del servidor MCP
    • test_server.py para probar el servidor remoto
    • Un archivo Dockerfile para desplegar en Cloud Run
    touch server.py test_server.py Dockerfile
    

    El directorio de tu proyecto debe tener la siguiente estructura:

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

Crear un servidor de MCP para operaciones matemáticas

Para proporcionar un contexto valioso que permita mejorar el uso de los LLMs con MCP, configura un servidor de MCP matemático con FastMCP. FastMCP ofrece una forma rápida de crear servidores y clientes de MCP con Python.

Sigue estos pasos para crear un servidor MCP para operaciones matemáticas, como sumas y restas.

  1. Ejecuta el siguiente comando para añadir FastMCP como dependencia en el archivo pyproject.toml:

    uv add fastmcp==2.8.0 --no-sync
    
  2. Añade el siguiente código fuente del servidor MCP matemático al archivo 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. Incluye el siguiente código en el archivo Dockerfile para usar la herramienta uv y ejecutar el archivo 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"]
    

Desplegar en Cloud Run

Puedes desplegar el servidor de MCP como una imagen de contenedor o como código fuente:

Imagen de contenedor

Para desplegar un servidor de MCP empaquetado como imagen de contenedor, sigue estas instrucciones.

  1. Crea un repositorio de Artifact Registry para almacenar la imagen de contenedor:

    gcloud artifacts repositories create remote-mcp-servers \
    --repository-format=docker \
    --location=us-central1 \
    --description="Repository for remote MCP servers" \
    --project=PROJECT_ID
    
  2. Crea la imagen de contenedor y envíala a Artifact Registry con Cloud Build:

    gcloud builds submit --region=us-central1 --tag us-central1-docker.pkg.dev/PROJECT_ID/remote-mcp-servers/mcp-server:latest
    
  3. Despliega la imagen del contenedor del servidor de MCP en 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
    

Fuente

Puedes desplegar servidores de MCP remotos en Cloud Run desde sus fuentes.

Para desplegar desde el código fuente, ejecuta el siguiente comando:

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

Autenticar el cliente de MCP

Si has implementado tu servicio con la marca --no-allow-unauthenticated, cualquier cliente de MCP que se conecte a tu servidor MCP remoto debe autenticarse.

  1. Asigna el rol Invocador de Cloud Run (roles/run.invoker) a la cuenta de servicio. Este enlace de política de gestión de identidades y accesos asegura que se utilice un mecanismo de seguridad sólido para autenticar tu cliente MCP local.

  2. Ejecuta el proxy de Cloud Run para crear un túnel autenticado al servidor de MCP remoto en tu máquina local:

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

    Si el proxy de Cloud Run aún no está instalado, este comando te pedirá que lo descargues. Sigue las indicaciones para descargar e instalar el proxy.

Cloud Run autentica todo el tráfico a http://127.0.0.1:8080 y reenvía las solicitudes al servidor de MCP remoto.

Probar el servidor MCP remoto

Para probar el servidor MCP remoto y conectarte a él, usa el cliente FastMCP y accede a la URL http://127.0.0.1:8080/mcp.

Para probar e invocar el mecanismo de suma y resta, sigue estos pasos:

  1. Antes de ejecutar el servidor de prueba, ejecuta el proxy de Cloud Run.

  2. Crea un archivo de prueba llamado test_server.py y añade el siguiente 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. En un nuevo terminal, ejecuta el servidor de prueba:

    uv run test_server.py
    

    Deberías ver este resultado:

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