Aller au contenu principal

Déployer un Serveur MCP en Production

Du prototype au serveur de production

Votre serveur MCP fonctionne en local avec ngrok. Il est temps de le déployer sur une infrastructure accessible 24h/24. Cette leçon couvre les principales options de déploiement, de la plus simple à la plus robuste.

Option 1 : Hugging Face Spaces (gratuit)

Hugging Face Spaces offre des machines virtuelles gratuites (sans GPU) parfaites pour héberger un serveur MCP. C’est l’option la plus rapide pour un premier déploiement.

Structure du projet

mon-mcp-space/
├── app.py              # Serveur FastAPI + MCP
├── requirements.txt    # Dépendances
└── README.md           # Metadata du Space

Le fichier app.py

# app.py
"""Serveur MCP déployé sur Hugging Face Spaces."""

import os
from fastapi import FastAPI
from mcp.server.fastmcp import FastMCP

api = FastAPI()
mcp = FastMCP("Mon Serveur Production")

@mcp.tool()
def hello(name: str) -> str:
    """Salue une personne.

    Args:
        name: Le prénom de la personne

    Returns:
        Message de salutation
    """
    return f"Bonjour {name} depuis Hugging Face Spaces !"

mcp.mount(api, path="/mcp-endpoint")

# Pour les variables sensibles, utilisez les Secrets HF
API_KEY = os.environ.get("MY_API_KEY", "")

Le README.md (metadata du Space)

---
title: Mon Serveur MCP
emoji: 🔧
colorFrom: blue
colorTo: green
sdk: docker
app_port: 7860
---

Déploiement

# Créer un Space sur huggingface.co
# Pousser le code
git push
# Le Space se déploie automatiquement

L’endpoint MCP sera : https://votre-username-mon-mcp-space.hf.space/mcp-endpoint/mcp

Option 2 : Docker (cloud ou serveur dédié)

Docker est la solution standard pour un déploiement contrôlé sur votre propre infrastructure.

Dockerfile

FROM python:3.12-slim

WORKDIR /app

# Installer les dépendances
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copier le code
COPY . .

# Exposer le port
EXPOSE 8000

# Lancer le serveur
CMD ["uvicorn", "server:api", "--host", "0.0.0.0", "--port", "8000"]

requirements.txt

fastapi>=0.115.0
uvicorn>=0.30.0
mcp>=1.0.0
fastmcp>=0.5.0
httpx>=0.27.0

Build et lancement

# Build l'image
docker build -t mon-mcp-server .

# Lancer le conteneur
docker run -d \
  --name mcp-server \
  -p 8000:8000 \
  -e MY_API_KEY="secret" \
  -e DATABASE_URL="postgresql://..." \
  --restart unless-stopped \
  mon-mcp-server

Avec Docker Compose

# docker-compose.yml
version: "3.8"
services:
  mcp-server:
    build: .
    ports:
      - "8000:8000"
    environment:
      - MY_API_KEY=${MY_API_KEY}
      - DATABASE_URL=${DATABASE_URL}
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/"]
      interval: 30s
      retries: 3

Option 3 : FastMCP Cloud

FastMCP Cloud permet de déployer directement depuis un dépôt GitHub :

# Installer le CLI FastMCP
pip install fastmcp

# Déployer depuis GitHub
fastmcp deploy --repo https://github.com/user/mon-mcp-server

Le service génère automatiquement une URL publique pour votre serveur.

Option 4 : Cloudflare Workers

Pour un déploiement serverless à faible latence :

# Utiliser le template MCP de Cloudflare
npm create cloudflare@latest -- mon-mcp --template=cloudflare/ai/demos/remote-mcp-server

Sécuriser le déploiement

HTTPS obligatoire

Tout serveur MCP de production doit être accessible en HTTPS. Les options :

  • Reverse proxy : Nginx ou Caddy devant votre serveur, avec certificat Let’s Encrypt
  • Cloud natif : Hugging Face, Cloudflare et la plupart des PaaS fournissent HTTPS automatiquement
  • Tunnel : Cloudflare Tunnel pour exposer un serveur local en HTTPS

Variables d’environnement

Ne codez jamais de secrets en dur. Utilisez des variables d’environnement :

import os

# Configuration via variables d'environnement
API_TOKEN = os.environ["MCP_API_TOKEN"]       # Obligatoire
DATABASE_URL = os.environ.get("DATABASE_URL")  # Optionnel
DEBUG = os.environ.get("DEBUG", "false") == "true"

Rate limiting

Protégez votre serveur contre les abus :

from fastapi import FastAPI, Request
from slowapi import Limiter, _rate_limit_exceeded_handler

limiter = Limiter(key_func=lambda request: request.client.host)
api = FastAPI()
api.state.limiter = limiter

@api.middleware("http")
async def rate_limit(request: Request, call_next):
    # 100 requêtes par minute par IP
    ...

Monitoring et logs

En production, surveillez votre serveur :

import logging
import time

logger = logging.getLogger("mcp-server")

@mcp.tool()
async def my_tool(param: str) -> str:
    """Mon tool avec logging."""
    start = time.time()
    logger.info(f"Tool appelé avec param={param}")

    try:
        result = await process(param)
        duration = time.time() - start
        logger.info(f"Tool terminé en {duration:.2f}s")
        return result
    except Exception as e:
        logger.error(f"Erreur dans le tool : {e}")
        raise

Checklist de déploiement

  • HTTPS actif et certificat valide
  • Variables d’environnement pour tous les secrets
  • Logs structurés activés
  • Health check endpoint (/ ou /health)
  • Restart automatique en cas de crash
  • Rate limiting configuré
  • Test avec MCP Inspector depuis l’extérieur
  • Test depuis Le Chat de Mistral

Points clés à retenir

  • Hugging Face Spaces : le plus rapide, gratuit, idéal pour commencer
  • Docker : contrôle total, adapté aux serveurs dédiés et au cloud
  • FastMCP Cloud : déploiement simplifié depuis GitHub
  • Cloudflare Workers : serverless, faible latence, scalable
  • Sécurisez avec HTTPS, variables d’environnement, et rate limiting
  • Ajoutez du monitoring et des logs pour le debugging en production