Accueil / Articles / MCP sans état : Échelle des serveurs sans sessions ni échanges de données

MCP sans état : Échelle des serveurs sans sessions ni échanges de données

Comment un protocole de contexte de modèle sans état termine les sessions et les échanges, et comment les requêtes métier à plusieurs tours, les en-têtes de routage, le cache et les tâches permettent de le maintenir utilisable.

1919 mots

Remarque sur le calendrier : la conception sans état décrite ici fait partie de la révision 2026 du protocole. Des détails tels que les noms exacts des méthodes, des en-têtes et des types de résultats peuvent encore changer, il est donc conseillé de les vérifier contre la spécification actuelle de MCP avant de s’y fier dans du code. Si vous avez besoin d’un rappel des bases sur la manière dont les clients MCP découvrent et invoquent des outils, l’introduction du blog sur la façon dont le Model Context Protocol permet aux agents de découvrir et d’appeler des outils aborde ce sujet.

Que signifie « état » ici

Les versions antérieures de MCP fonctionnaient de la même manière au niveau de la connexion. Lorsqu’un client (l’application IA) se connectait pour la première fois à un serveur, les deux parties effectuaient une séquence d’initialisation. Le serveur émettait ensuite un identifiant de session, par exemple abc123, que le client ajoutait à chaque requête ultérieure afin que le serveur puisse relier chaque appel à ce qui s’était passé précédemment dans la conversation, y compris les capacités négociées entre les deux parties.

Pourquoi les sessions échouent lors du scaling horizontal

Avec une seule instance de serveur et un trafic modéré, cette conception est tout à fait suffisante. Les problèmes commencent lorsque la charge augmente et que l’on ajoute des instances derrière un équilibreur de charge :

  1. Le client d’un utilisateur envoie sa première requête, par exemple pour obtenir la liste des outils. L’équilibreur de charge l’envoie au Serveur 1, qui crée la session abc123.
  2. Le même client envoie une deuxième requête, par exemple pour utiliser l’outil météo. Cette fois, l’équilibreur de charge choisit le Serveur 2.
  3. Le Serveur 2 n’a jamais entendu parler de abc123. Il ne conserve aucune donnée en mémoire du Serveur 1, donc la requête échoue.

Les systèmes à état disposent de deux solutions standard. Les sessions persistantes lient chaque client à une instance spécifique, ce qui entrave la distribution équitable de la charge et complique les mécanismes de basculement en cas de panne. Une alternative consiste à utiliser un stockage partagé comme Redis pour conserver les données des sessions, accessibles par toutes les instances. Cette méthode fonctionne, mais elle ajoute une infrastructure supplémentaire à gérer, à sécuriser et à maintenir disponible, ainsi qu’une recherche réseau à chaque appel, tout cela uniquement pour assurer la traçabilité des protocoles.

Le modèle sans état

La révision de 2026 emprunte une voie différente : elle transforme MCP en un protocole de demande-réponse sans état et élimine les sessions. Chaque requête est indépendante et ne dépend pas de ce que le serveur se souvient d’une requête précédente. Comme il n’y a pas de mémoire par client sur le serveur, n’importe quelle instance peut répondre à n’importe quelle requête, et l’extension de la capacité se fait simplement en ajoutant des instances derrière un équilibreur de charge ordinaire.

Cela ne signifie pas pour autant que votre application ne peut avoir aucun état du tout. Un outil qui gère un panier d’achat ou une édition de long document a toujours besoin de données quelque part. La différence réside dans le fait que cet état devient des données d’application explicites, stockées là où vous le choisissez et référencées par des identifiants dans la requête, plutôt qu’un état de protocole implicite lié à une connexion.

Comment une requête transporte son propre contexte

Même en l’absence de handshake ou d’ID de session, le serveur doit savoir quelle version du protocole utilise le client, qui est ce client et quelles sont ses capacités. La réponse est que chaque requête apporte ces informations avec elle.

L’objet _meta

