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