Guide
Comment fonctionne MCP : hôte, client, serveur
Hôte, client, serveur, couche de données JSON-RPC, transports, découverte : l'architecture du Model Context Protocol expliquée pas à pas.
Mis à jour le
MCP (Model Context Protocol) fonctionne en client-serveur : une application d'IA, l'hôte, ouvre une connexion vers un ou plusieurs serveurs MCP en créant un client par serveur. Les messages suivent le format JSON-RPC 2.0 (un format standard d'appel de procédure à distance, écrit en JSON). Le serveur annonce ce qu'il sait faire, le client le découvre, puis le modèle de langage appelle ce dont il a besoin.
Les trois participants
| Rôle | Ce que c'est | Exemple donné par la documentation |
|---|---|---|
| Hôte | L'application d'IA qui coordonne un ou plusieurs clients | Claude Desktop, Claude Code, Visual Studio Code |
| Client | Le composant qui maintient la connexion à un serveur et en tire du contexte pour l'hôte | Un objet client par serveur, créé par l'hôte |
| Serveur | Le programme qui fournit du contexte et des actions | Le serveur de fichiers local, le serveur Sentry distant |
Le point qui surprend souvent : un client par serveur. Quand Visual Studio Code se connecte au serveur Sentry puis au serveur de fichiers, il crée deux clients distincts, chacun avec sa connexion dédiée.
« Serveur » ne veut pas dire « machine distante ». Le serveur de fichiers lancé par Claude Desktop tourne sur votre ordinateur : on parle de serveur local. Le serveur officiel de Sentry tourne sur la plateforme Sentry : c'est un serveur distant.
Deux couches
La documentation sépare MCP en deux couches :
- La couche de données (intérieure) : le protocole JSON-RPC lui-même. Elle couvre la découverte des versions et des capacités, les primitives (outils, ressources, prompts), et les notifications.
- La couche de transport (extérieure) : comment les messages circulent. Deux transports standard existent : stdio (entrées et sorties standard d'un processus local) et Streamable HTTP (requêtes HTTP POST, avec un flux SSE, Server-Sent Events, facultatif pour la réponse). L'autorisation se règle à ce niveau. Détails dans stdio ou Streamable HTTP.
Le même format de message passe sur les deux transports : votre logique de serveur ne change pas quand vous passez du local au distant.
Ce que chacun expose
Côté serveur, trois primitives :
- Outils : des fonctions exécutables que le modèle appelle (opérations sur des fichiers, appels d'API, c'est-à-dire d'interfaces de programmation, requêtes en base).
- Ressources : des sources de données qui apportent du contexte (contenu de fichiers, enregistrements, réponses d'API).
- Prompts : des modèles réutilisables qui structurent l'échange avec le modèle.
Chaque primitive a ses méthodes de découverte (tools/list, resources/list, prompts/list), de lecture (resources/read, prompts/get) et, pour les outils, d'exécution (tools/call). Le détail est sur la page outils, ressources et prompts.
Côté client, la primitive active est l'élicitation : le serveur peut demander une information complémentaire ou une confirmation à l'utilisateur. Deux autres primitives client, l'échantillonnage (le serveur demande une génération au modèle de l'hôte) et la journalisation, sont dépréciées depuis la version 2026-07-28.
Le déroulé d'un échange
Prenons la séquence décrite dans la documentation, avec la version 2026-07-28 :
- Découverte (facultative) : le client envoie
server/discover. Le serveur, qui doit implémenter cette méthode, répond avec ses versions prises en charge, ses capacités (par exempletoolsetresources) et son identité. - Liste des outils :
tools/listrenvoie, pour chaque outil, un nom, un titre, une description et uninputSchema(un schéma JSON qui décrit les paramètres attendus). - Appel : quand le modèle décide d'utiliser un outil, l'hôte envoie
tools/callavec le nom exact et les arguments. Le résultat revient sous forme d'un tableaucontent(texte, image, ressource…). - Notifications : si le client les a demandées via
subscriptions/listen, le serveur le prévient quand sa liste d'outils change, et le client la recharge.
Chaque requête porte dans son champ _meta la version du protocole et les capacités du client : le serveur n'a pas besoin de se souvenir de l'échange précédent. Si la version demandée n'est pas prise en charge, le serveur répond par une erreur UnsupportedProtocolVersionError qui liste les versions acceptées.
Ce que MCP ne fait pas
La documentation le précise : MCP porte uniquement sur l'échange de contexte. Il ne dit pas comment l'application d'IA utilise le modèle de langage ni comment elle gère le contexte reçu. Choisir quels outils montrer au modèle, demander une confirmation avant une action, tenir un journal : tout cela reste à la charge de l'hôte. La spécification fixe toutefois des principes, comme le consentement explicite de l'utilisateur avant l'appel d'un outil (voir sécurité des serveurs MCP).
Pour aller plus loin
Une fois l'architecture comprise, le plus parlant est d'écrire un petit serveur : en Python ou en TypeScript, puis de le brancher à Claude Desktop.
Questions fréquentes
Quelle différence entre un hôte MCP et un client MCP ?
L'hôte est l'application d'IA (Claude Desktop, Claude Code, Visual Studio Code). Le client est le composant que l'hôte crée pour chaque serveur : un client par serveur, chacun avec sa connexion dédiée.
MCP garde-t-il une session ouverte entre deux requêtes ?
Plus depuis la version 2026-07-28 : le protocole est sans état et chaque requête porte sa version de protocole et les capacités du client dans son champ _meta.
Sources
Pages consultées pour écrire cet article :