Configurer un Serveur SSE Distant
Mis à jour le 29 juillet 2026
Passer du local au distant
Jusqu’ici, votre serveur MCP vivait sur votre machine et communiquait par STDIO. Ce mode est idéal pour développer, mais il enferme votre travail : personne d’autre que vous ne peut l’utiliser, et Le Chat de Mistral ne pourra jamais lancer un processus sur votre poste. Pour franchir cette frontière, il faut exposer le serveur en HTTP.
Le changement est plus léger qu’on ne l’imagine. Un serveur MCP distant publie ses tools sur une URL ; le client — Le Chat, un SDK, un IDE — s’y connecte par le réseau au lieu de démarrer un processus. Le code de vos tools, lui, ne bouge pas.
Le serveur ne change presque pas
FastMCP prend en charge le transport Streamable HTTP nativement. Le fichier ci-dessous est écrit exactement comme un serveur local : mêmes décorateurs, mêmes docstrings, mêmes signatures typées.
# serveur_distant.py
"""Serveur MCP distant avec transport HTTP."""
from mcp.server.fastmcp import FastMCP
# Le serveur est le même qu'en local
app = FastMCP("Serveur Distant Démo")
@app.tool()
def analyze_text(text: str, language: str = "fr") -> str:
"""Analyse un texte et retourne des statistiques.
Args:
text: Le texte à analyser
language: Code langue (fr, en, es). Défaut : fr
Returns:
Statistiques du texte : nombre de mots, caractères, phrases
"""
words = len(text.split())
chars = len(text)
sentences = text.count(".") + text.count("!") + text.count("?")
return (
f"Langue : {language}\n"
f"Mots : {words}\n"
f"Caractères : {chars}\n"
f"Phrases : {sentences}"
)
@app.tool()
def summarize_key_points(text: str, max_points: int = 5) -> str:
"""Extrait les points clés d'un texte (version simplifiée).
Args:
text: Le texte source
max_points: Nombre maximum de points à extraire (1-10)
Returns:
Liste des points clés identifiés
"""
sentences = [s.strip() for s in text.split(".") if len(s.strip()) > 20]
points = sentences[:max_points]
return "\n".join(f"- {p}" for p in points) if points else "Aucun point clé identifié."
Ce qui change n’est pas le code mais la commande de lancement : vous demandez explicitement le transport HTTP et un port.
# Lancer le serveur FastMCP en mode HTTP
fastmcp run serveur_distant.py --transport streamable-http --port 8000
Votre serveur écoute désormais sur http://localhost:8000/mcp. C’est déjà du HTTP, mais l’adresse reste inaccessible depuis l’extérieur de votre machine.
Obtenir une URL publique avec ngrok
Pour tester votre serveur depuis Le Chat sans passer par un vrai déploiement, ngrok crée un tunnel entre une URL publique et votre port local. C’est l’outil qui raccourcit le plus la boucle de développement : vous modifiez un tool, vous relancez, et le connecteur distant voit immédiatement la nouvelle version.
# Installer ngrok (une seule fois)
pip install ngrok
# ou via le site officiel : https://ngrok.com/download
# Exposer le port 8000
ngrok http 8000
ngrok vous attribue une adresse du type https://abc123.ngrok-free.app. Votre endpoint MCP devient donc celui-ci, en ajoutant simplement le chemin /mcp :
https://abc123.ngrok-free.app/mcp
Cette URL s’ajoute telle quelle dans Le Chat de Mistral comme connecteur custom. Souvenez-vous qu’elle est temporaire et qu’elle expose votre machine : ne laissez pas un tunnel ouvert sur un serveur qui touche à des données réelles.
Connecter un client Python
Côté client, la structure du code reste celle de la leçon sur le RunContext. Seule la classe de connexion diffère : MCPClientSSE avec SSEServerParams remplace le duo STDIO, et vous fournissez une URL plutôt qu’une commande.
# client_distant.py
import asyncio
from mistralai import Mistral
from mistralai.extra.run.context import RunContext
from mistralai.extra.mcp.streamable_http import (
MCPClientStreamableHTTP,
StreamableHTTPServerParams,
)
async def main():
client = Mistral(api_key="VOTRE_CLE_API")
agent = client.beta.agents.create(
model="mistral-medium-latest",
name="assistant-distant",
instructions="Vous utilisez des outils distants pour analyser du texte.",
)
# Connexion au serveur distant
server_url = "https://abc123.ngrok-free.app/mcp"
mcp_client = MCPClientStreamableHTTP(
params=StreamableHTTPServerParams(
url=server_url,
timeout=100, # Timeout en secondes
)
)
async with RunContext(
agent_id=agent.id,
continue_on_fn_error=True,
) as run_ctx:
await run_ctx.register_mcp_client(mcp_client=mcp_client)
result = await client.beta.conversations.run_async(
run_ctx=run_ctx,
inputs="Analyse ce texte : Le MCP est un protocole ouvert.",
)
print(result.output)
asyncio.run(main())
Le paramètre timeout mérite un instant de réflexion. En STDIO, l’appel était quasi instantané ; sur le réseau, un tool qui interroge une API tierce ou traite un gros document peut prendre plusieurs dizaines de secondes. Un timeout trop court se manifeste par des erreurs intermittentes et difficiles à reproduire, généralement sur les requêtes les plus utiles.
Quand le serveur attend des en-têtes particuliers — un jeton d’API, une clé de routage, une contrainte CORS —, vous les passez dans headers :
mcp_client = MCPClientStreamableHTTP(
params=StreamableHTTPServerParams(
url="https://mon-serveur.example.com/mcp",
timeout=100,
headers={
"Authorization": "Bearer mon_token_api",
"X-Custom-Header": "valeur",
},
)
)
Plusieurs serveurs sur un seul hôte
La leçon 3 recommandait des serveurs focalisés plutôt qu’un catalogue fourre-tout. Cette recommandation ne vous condamne pas à louer une machine par serveur : avec FastAPI, vous montez plusieurs serveurs MCP sur des routes distinctes d’un même hôte.
# server.py — Plusieurs serveurs MCP sur un seul hôte
from contextlib import asynccontextmanager
from fastapi import FastAPI
from mcp.server.fastmcp import FastMCP
# Serveur MCP pour l'analyse de texte
text_mcp = FastMCP("Text Analysis")
@text_mcp.tool()
def analyze(text: str) -> str:
"""Analyse un texte."""
return f"Mots: {len(text.split())}"
# Serveur MCP pour les calculs
math_mcp = FastMCP("Math Tools")
@math_mcp.tool()
def calculate(expression: str) -> str:
"""Évalue une expression mathématique."""
return str(eval(expression)) # Attention : eval en prod !
# Chaque serveur MCP produit une application ASGI autonome
text_app = text_mcp.streamable_http_app()
math_app = math_mcp.streamable_http_app()
# Lifespan combiné : chaque serveur doit démarrer son gestionnaire de sessions
@asynccontextmanager
async def lifespan(app: FastAPI):
async with text_mcp.session_manager.run(), math_mcp.session_manager.run():
yield
api = FastAPI(lifespan=lifespan)
api.mount("/text", text_app)
api.mount("/math", math_app)
Vous obtenez deux endpoints indépendants, https://mon-serveur.com/text/mcp pour les outils d’analyse de texte et https://mon-serveur.com/math/mcp pour les outils mathématiques, que l’on ajoute séparément dans Le Chat. Le point à ne pas manquer est le lifespan : chaque serveur MCP possède un gestionnaire de sessions qu’il faut démarrer explicitement, et si vous montez les applications sans transmettre ce lifespan à FastAPI, le serveur répond mais chaque appel d’outil échoue sur une erreur de tâche non initialisée. Un utilisateur qui n’a besoin que du calcul n’encombrera pas son contexte avec les tools de texte. Le commentaire sur eval n’est pas une plaisanterie : sur un endpoint public, cette ligne exécute n’importe quel code envoyé par l’appelant — c’est un exemple pédagogique, jamais un patron de production.
Un réflexe pour terminer : avant d’ajouter votre URL dans un chat, repassez-la à l’Inspector. Un endpoint distant ajoute des sources de panne que le local ignorait — tunnel fermé, en-tête manquant, port occupé — et il vaut mieux les découvrir en dehors d’une conversation.
Points clés à retenir
- Un serveur MCP distant expose ses tools via HTTP sur un endpoint
/mcp - ngrok permet d’obtenir une URL publique pour le développement
MCPClientStreamableHTTPavecStreamableHTTPServerParamsconnecte le client au serveur distant (MCPClientSSEne sert plus qu’aux anciens endpoints/sse)- Le paramètre timeout est important pour les serveurs lents
- Vous pouvez monter plusieurs serveurs MCP sur un même hôte FastAPI, à condition de transmettre leur lifespan
- Testez toujours avec l’Inspector avant d’intégrer dans un chat