Créer un serveur MCP local et le rendre accessible à distance sont deux tâches différentes. Le code expose des capacités ; le déploiement doit aussi gérer le transport, la disponibilité et les autorisations. Ce guide construit un outil Python minimal puis décrit les contrôles nécessaires avant son ouverture sur Internet.

La vidéo de novembre 2025 est conservée comme contexte historique. La procédure ci-dessous s’appuie sur le SDK Python officiel, branche 1.x, et non sur une transcription de cette vidéo. Exemple documenté, non exécuté sur un hébergement distant : aucun fournisseur, certificat ou raccordement OAuth n’a été provisionné pour cet article.

1. Installer le SDK dans un projet isolé

Prévois Python 3.10 ou une version compatible avec le paquet résolu, uv, Node.js 22.19 ou plus récent pour Inspector,[5] puis un hébergement capable de maintenir un processus Python. Un espace qui sert uniquement des fichiers statiques ne suffit pas.

uv init mcp-demo
cd mcp-demo
uv add 'mcp[cli]>=1.28,<2'

La borne supérieure est intentionnelle : la documentation officielle 1.x distingue cette branche de maintenance du SDK 2.x.[6] Ce n’est pas une recommandation d’ignorer les nouvelles versions. Si tu choisis 2.x, utilise son guide de migration au lieu de mélanger les API. Conserve uv.lock pour reproduire l’environnement.

2. Exposer une capacité sans effet de bord

Crée server.py avec un outil qui fournit un statut constant. Il ne lit aucune base et ne déclenche aucune action externe.

from mcp.server.fastmcp import FastMCP

mcp = FastMCP(
    'Diagnostic',
    host='127.0.0.1',
    port=8000,
    stateless_http=True,
    json_response=True,
)


@mcp.tool()
def service_status() -> str:
    """Retourne le statut de la démonstration, sans données sensibles."""
    return 'demo-ready'


if __name__ == '__main__':
    mcp.run(transport='streamable-http')

Cette adaptation utilise les outils FastMCP et le transport Streamable HTTP décrits par le SDK.[7] Le mode sans état convient à cette démonstration sans conversation ni stockage. Il ne résout ni l’authentification ni la protection des données.

Démarre le serveur :

uv run python -m py_compile server.py
uv run python server.py

Résultat attendu : le processus démarre sur la boucle locale et propose l’endpoint MCP /mcp. La compilation vérifie seulement la syntaxe Python ; elle ne teste pas le protocole ou les dépendances importées à l’exécution.

3. Vérifier le protocole, pas seulement le port

Dans un second terminal :

npx -y @modelcontextprotocol/inspector

Avec Inspector, sélectionne Streamable HTTP, connecte-toi à http://127.0.0.1:8000/mcp, liste les outils puis appelle service_status.[5] Le résultat attendu est demo-ready. C’est une valeur fixée par notre exemple, pas une mesure de santé de ton hébergement.

Une réponse HTTP obtenue par un GET simple ne valide pas la négociation MCP. Inversement, un GET refusé ne prouve pas à lui seul que le serveur est cassé : teste avec un client qui sait initialiser le protocole.[5]

4. Déployer d’abord derrière un accès privé

Pour la première installation distante, garde le serveur accessible par SSH uniquement. Sur le serveur, copie le projet et son verrouillage, puis lance :

uv sync --frozen
uv run python server.py

Depuis ton poste, ouvre un tunnel :

ssh -L 8000:127.0.0.1:8000 utilisateur@ton-serveur

Connecte Inspector à la même URL locale. Ce contrôle valide le chemin distant sans rendre l’endpoint anonyme. Adapte le port si un autre service utilise déjà 8000. Le tunnel reste ouvert tant que ta session SSH reste active ; ce n’est pas un service de production supervisé.

5. Préparer la publication HTTPS

Avant de donner une URL distante à un client IA, mets en place ces éléments :

  1. Un processus supervisé, redémarré après une panne ou un redémarrage de la machine, avec un utilisateur système peu privilégié.
  2. Un domaine et un certificat HTTPS valides, terminés par un reverse proxy.
  3. Un proxy vers 127.0.0.1:8000 qui conserve le chemin /mcp, les méthodes et les en-têtes nécessaires au protocole.
  4. Un mécanisme d’authentification compatible avec le client choisi, puis des autorisations vérifiées à chaque appel.
  5. Des journaux sans secrets, des limites d’accès et un contrôle après redémarrage.

Le guide de sécurité MCP traite notamment de la validation des jetons et des frontières de confiance.[8] Ne transmets pas aveuglément à un service tiers le jeton reçu du client. Une URL difficile à deviner ou HTTPS seul ne remplace pas une autorisation.

Ce guide ne fournit pas de configuration OAuth prête à déployer : le fournisseur d’identité, les clients et le domaine conditionnent cette étape. N’ouvre pas l’endpoint sur Internet tant que ces contrôles ne sont pas implémentés.

Contrôler le résultat et diagnostiquer

Après publication, reprends le test Inspector sur l’URL HTTPS finale : découverte puis appel. Vérifie aussi qu’un client non autorisé est refusé, que le service repart après un redémarrage et que le proxy ne transforme pas le chemin ou les réponses. Un 404 suggère une erreur de route ; un échec uniquement à distance invite à contrôler proxy, authentification et restrictions d’hôte.[7][8]

Pour une intégration PHP plutôt que Python, utilise le tutoriel du bundle MCP Symfony. La vidéo associée reste disponible pour son contexte de déploiement initial ; ce guide n’en reproduit pas les commandes d’hébergement.

Sources

[5] https://modelcontextprotocol.io/docs/tools/inspector [6] https://github.com/modelcontextprotocol/python-sdk/tree/v1.x [7] https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/docs/server.md [8] https://modelcontextprotocol.io/specification/latest/basic/security_best_practices