Passer au SDK v2 et à la spécification 2026-07-28
Sur cette page
Les exemples de ce cours sont écrits pour la version 2 du SDK Python mcp. Mais beaucoup de projets, de tutoriels et de serveurs existants restent écrits pour la branche 1.x, qui reçoit encore des versions. Cette leçon résume ce qui a changé en 2026, dans le protocole comme dans le SDK, et dans quel ordre migrer un projet 1.x, d’après la documentation officielle du protocole et le guide de migration du SDK. À la fin, vous saurez reconnaître un projet 1.x à son premier message d’erreur, et planifier sa migration.
Ce qui change dans le protocole
La version courante de la spécification MCP est la 2026-07-28. Son changement majeur est de rendre le protocole sans état. La poignée de main initialize disparaît : chaque requête porte elle-même la version du protocole et les capacités du client. Les sessions et l’en-tête Mcp-Session-Id du transport Streamable HTTP disparaissent aussi ; un serveur qui a besoin de conserver un état d’un appel à l’autre crée ses propres identifiants et les fait circuler comme arguments d’outils. Un nouvel appel, server/discover, permet au client de découvrir les versions et capacités du serveur.
Les requêtes que le serveur adressait au client — demander un échantillonnage au modèle (sampling), lister les racines (roots), solliciter l’utilisateur (élicitation) — passent par un nouveau mécanisme, les requêtes en plusieurs allers-retours : le serveur répond « il me manque une information », le client la fournit en relançant sa requête. Enfin, plusieurs fonctionnalités sont dépréciées : Roots, Sampling et Logging, ainsi que l’ancien transport HTTP+SSE. Elles restent utilisables pendant la période de dépréciation, mais une nouvelle implémentation ne doit plus les adopter.
Ce qui change dans le SDK Python
Le SDK mcp est passé en version 2 en août 2026 ; il parle la spécification 2026-07-28 tout en restant compatible avec les clients plus anciens. Le guide de migration liste les changements que presque tous les projets rencontrent :
| Changement | Premier symptôme |
|---|---|
FastMCP devient MCPServer | ModuleNotFoundError: No module named 'mcp.server.fastmcp' |
| Les champs passent de camelCase à snake_case | AttributeError: 'Tool' object has no attribute 'inputSchema' |
McpError devient MCPError | ImportError à l’import |
| Les URI de ressources sont de simples chaînes | AttributeError: 'str' object has no attribute 'host' |
streamablehttp_client est supprimé | ImportError à l’import |
httpx est remplacé par httpx2 | ModuleNotFoundError: No module named 'httpx' |
| Les paramètres de transport quittent le constructeur | TypeError: MCPServer.__init__() got an unexpected keyword argument 'port' |
Le client démarre en mode auto | le serveur reçoit une requête server/discover inattendue |
Le serveur, avant et après
La bonne nouvelle concerne l’essentiel de ce que vous avez écrit dans ce cours : les décorateurs @mcp.tool(), @mcp.resource() et @mcp.prompt() gardent les mêmes arguments et les mêmes signatures, et le traitement des valeurs renvoyées par un outil ne change pas. Le premier changement est donc un renommage :
# Avant (SDK 1.x)
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Documents")
# Après (SDK 2.x)
from mcp.server.mcpserver import MCPServer, Context
mcp = MCPServer("Documents")
Context sert à annoter le paramètre ctx injecté dans vos outils, ressources et prompts. Tous les sous-modules de mcp.server.fastmcp se retrouvent sous mcp.server.mcpserver, avec la même structure, y compris mcp.server.mcpserver.prompts.base et mcp.server.mcpserver.exceptions (ToolError, ResourceError, à lever pour que vos messages d’erreur atteignent le client, comme vu aux leçons 5 et 8). Les réglages de transport, host, port, chemins HTTP, json_response, stateless_http, ne se passent plus au constructeur mais à run() ou aux méthodes qui construisent l’application web. Nouveauté de la v2 à connaître : un paramètre d’outil annoté Resolve(fn) est rempli par votre fonction, invisible pour le modèle, et cette fonction peut renvoyer Elicit(...) pour poser une question à l’utilisateur, quel que soit l’âge du client en face.
Le client, avant et après
Côté client, les objets du protocole adoptent les noms Python habituels. Le format échangé sur le réseau, lui, ne change pas : il reste en camelCase.
# Avant (SDK 1.x)
result = await session.call_tool("my_tool", {"x": 1})
if result.isError:
...
tools = await session.list_tools()
schema = tools.tools[0].inputSchema
# Après (SDK 2.x)
result = await session.call_tool("my_tool", {"x": 1})
if result.is_error:
...
tools = await session.list_tools()
schema = tools.tools[0].input_schema
Attention à un piège silencieux : si vous sérialisez vous-même ces objets, model_dump() produit désormais des clés en snake_case que les autres implémentations MCP ne reconnaîtront pas. Passez by_alias=True, mode="json" pour obtenir le format du réseau.
L’ordre de migration conseillé
Le guide officiel propose sept étapes : mettre à jour les dépendances (mcp>=2,<3) et l’usage de la ligne de commande ; appliquer les renommages et déplacements d’imports ; porter le serveur ; porter le client ; mettre à jour les transports et l’authentification ; lancer les tests et traiter ce qui échoue désormais ; enfin, traiter les avertissements de dépréciation. Faites-le sur une branche, avec vos tests, et vérifiez le comportement avec l’inspecteur MCP avant de déployer ; son réglage Protocol Era (legacy, auto, modern) permet de tester votre serveur face à un client ancien comme face à un client 2026-07-28.
À vous de jouer
- Téléchargez le projet de démarrage du cours officiel (
cli_project.zip, écrit pour le SDK v1), installez-le tel quel, puis forcezmcp>=2,<3: notez le premier message d’erreur et retrouvez-le dans le tableau ci-dessus. - Portez le serveur en suivant l’ordre du guide : renommage, exceptions, transport dans
run(). Vérifiez chaque primitive dans l’inspecteur. - Portez le client (
is_error,input_schema, URI en chaîne) et relancez vos tests. - Dans l’inspecteur, passez le serveur en Protocol Era
modernet reconnectez-vous : le badge doit afficher 2026-07-28.
Sources officielles : Versioning de la spécification · Changelog 2026-07-28 · What’s new in v2 · Guide de migration
Points clés à retenir
- Spécification 2026-07-28 : protocole sans état, plus de
initializeni de session,server/discover, requêtes en plusieurs allers-retours ; Roots, Sampling, Logging et HTTP+SSE dépréciés - SDK Python v2 :
FastMCPdevientMCPServer, les champs passent en snake_case, les paramètres de transport vont dansrun() - Les décorateurs
@mcp.tool(),@mcp.resource()et@mcp.prompt()ne changent pas - Ce cours est écrit pour la v2 (
uv add "mcp[cli]>=2,<3") ; pour un projet 1.x existant, migrez en suivant l’ordre du guide officiel