Les en-têtes des requêtes incluent un objet _meta optionnel pour ces métadonnées. Il peut contenir :

  • La version du protocole, afin que le serveur sache comment interpréter le message.
  • L’identité du client, telle que le nom et la version d’une application, par exemple MyAIApp v1.0.
  • Les capacités du client, afin que le serveur sache quelles fonctionnalités il peut utiliser dans sa réponse.
  • Puisque le contexte est inclus dans la requête, le serveur peut le traiter immédiatement, sans avoir besoin de consulter une table de session. L’inconvénient est un en-tête légèrement plus volumineux à chaque appel, ce qui est généralement négligeable par rapport aux coûts liés à un stockage de sessions partagé.

    Interactions en plusieurs étapes sans connexion ouverte

    Les architectures à état facilitent les échanges : si le serveur a besoin d’informations supplémentaires, il peut les demander via la connexion déjà ouverte. Prenons un utilisateur qui souhaite réserver un vol pour Delhi mais oublie de mentionner la date. Un serveur à état pourrait simplement demander la date et attendre la réponse sur la même connexion.

    Un protocole sans état ne peut pas maintenir des connexions ouvertes à cette fin, c’est pourquoi MCP définit plutôt un flux structuré en plusieurs étapes :

    1. Lorsqu’un serveur reçoit une demande manquant de paramètres essentiels, il renvoie un résultat spécifique input required au lieu de planter ou d’attendre.
    2. L’application client demande à l’utilisateur les informations manquantes.
    3. Le client place ces réponses dans un objet input responses et envoie une nouvelle demande complètement indépendante que le serveur peut traiter.

    Puisque la deuxième requête contient tout ce qui est nécessaire, elle peut être traitée par n’importe quelle instance de serveur. Le serveur n’a pas besoin de se souvenir qu’il a posé une question ; c’est le client qui poursuit le traitement. Si le serveur doit relier les deux requêtes (par exemple pour éviter de répéter des tâches coûteuses), il peut renvoyer un token opaque que le client pourra réenvoyer, au lieu de conserver une mémoire cachée.

    Affectation des requêtes via les en-têtes plutôt que le corps

    Cette approche sans état ouvre également la voie à des améliorations en termes de performance et d’opérations. Deux changements se distinguent : l’affectation des requêtes basée sur les en-têtes et la possibilité de mettre en cache les résultats.

    Détails du protocole dans les en-têtes HTTP

    Auparavant, les infrastructures situées en amont d’un serveur MCP, telles qu’une passerelle API, un pare-feu pour applications web ou un équilibreur de charge, devaient analyser le corps JSON de chaque requête uniquement pour déterminer quelle méthode ou outil était invoqué. L’analyse des corps de requête au niveau du périphérique consomme de la puissance CPU, augmente la latence et est difficile à configurer dans de nombreuses passerelles.

    Sous les nouvelles règles, les requêtes HTTP doivent exposer des informations clés du protocole dans les en-têtes :

    • MCP-Method, par exemple tools/call ;
    • MCP-Name, le nom de l’outil spécifique qui est appelé.

    Listes d’outils et de prompts pouvant être mémorisées

    Les listes d’outils et de prompts changent rarement, ce qui permet à la nouvelle version de rendre les résultats des listes stockables en cache. Un client peut récupérer la liste d’outils une seule fois, la conserver en mémoire et l’utiliser à nouveau pour des demandes ultérieures au lieu de la demander à nouveau. Cette même propriété permet aux infrastructures partagées, telles qu’un gateway ou un cache HTTP en amont des serveurs, de répondre aux demandes répétées de listes pour de nombreux clients en même temps. Dans tous les cas, beaucoup moins de demandes parviennent au serveur. Comme pour tout cache, il est nécessaire d’avoir un moyen de le rendre invalide lorsque des mises à jour modifient la liste ; il convient donc de prévoir une expiration ou un système de versionnement plutôt qu’un stockage permanent.

    Tâches en arrière-plan pour des opérations longues

    Certaines outils répondent en quelques millisecondes, comme pour une recherche météorologique. D’autres ne le font pas : demander à un assistant d’analyser 10 000 documents pourrait prendre vingt minutes. Dans un cycle classique demande-réponse, le client devrait maintenir la connexion ouverte pendant toute cette durée, ce qui consomme des ressources des deux côtés et laisse l’interface utilisateur bloquée en attente.

    Afin de résoudre ce problème, la révision de 2026 intègre un cadre Tasks redessiné :

    1. Création. Lorsqu’un client déclenche un outil gourmand en ressources, le serveur répond immédiatement avec un identifiant de tâche, par exemple task_abc123, et la demande initiale se termine.
    2. Exécution en arrière-plan. Le serveur effectue l’analyse en arrière-plan tandis que l’utilisateur continue à utiliser les autres fonctionnalités de l’application.
  • Vérifications de progression. À tout moment, le client peut demander l’état et les résultats de la tâche en effectuant une appel Task Get.
  • Données mises à jour. Si le travail nécessite plus d’informations en cours de route, le client les fournit via Task Update.
  • C’est le schéma de travail asynchrone familier des API web, appliqué à MCP. Il permet aux applications de rester réactives quel que soit le volume de travail. Dans un déploiement multi-instance, n’oubliez pas que l’état de la tâche doit être stocké à un endroit accessible par toutes les instances, car l’appel Task Get peut arriver sur un serveur différent de celui qui a créé la tâche. Le protocole n’a plus besoin d’un état de session partagé, mais la gestion d’un stockage durable des tâches reste votre responsabilité.

    Conséquences pour vos serveurs

    Si vous gérez ou développez des serveurs MCP, la liste de contrôle pratique est la suivante :

    • Éliminez la mémoire cachée par connexion. Tout ce dont un outil a besoin entre deux appels doit être stocké de manière explicite, identifié par des clés envoyées par le client.
    • Lisez le contexte de chaque demande. Prenez la version du protocole, l’identité et les capacités du client depuis _meta, et non depuis une session.
    • Concevez des outils qui demandent des informations plutôt que d’attendre. Retournez un résultat nécessitant une entrée lorsque des paramètres manquent, et attendez les réponses dans une nouvelle demande.
    • Utilisez les en-têtes de routage au niveau du bord. Configurez les passerelles pour router et limiter selon MCP-Method et MCP-Name, puis validez-les par rapport au corps de la demande sur le serveur.
  • Gestion des listes de cache et planification de leur invalidation. Permettez aux clients et aux passerelles de mettre en cache les listes d’outils et de prompts, avec un moyen clair de les mettre à jour après les déploiements.
  • Déplacement des outils lents vers des tâches. Retournez rapidement un ID de tâche et conservez l’état de la tâche dans un stock partagé par toutes les instances.
  • Points clés

    • La révision sans état remplace le design basé sur des sessions de MCP par des appels indépendants demande-réponse, éliminant ainsi le besoin de sessions persistantes ou d’un stock de sessions partagé simplement pour l’extension horizontale.
    • Les identifiants de handshake et de session ont disparu ; chaque demande contient sa propre version de protocole, l’identité du client ainsi que ses capacités dans le champ _meta.
    • L’information manquante est gérée via un résultat input required ainsi qu’une demande ultérieure contenant des input responses, au lieu d’une connexion ouverte.
    • MCP-Method et MCP-Name permettent aux passerelles de diriger, de limiter le débit et de bloquer le trafic sans avoir à parser les corps JSON.
    • Les listes stables d’outils, de prompts et de ressources peuvent être mémorisées en cache, réduisant ainsi la charge répétitive sur les serveurs.
    • Les outils à exécution prolongée retournent immédiatement un ID de tâche, que les clients suivent ensuite avec Task Get et Task Update.
    • L’absence d’état consiste à déplacer l’état plutôt qu’à l’éliminer : les données de l’application et l’avancement des tâches nécessitent toujours un emplacement persistant accessible par toutes les instances. Vérifiez les noms exacts selon la spécification actuelle avant de vous en servir.

    Lectures complémentaires