MCP pour les devs : relier tes LLM au monde réel
MCP (Model Context Protocol) évite d'écrire un connecteur par client LLM et par source de données. Son architecture, puis un premier serveur MCP en TypeScript.
Dans l'article précédentIA pour les développeurs · partie 224 minAgents IA : boucle agentique et pattern ReActConstruis un agent IA autonome en TypeScript avec Mistral : boucle agentique, pattern ReAct, planification, mémoire et garde-fous. Code complet inclus.Lire l'articleNouvel ongletUn bandeau t'y proposera de reprendre ici., on a construit un agent capable de raisonner et d'agir via des tools. Il cherchait sur le web, lisait des pages, et synthétisait les résultats. Mais tous ses tools étaient codés en dur dans le projet : web_search, read_url, chacun avec son schéma Zod, son implémentation, son entrée dans le registre.
Le jour où tu veux que ce même agent accède aussi à tes fichiers, à ton calendrier ou à ta base de données, tu recodes chaque intégration à la main. Et tu recommences dans le projet suivant. C'est exactement ce qui m'a poussé à regarder MCP de près.
Cet article explique ce qu'est MCP à un dev qui connaît le function calling, puis on écrit un premier serveur en TypeScript, on le teste dans Claude Desktop et on y branche l'agent de la partie 2.
Sans protocole commun, il faut N×M connecteurs
Avec 5 clients LLM (Claude, Cursor, ton app, ChatGPT, Gemini) et 10 sources de données (filesystem, PostgreSQL, GitHub, Slack...), ça fait 50 connecteurs à écrire et maintenir.
Sans standard :
Claude ──custom──▶ GitHub
Claude ──custom──▶ Slack
Cursor ──custom──▶ GitHub (recodé depuis zéro)
Cursor ──custom──▶ Slack (recodé depuis zéro)
...MCP règle ça : chaque source de données est exposée par un serveur MCP, et chaque client parle le même protocole. Tu codes l'intégration une fois, elle sert partout.
Avec MCP :
Claude ─┐
Cursor ─┤─── MCP ───▶ Serveur GitHub
Ton app ─┘ Serveur Slack
Serveur PostgreSQLN + M au lieu de N × M. Anthropic a publié MCP fin 2024, et en un an, OpenAI, Google et Microsoft l'ont adopté.
Un client découvre les tools qu'un serveur expose
Le Model Context Protocol définit comment un client LLM communique avec un serveur qui expose des outils.
flowchart TD
C["Client MCP<br/>(Claude, Cursor, ton agent)"] -- MCP --> S["Serveur MCP<br/>(expose des tools)"]
S --> B["Backend<br/>(fichiers, API, base de données)"]Le client se connecte au serveur, lui demande la liste de ses tools avec leurs descriptions et leurs schémas, et peut les appeler aussitôt. Rien n'est déclaré à la main côté client : c'est ce qu'on appelle la discovery.
MCP sort les tools de ton application
Dans la partie 1IA pour les développeurs · partie 116 minLLM pour les devs : du token au function callingComment fonctionne un LLM : tokens, température, types de messages et function calling. On construit ensuite un jeu de dés en TypeScript avec Mistral Small.Lire l'articleNouvel ongletUn bandeau t'y proposera de reprendre ici, section 2., tu définissais des tools dans ton code, le LLM les appelait, et ton code les exécutait. MCP déplace tout ça dans un serveur séparé.
| Function calling | MCP | |
|---|---|---|
| Qui définit les tools | Toi, dans ton code | Le serveur MCP |
| Qui les exécute | Ton code | Le serveur MCP |
| Discovery | Manuelle (tu listes les tools) | Automatique |
| Réutilisabilité | Copier-coller entre projets | Un serveur sert tous les clients |
| Transport | Intégré à ton app | Protocole séparé (stdio ou HTTP) |
Sous le capot, MCP repose sur le function calling : quand Claude est connecté à un serveur MCP, les tools du serveur apparaissent comme des functions dans son contexte. Ils viennent d'un processus externe au lieu d'être déclarés dans le code de l'application, donc n'importe quel client MCP peut les réutiliser.
Un serveur expose des tools, des resources et des prompts
Les tools, d'abord : des fonctions que le LLM appelle, read_file, search_database, send_email. C'est la primitive principale, et beaucoup de serveurs n'exposent que ça.
Les resources ensuite : des données en lecture seule que le client charge dans le contexte, comme un schéma de base de données ou un fichier de config. C'est le client qui les récupère, souvent à l'initiative de l'utilisateur, alors qu'un tool est appelé par le LLM.
Et les prompts : des templates fournis par le serveur pour guider le LLM. Un serveur SQL pourrait proposer un prompt "Analyse cette table" qui structure la requête.
Pour la suite, on se concentre sur les tools.
Ton premier serveur MCP
On écrit un serveur qui expose un seul tool, get_weather. Il te faut Node.js 20 ou plus récent.
mkdir weather-server && cd weather-server
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/server zod
npm install -D tsximport { McpServer } from "@modelcontextprotocol/server";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import { z } from "zod";
const server = new McpServer({
name: "weather-server",
version: "1.0.0",
});
server.registerTool(
"get_weather",
{
description: "Retourne la météo actuelle pour une ville donnée",
inputSchema: z.object({
city: z.string().describe("Nom de la ville"),
}),
},
async ({ city }) => {
// En vrai, tu appellerais une API météo ici
const weather = {
city,
temperature: Math.round(Math.random() * 30),
condition: ["Ensoleillé", "Nuageux", "Pluvieux"][Math.floor(Math.random() * 3)],
};
return {
content: [{ type: "text", text: JSON.stringify(weather, null, 2) }],
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);Le SDK gère le protocole, la sérialisation des messages (du JSON-RPC) et la discovery. Toi, tu définis le nom, la description, le schéma Zod et l'implémentation. C'est le même principe que le roll_dice de la partie 1, sauf que le tool vit dans son propre processus. La première fois, ça fait bizarre de voir Claude appeler du code qui tourne dans un terminal à côté.
La dernière ligne branche le serveur sur le transport stdio : le client lance le serveur comme un sous-processus et lui parle par l'entrée et la sortie standard.
Attention
En stdio, la sortie standard est réservée au protocole. Un console.log dans ton serveur corrompt les échanges : pour débugger, écris sur console.error.
Note
Ce code utilise la v2 du SDK TypeScript, stable depuis juillet 2026 et découpée en deux paquets, @modelcontextprotocol/server et @modelcontextprotocol/client. Beaucoup de tutoriels, dont la première version de celui-ci, utilisent encore la v1 (@modelcontextprotocol/sdk), où le même tool se déclarait avec server.tool(nom, description, schéma, handler). La v1 est toujours publiée, et le guide de migration détaille le passage de l'une à l'autre.
Tester avec Claude Desktop
Dans Claude Desktop, ouvre les réglages, onglet Developer, puis "Edit Config". Ça ouvre le fichier claude_desktop_config.json, qui se trouve dans ~/Library/Application Support/Claude/ sur macOS et dans %APPDATA%\Claude\ sur Windows. Ajoutes-y ton serveur, avec un chemin absolu :
{
"mcpServers": {
"weather": {
"command": "npx",
"args": ["tsx", "/chemin/absolu/vers/weather-server/src/server.ts"]
}
}
}Quitte complètement Claude Desktop, relance-le, puis demande "Quel temps fait-il à Lyon ?" :
Toi : "Quel temps fait-il à Lyon ?"
Claude : [appelle get_weather({ city: "Lyon" })]
→ { city: "Lyon", temperature: 22, condition: "Ensoleillé" }
Claude : "Il fait 22°C à Lyon et c'est ensoleillé."Le même serveur fonctionne tel quel avec Cursor, Claude Code ou n'importe quel client MCP.
Brancher l'agent de la partie 2 sur ce serveur
Claude Desktop est un client MCP parmi d'autres. L'agent qu'on a écrit dans la partie 2IA pour les développeurs · partie 224 minAgents IA : boucle agentique et pattern ReActConstruis un agent IA autonome en TypeScript avec Mistral : boucle agentique, pattern ReAct, planification, mémoire et garde-fous. Code complet inclus.Lire l'articleNouvel ongletUn bandeau t'y proposera de reprendre ici, section 3. peut en devenir un aussi. Sa boucle runAgent attend deux choses : une liste de tools et une fonction executeTool. Un client MCP fournit les deux, avec listTools() et callTool().
Dans le projet de l'agent, installe le paquet client :
npm install @modelcontextprotocol/clientimport { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
import { runAgent } from "./agent";
// 1. Lancer le serveur comme sous-processus et s'y connecter
const mcp = new Client({ name: "mon-agent", version: "1.0.0" });
await mcp.connect(
new StdioClientTransport({
command: "npx",
args: ["tsx", "/chemin/absolu/vers/weather-server/src/server.ts"],
})
);
// 2. Découvrir les tools et les traduire au format de l'API Mistral
const { tools: mcpTools } = await mcp.listTools();
const tools = mcpTools.map((tool) => ({
type: "function" as const,
function: {
name: tool.name,
description: tool.description ?? "",
parameters: tool.inputSchema,
},
}));
// 3. Même boucle qu'avant : seule l'exécution change de main
const answer = await runAgent("Quel temps fait-il à Lyon ?", {
model: "mistral-small-latest",
systemPrompt: "Tu réponds en français, en t'appuyant sur les outils disponibles.",
tools,
executeTool: (name, args) => mcp.callTool({ name, arguments: args }),
});
console.log(answer);
await mcp.close();npx tsx src/mcp-agent.tsDans les logs de l'agent, tu dois voir passer une action get_weather, puis la réponse rédigée par le modèle.
La traduction de l'étape 2 est courte parce qu'un tool MCP et un tool de function calling décrivent la même chose : un nom, une description et un JSON Schema. Et l'agent ne contient plus une ligne de code météo. Remplace la commande par celle d'un autre serveur MCP, et il gagne d'autres tools sans que tu touches à la boucle. Les garde-fous de la partie 2 (budget, limite d'itérations, détection de boucle) continuent de s'appliquer, puisqu'ils vivent dans runAgent.
Où en est MCP fin 2026
Côté clients, la documentation officielle cite Claude et ChatGPT pour les assistants, Visual Studio Code et Cursor pour les outils de développement, et la liste est bien plus longue. Chez Anthropic, Claude Desktop, Claude.ai et Claude Code sont tous des clients MCP.
Côté serveurs, il en existe pour à peu près tout ce qu'un dev utilise : filesystem, bases de données, GitHub, Slack, Google Drive, Linear, Notion, Sentry... Le registry officiel MCP les recense.
Côté gouvernance, Anthropic a confié MCP en décembre 2025 à l'Agentic AI Foundation, une fondation hébergée par la Linux Foundation et lancée avec Block et OpenAI. Ce n'est plus le protocole d'un seul acteur, et c'est ce qui m'a rassuré pour construire dessus.
Côté spec, la révision en vigueur date du 28 juillet 2026, et elle change le protocole en profondeur. Elle le rend sans état : le handshake initialize et les sessions disparaissent, chaque requête porte sa version de protocole et les capacités du client. Elle déprécie aussi trois fonctionnalités (Roots, Sampling, Logging) et, pour l'authentification, l'enregistrement dynamique des clients OAuth. Pour le serveur de cet article, ça ne change rien : le SDK s'occupe de la négociation, et le code d'un tool reste le même. Les effets se voient surtout sur les serveurs distants.
Stdio pour le local, HTTP pour le distant
Le serveur qu'on vient d'écrire utilise stdio : le client le lance comme un sous-processus et communique via stdin/stdout. Simple, parfait pour le dev local.
Sauf que stdio implique que le serveur tourne sur ta machine. Pour y accéder depuis le web, depuis ton téléphone, ou le partager avec une équipe, il faut le transport Streamable HTTP : un serveur déployé derrière une URL HTTPS, avec une authentification OAuth.
stdio → local, un seul client, dev/perso
HTTP → distant, multi-clients, partageableC'est le sujet de MCP remote : quand stdio ne suffit plusMCP en pratique · partie 112 minMCP remote : quand stdio ne suffit plusStdio suffit sur ta machine, pas au-delà. Streamable HTTP sans session depuis la spec de juillet 2026, un serveur MCP remote en TypeScript, puis OAuth 2.1.Lire l'articleNouvel ongletUn bandeau t'y proposera de reprendre ici, section 4., le premier article de la série MCP en pratique.
La suite
Si tu as suivi la série depuis le début, tu as maintenant toute la chaîne : les LLM génèrent du texte, le function calling leur permet d'agir, les agents enchaînent les actions seuls, et MCP standardise leurs outils pour que tu n'aies plus à les réécrire.
Un serveur MCP en stdio, c'est une soirée de boulot. Le passage en remote, avec Streamable HTTP et OAuth, m'a demandé beaucoup plus : c'est là que j'ai passé le plus de temps sur Vaulken, et c'est tout l'objet de la série MCP en pratique. La suite de cette série-ci abordera l'évaluation des réponses LLM et la gestion des coûts.
Pour aller plus loin
IA pour les développeurs · partie 3 sur 3
Tu viens de finir la série.
À lire ensuite
MCP remote : quand stdio ne suffit plus
Stdio suffit sur ta machine, pas au-delà. Streamable HTTP sans session depuis la spec de juillet 2026, un serveur MCP remote en TypeScript, puis OAuth 2.1.
Cité dans cet article, à propos de MCP remote : quand stdio ne suffit plus
Vaulken : serveur MCP remote pour mes fichiers
Vaulken ouvre tes fichiers S3 à Claude via un serveur MCP remote. Ce qu'il fait, pour qui, et comment il est construit : OAuth, ton bucket, Qdrant, 12 tools.
Inkfate : quand l'IA devient maître de jeu
Inkfate est un jeu de rôle solo où une IA tient le rôle du maître de jeu. Les règles du Year Zero Engine, et le pipeline LangGraph et Mistral derrière le MJ.