Cómo desplegar un MCP Server público con FastMCP, Docker y Traefik

En este tutorial aprenderás a crear y desplegar un MCP Server usando FastMCP, contenerizarlo con Docker, y exponerlo de manera segura en Internet utilizando Traefik como reverse proxy con certificados SSL automáticos de Let’s Encrypt. Al finalizar, podrás acceder a tu servidor en la URL:

https://mcp-server-demo.yourdomain.com

con SSL habilitado gracias a Traefik y Let’s Encrypt.

1. Iniciar el proyecto

Primero, inicializamos el proyecto con uv:

uv init mcp-server-docker-demo

Entramos en la carpeta del proyecto:

cd mcp-server-docker-demo/

2. Crear entorno virtual

Con uv puedes crear un entorno virtual fácilmente:

uv venv

Activar el entorno virtual

  • En Linux / macOS:
.venv/bin/activate
  • En Windows:
source .venv/Scripts/activate

3. Instalar FastMCP

Agregamos la librería FastMCP:

uv add fastmcp

4. Crear el archivo principal

Creamos src/main.py con el siguiente contenido:

""" FastMCP Demo """
from fastmcp import FastMCP

mcp = FastMCP(
    "Demo 🚀",
    host="0.0.0.0",
    port=9000
)

@mcp.tool
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

if __name__ == "__main__":
    mcp.run(transport="http")

Esto define un servidor MCP con un ejemplo de función (add) que suma dos números.


5. Crear el Dockerfile

Creamos un Dockerfile optimizado en dos etapas:

FROM ghcr.io/astral-sh/uv:python3.11-bookworm-slim AS uv

WORKDIR /app

COPY pyproject.toml /app/
COPY uv.lock /app/

RUN --mount=type=cache,target=/root/.cache/uv \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --frozen --no-dev --no-editable

ADD ./src/ /app/

FROM python:3.11-slim-bookworm

WORKDIR /app

COPY --from=uv /app/.venv /app/.venv
COPY --from=uv /app /app

ENV PATH="/app/.venv/bin:$PATH"
ENV PYTHONPATH=/app

ENTRYPOINT ["python", "./main.py"]

6. Crear docker-compose.yml

Creamos docker-compose.yml para levantar el servicio con Traefik:

services:
  mcp-server-demo:
    build:
      context: .
      dockerfile: Dockerfile
    # ports:
    #   - "9000:9000"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mcp-server-demo.rule=Host(`mcp-server-demo.yourdomain.com`)"
      - "traefik.http.services.mcp-server-demo.loadbalancer.server.port=9000"
      # SSL
      - "traefik.http.routers.mcp-server-demo.tls=true"
      - "traefik.http.routers.mcp-server-demo.entrypoints=websecure"
      - "traefik.http.routers.mcp-server-demo.tls.certresolver=letsencryptresolver"
    # volumes:
    #   - .env:/app/.env
    networks:
      - traefik-net

networks:
  traefik-net:
    external: true
    name: traefik-net

⚡ Importante: asegúrate de tener configurada una red externa traefik-net en tu servidor y que Traefik ya esté corriendo en esa red.


7. Desplegar el servidor

Finalmente, construimos y levantamos el contenedor:

docker compose up -d --build

Ahora tu MCP Server estará disponible en:

https://mcp-server-demo.yourdomain.com

con SSL habilitado gracias a Traefik y Let’s Encrypt.

8. Configura la Conexión en VS Code

Crea la carpeta .vscode en la raíz de tu proyecto si no existe, y dentro de ella, un archivo llamado mcp.json.

{
	"servers": {
		"mcp-server-demo": {
			"url": "https://mcp-server-demo.yourdomain.com/mcp/",
			// "headers": {
			// 	"Authorization": "Bearer <tu-token-secreto>"
			// },
			"type": "http"
		}
	},
	"inputs": []
}
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments