Tutoriel MCP : De zéro à serveur en production avec la spécification 2026-07-28
Points clés
- 97M+ téléchargements mensuels du SDK MCP, mais seulement 8,5% des serveurs utilisent OAuth — l'adoption du protocole dépasse sa posture de sécurité, rendant les étapes de durcissement de production de ce tutoriel non optionnelles pour tout déploiement B2B.
- MCP SDK v2 a réduit la taille du paquet de 83% et amélioré la vitesse de 25% — la spécification 2026-07-28 a été livrée avec des SDK repensés pour TypeScript, Python, Go et C#, avec des guides de migration pour chacun.
- La spécification 2026-07-28 a supprimé les sessions et le handshake d'initialisation — chaque requête est désormais autonome, atterrissant sur n'importe quelle instance de serveur derrière un simple load balancer round-robin sans état partagé.
- La feuille de route MCP du 22 août définit cinq domaines prioritaires — identité d'agents, unification du transport HTTP, primitives de messagerie agentique, primitives d'outils améliorées et expérience développeur SDK — chacun couvert dans le chemin de production de ce tutoriel.
- 82% des serveurs MCP sont vulnérables au path traversal (selon Practical DevSecOps) — les étapes de sandboxing et de validation des entrées ici font la différence entre une démo et un déploiement.
Le Model Context Protocol a dépassé 97 millions de téléchargements mensuels du SDK en 2026, les SDK TypeScript et Python dépassant chacun le milliard de téléchargements totaux. La spécification 2026-07-28 a livré la plus grande révision depuis le lancement : un cœur de protocole stateless, des extensions de première classe et trois déprécations qui simplifient la surface de déploiement. Trois semaines plus tard, le 22 août, les mainteneurs MCP ont publié une nouvelle feuille de route définissant cinq domaines prioritaires pour le prochain cycle de spécification — identité d'agents, unification du transport HTTP, primitives de messagerie agentique, primitives d'outils améliorées et expérience développeur SDK.
Ce tutoriel couvre le chemin de production : construire un serveur MCP qui est stateless, évolutif horizontalement, conscient de l'identité et prêt pour les priorités entreprise de la feuille de route. Le quickstart officiel parcourt un serveur météo connecté à Claude Desktop. Cet article commence là où ce quickstart se termine — les étapes entre une démo fonctionnelle et un serveur que vous mettriez derrière un système d'agents B2B en production.
Étape 1 — Configuration du projet avec SDK v2
La spécification 2026-07-28 a été livrée avec des SDK repensés. Le TypeScript SDK v2 a réduit la taille du paquet d'environ 83% et amélioré les performances de 25% grâce à une nouvelle séparation client-serveur. Le Python SDK 2.0+, le Go SDK et le C# SDK v2.0 parlent tous la version de protocole 2026-07-28 à partir du jour de publication, avec des notes de migration détaillées pour les changements cassants.
Pour ce tutoriel, nous utilisons Python 3.10+ avec uv :
uv init mcp-server
cd mcp-server
uv venv
source .venv/bin/activate
uv add "mcp[cli]"L'extra mcp[cli] apporte les outils CLI pour exécuter et inspecter les serveurs. Le SDK utilise les type hints et docstrings Python pour générer automatiquement les définitions d'outils — vous définissez une fonction, la décorez, et les métadonnées du protocole sont dérivées de la signature.
Étape 2 — Définissez vos premiers outils
Un serveur MCP expose trois types de capacités : tools (fonctions que le modèle appelle), resources (données que le modèle lit) et prompts (workflows basés sur des modèles). Pour un serveur B2B, les tools sont la surface principale — c'est ainsi qu'un agent recherche dans un catalogue, génère un devis ou réserve du stock.
from mcp.server import MCPServer
mcp = MCPServer("catalog-server")
@mcp.tool()
async def search_catalog(query: str, supplier_id: str | None = None) -> str:
"""Search the supplier catalog by keyword, optionally filtered by supplier.
Args:
query: Search keyword (SKU, product name, or category)
supplier_id: Optional supplier filter (e.g., "s-12")
"""
results = await catalog.search(query=query, supplier_id=supplier_id)
return format_results(results)
@mcp.tool()
async def get_pricing(sku: str, quantity: int) -> str:
"""Get tiered pricing for a SKU at a given quantity.
Args:
sku: Supplier product identifier
quantity: Order quantity (determines pricing tier)
"""
price = await pricing_engine.get(sku=sku, quantity=quantity)
return f"SKU {sku}: ${price.unit_price:.2f} (tier: {price.tier_name})"Le docstring de chaque outil devient la description que le modèle voit dans sa liste d'outils. Les type hints deviennent le schéma d'entrée. C'est le modèle du MCP Module Code Standard : chaque outil a un schéma typé, un docstring clair et une seule responsabilité.
Piège du logging STDIO : pour les serveurs basés sur STDIO, n'écrivez jamais sur stdout — cela corrompt le flux de messages JSON-RPC. Utilisez le module standard logging, qui écrit sur stderr :
import logging
logger = logging.getLogger(__name__)
logger.info("Catalog search: query=%s", query) # stderr, safeÉtape 3 — Transport : STDIO vs Streamable HTTP
La spécification 2026-07-28 fait des serveurs MCP distants « rien de plus qu'une autre charge HTTP » (changelog de la spécification). Le deuxième domaine prioritaire de la feuille de route — l'unification du transport HTTP-native — étend cela aux serveurs locaux parlant Streamable HTTP sur stdio, unifiant sur un modèle de transport.
Pour le développement local et les clients de bureau, STDIO est le défaut :
if __name__ == "__main__":
mcp.run(transport="stdio")Pour les déploiements B2B en production — où l'agent s'exécute comme une charge cloud, pas comme une application de bureau — Streamable HTTP est le transport de production. Le serveur s'exécute derrière un load balancer, accepte les requêtes HTTP POST avec les en-têtes Mcp-Method et Mcp-Name, et répond avec JSON-RPC sur HTTP :
if __name__ == "__main__":
mcp.run(transport="http", host="0.0.0.0", port=8080)Le routage basé sur les en-têtes signifie que votre gateway, votre limiteur de débit ou votre WAF peut router et mesurer directement sur les en-têtes Mcp-Method et Mcp-Name — aucune analyse du corps JSON nécessaire pour les décisions de routage. C'est la forme de déploiement pour laquelle le protocole stateless a été conçu : un pool d'instances de serveurs stateless derrière un load balancer round-robin, sans couche de session partagée.
Étape 4 — Handles explicites pour les workflows avec état
Stateless ne signifie pas que l'état disparaît. La spécification 2026-07-28 remplace l'état de session caché par le modèle de handle explicite : un outil crée un handle (un order_id, un quote_id, un basket_id) et le modèle le repasse comme un argument ordinaire lors des appels suivants. Ceci est couvert en détail dans MCP 2026-07-28 : Ce que le protocole stateless signifie pour les déploiements d'agents B2B.
Pour un workflow de devis couvrant cinq appels d'outils — créer une demande, rechercher dans le catalogue, générer un devis, réserver la disponibilité, appliquer le niveau de prix — les handles traversent chaque appel :
@mcp.tool()
async def create_request(buyer_id: str, line_items: list[dict]) -> str:
"""Create an RFQ request and return a request_id handle."""
request = await rfq_engine.create(buyer_id, line_items)
return f"request_id={request.id}"
@mcp.tool()
async def generate_quote(request_id: str, supplier_ids: list[str]) -> str:
"""Generate a quote from specified suppliers. Returns quote_id."""
quote = await rfq_engine.quote(request_id, supplier_ids)
return f"quote_id={quote.id}"Chaque appel porte le handle dont il a besoin. Aucun serveur ne se souvient de rien entre les appels. Si le load balancer route l'appel 4 vers une instance différente de l'appel 3, cela fonctionne toujours — le handle est dans la requête. Si l'équipe d'audit doit reconstruire ce workflow une semaine plus tard, les handles dans les arguments de la requête racontent l'histoire complète.
Étape 5 — Identité d'agents : la lacune entreprise
Le troisième domaine prioritaire de la feuille de route — identité d'agents et sécurité entreprise — est le plus significatif pour les déploiements B2B. La feuille de route est explicite : l'autorisation MCP aujourd'hui est « construite autour d'une personne approuvant l'accès dans un navigateur », mais « de plus en plus d'appelants sont des agents s'exécutant comme des charges cloud avec leur propre identité, agissant au nom d'un utilisateur qui n'est pas présent, ou déléguant une autorité plus restreinte à des sous-agents. »
Le chemin à suivre, tel que défini par la feuille de route :
- DPoP (RFC 9449) — Demonstrating Proof of Possession lie un token OAuth à une clé détenue par le client. Un token volé seul ne peut pas rejouer des requêtes depuis un autre processus. DPoP ne décide pas ce que l'agent est autorisé à faire ; il rend la credential plus difficile à réutiliser en dehors de son détenteur prévu.
- Workload Identity Federation — le groupe de travail IETF WIMSE développe une architecture pour l'identité de charge de travail dans des environnements multi-systèmes. Un agent est une charge de travail, il obtient donc une identité de charge de travail : nommée avec un SPIFFE ID, authentifiée avec des credentials de courte durée, pas une clé API partagée.
- Enterprise-Managed Authorization (EMA) — l'extension EMA déplace la décision d'accès vers le fournisseur d'identité de l'organisation. Le client MCP échange une assertion d'identité utilisateur contre un Identity Assertion JWT Authorization Grant (ID-JAG), puis échange ce grant contre un token d'accès spécifique au serveur. Cela permet l'attribution et la révocation centralisées.
Pour le serveur de production de ce tutoriel, la ligne de base minimale est :
- Pas de clés API partagées. Chaque agent obtient un token de courte durée, lié à une audience.
- OAuth avec DPoP. Le rapport Practical DevSecOps MCP Security Statistics 2026 a trouvé que seulement 8,5% des serveurs MCP utilisent OAuth — les 91,5% restants s'appuient sur des clés API ou aucune authentification.
- Échange de tokens à chaque frontière de confiance. Le standard d'échange de tokens CoSAI (publié le 18 août) établit l'échange de tokens comme contrôle fondamental pour les workflows agentiques. Chaque point d'entrée
register_tools()devrait accepter un token à portée de tâche, pas une credential persistante.
Voir la MCP Security Hardening Checklist pour les 12 contrôles qui vérifient ces standards avant la production, et le MCP Module Code Standard pour la posture défensive au niveau du module.
Étape 6 — Découverte progressive d'outils : résoudre le problème des cent outils
Le quatrième domaine prioritaire de la feuille de route — primitives améliorées — adresse un problème de production concret : « Se connecter à un serveur avec cent outils signifie que le modèle paie pour toute cette surface avant que l'utilisateur n'ait posé une seule question, et la sélection d'outils tend à se dégrader à mesure que la liste s'allonge. »
La réponse de la feuille de route est la découverte progressive : un serveur offre un petit point d'entrée et révèle plus de son catalogue à mesure que la conversation se resserre. Au lieu de déverser 100 schémas d'outils dans la fenêtre de contexte du modèle à la connexion, le serveur expose une poignée d'outils de premier niveau et étend dynamiquement la surface selon ce que l'agent fait.
La spécification 2026-07-28 fournit déjà les blocs de construction :
- RPC
server/discover— un client peut apprendre les capacités d'un serveur avant de faire quoi que ce soit d'autre, sans handshake de session. tools/listavecttlMsetcacheScope— les réponses de liste portent des indices de cache, donc les clients mettent en cache les catalogues d'outils et évitent de refetcher à chaque connexion._metasur chaque requête — version du protocole, info client et capacités voyagent par requête, pas dans une session négociée.
Pour un serveur avec 50+ outils, le modèle de découverte progressive ressemble à ceci :
@mcp.tool()
async def discover_tools(category: str) -> str:
"""Discover available tools in a category. Start here for a guided tour.
Args:
category: Tool category — 'catalog', 'pricing', 'inventory', 'orders'
"""
available = tool_registry.by_category(category)
return format_tool_list(available)L'agent appelle d'abord discover_tools("catalog"), obtient un ensemble ciblé de 5-8 outils, et ne s'étend à d'autres catégories que lorsque le workflow l'exige. Cela garde la fenêtre de contexte légère et la sélection d'outils précise — le même principe derrière la conception d'outils à responsabilité unique du MCP Module Code Standard.
Étape 7 — Déploiement : stateless, horizontal, derrière un load balancer
La forme de déploiement pour laquelle la spécification 2026-07-28 a été conçue :
┌──────────────────┐
│ Load Balancer │
│ (round-robin) │
└────────┬─────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌────────┴────┐ ┌───────┴────┐ ┌───────┴────┐
│ MCP Server │ │ MCP Server │ │ MCP Server │
│ Instance 1 │ │ Instance 2 │ │ Instance 3 │
│ (stateless) │ │ (stateless) │ │ (stateless) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└──────────────┼──────────────┘
│
┌────────┴─────────┐
│ Upstream Systems │
│ (NetSuite, etc.) │
└──────────────────┘Pas de store de session partagé. Pas de load balancer avec sessions sticky. Pas d'infrastructure de replay de session. Chaque requête porte ce dont elle a besoin — version du protocole, info client, capacités et handles — dans le corps et les en-têtes de la requête, pas dans l'état côté serveur.
Pour le durcissement de production :
- Sandbox pour chaque instance de serveur. Le MCP Project Sandboxing Baseline (publié le 16 août) exige le sandboxing au niveau OS pour les processus générés. Utilisez Landlock (Linux), Seatbelt (macOS) ou les ACL Windows pour restreindre l'accès au système de fichiers et au réseau. Le taux de vulnérabilité au path traversal de 82% (selon Practical DevSecOps) est la preuve que la validation des entrées seule est insuffisante.
- Limiter le débit de chaque outil. Le MCP Module Code Standard exige des limites de débit par outil. La vulnérabilité DoS du MCP Ruby SDK (divulguée le 16 août) confirme que les attaques d'épuisement des ressources sont une surface d'attaque réelle.
- Logger vers OpenTelemetry, pas le canal de logging MCP. La spécification 2026-07-28 a déprécié la fonctionnalité Logging au profit de stderr et OpenTelemetry. Les logs du serveur MCP s'intègrent aux pipelines d'observabilité existants (Datadog, CloudWatch, Honeycomb) sans transport personnalisé.
- Utiliser le routage basé sur les en-têtes pour le WAF et la limitation de débit. Les en-têtes
Mcp-MethodetMcp-Namepermettent à votre gateway de router et autoriser sans analyser les corps JSON.
La feuille de route : cinq domaines prioritaires
La feuille de route du 22 août définit la direction pour le prochain cycle de spécification. Ce tutoriel couvre les parties prêtes pour la production ; la feuille de route nomme ce qui vient ensuite :
| Domaine prioritaire | Statut | Couverture du tutoriel |
|---|---|---|
| Identité d'agents et sécurité entreprise | En cours (DPoP, WIMSE, EMA) | Étape 5 — baseline établie ; implémentation complète en attente |
| Unification du transport HTTP-native | Livré (distant), en cours (local) | Étape 3 — HTTP distant est en production ; Streamable HTTP local sur stdio est l'objectif |
| Primitives de messagerie agentique | Extensions livrées (Tasks, abonnements) | Non couvert — les événements initiés par le serveur (webhooks, canaux) sont la prochaine frontière |
| Primitives améliorées (découverte progressive) | Phase de conception | Étape 6 — le modèle est implémentable aujourd'hui avec discover_tools ; le support au niveau spec arrive |
| Expérience développeur SDK améliorée | Livré (SDK v2, tests de conformité) | Étape 1 — SDK v2 est la baseline de production actuelle |
La feuille de route est une direction, pas une promesse de compatibilité. La spécification du 28 juillet a déjà livré le cœur HTTP stateless et l'extension Tasks. Les événements push, la découverte unifiée, la délégation et la conformité inter-SDK nécessitent encore du travail d'implémentation. Pour les déploiements B2B, la priorité d'identité d'agents est celle à surveiller — elle adresse exactement la lacune (clés API et tokens de longue durée) que les articles de sécurité MCP et la checklist de gouvernance signalent.
Le chemin de production du tutoriel couvre la checklist de production en cinq étapes :
Lecture associée
- MCP 2026-07-28 : Ce que le protocole stateless signifie pour les déploiements d'agents B2B — l'analyse complémentaire couvrant le protocole stateless, le modèle de handle explicite et les déprécations en profondeur
- MCP Module Code Standard — le modèle structurel qui rend chaque module prêt pour la production : structure de répertoire, enregistrement d'outils, gestion d'erreurs, limitation de débit et logging d'audit
- MCP Security Hardening Checklist : 1.467 serveurs exposés et les contrôles qui les ferment — les 12 contrôles qui vérifient un serveur avant la production, adressant les lacunes de path traversal de 82% et OAuth de 8,5%
Vignette de construction
Un distributeur de marché intermédiaire utilisant NetSuite voulait donner à son équipe commerciale un assistant IA qui pouvait rechercher dans les catalogues fournisseurs, générer des devis et vérifier les niveaux de stock sans quitter le CRM. La première tentative utilisait une seule clé API partagée entre toutes les instances d'agent — les 91,5% de serveurs MCP qui ignorent OAuth. Une mise à jour de liste de prix fournisseur a exposé la clé dans un fichier de log, et l'équipe a passé deux jours à faire tourner les credentials sur 15 services.
La reconstruction a suivi le chemin de production de ce tutoriel : SDK v2 avec des schémas d'outils typés, transport Streamable HTTP derrière un load balancer round-robin, tokens OAuth liés avec DPoP avec expiration de 15 minutes, handles explicites pour le workflow de devis en cinq étapes et sandboxing au niveau OS sur chaque instance de serveur. L'agent se connecte à NetSuite via un module MCP suivant le standard de code, avec découverte progressive exposant 8 outils de catalogue d'abord et s'étendant aux prix et à l'inventaire uniquement lorsque le workflow l'exige. Six instances de serveur s'exécutent stateless derrière le load balancer. Pas de store de session partagé. Pas de sessions sticky. Chaque requête porte son handle, son token et sa version de protocole.
Demandez une construction avec portée définie
Discovery d'une semaine. Vous obtenez un inventaire système, une carte des workflows et une portée fixe — que vous construisiez avec nous ou non.
Vous voulez cela construit pour vos systèmes ?
Chaque document ici provient d'un travail réel en production. Si vous avez un système cible et un flux en tête, nous pouvons cadrer une construction en une semaine.
Demander un projet cadréDécouverte d'une semaine. Vous obtenez un inventaire des systèmes, une cartographie des flux et un périmètre fixe — que vous construisiez avec nous ou non.