Guide
Créer un serveur MCP en TypeScript : McpServer et zod
Paquet @modelcontextprotocol/server, registerTool avec un schéma zod, serveStdio et compatibilité des versions : un serveur MCP TypeScript pas à pas.
Mis à jour le
Pour créer un serveur MCP (Model Context Protocol) en TypeScript, le tutoriel officiel installe le paquet @modelcontextprotocol/server et la bibliothèque de validation zod, déclare chaque outil avec server.registerTool() dans une fonction qui fabrique le serveur, puis lance le tout avec serveStdio(). Ce dernier point est récent et compte : c'est lui qui permet de répondre aux clients de la version 2026-07-28 comme aux plus anciens. Relevé sur la documentation le 15/11/2026.
Prérequis
- Node.js en version 20 ou plus (vérifiez avec
node --versionetnpm --version). - Des bases en TypeScript.
Le SDK (kit de développement) TypeScript fait partie des SDK classés au premier niveau de maturité par le projet. Son dépôt est modelcontextprotocol/typescript-sdk sur GitHub.
Préparer le projet
mkdir weather
cd weather
npm init -y
npm install @modelcontextprotocol/server zod
npm install -D @types/node typescript
mkdir src
touch src/index.ts
Dans package.json, le tutoriel ajoute "type": "module", un script "build": "tsc && chmod 755 build/index.js" et une entrée bin qui pointe vers ./build/index.js. Le tsconfig.json proposé compile src/ vers build/ avec "module": "Node16" et "target": "ES2022".
Le serveur minimal
En reprenant la structure du tutoriel, avec un seul outil :
import { McpServer } from "@modelcontextprotocol/server";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import { z } from "zod";
function createServer() {
const server = new McpServer({ name: "demo", version: "1.0.0" });
server.registerTool(
"saluer",
{
description: "Renvoie une salutation",
inputSchema: z.object({
nom: z.string().describe("Prénom de la personne"),
}),
},
async ({ nom }) => ({
content: [{ type: "text", text: `Bonjour ${nom}` }],
}),
);
return server;
}
serveStdio(createServer, {
onerror: (error) => console.error("Erreur du serveur MCP :", error),
});
console.error("Serveur MCP lancé sur stdio");
Les éléments à comprendre :
registerTool(nom, définition, fonction): la définition porte une description et uninputSchemaécrit aveczod. Le SDK en tire le schéma JSON que le client verra danstools/list.- Le résultat est un objet avec un tableau
content, ici un bloc de typetext. createServerest une fabrique : la documentation explique queserveStdiol'appelle chaque fois qu'il a besoin d'une instance, y compris pour une sondeserver/discoverabandonnée si le client revient à l'ancienne poignée de maininitialize. Chaque appel doit donc renvoyer un nouveauMcpServer.
serveStdio plutôt que StdioServerTransport
C'est le changement à connaître si vous partez d'un ancien exemple. D'après la documentation, serveStdio négocie la révision du protocole avec chaque client : le même serveur répond aux clients 2026-07-28 et à ceux qui ouvrent encore par la poignée de main initialize de l'ère 2025. Un serveur branché à la main avec server.connect(new StdioServerTransport()) compile toujours, mais il ne sert que les clients de l'ère 2025.
Ne rien écrire sur la sortie standard
En stdio, la sortie standard transporte les messages JSON-RPC (le format d'échange du protocole). console.log() y écrit par défaut et casse le serveur. Utilisez console.error(), qui écrit sur stderr, ou une bibliothèque de journalisation qui écrit sur stderr ou dans un fichier. Pour un serveur HTTP (exposé sur le réseau), cette contrainte ne s'applique pas.
Compiler et vérifier
Lancez npm run build : la documentation insiste, sans cette étape le serveur ne se connectera pas. Pour vérifier qu'il répond aux clients de la version 2026-07-28, elle propose MCP Inspector en ligne de commande :
npx @modelcontextprotocol/inspector --cli node build/index.js --protocol-era modern --method tools/list
Inspector utilise par défaut l'ère legacy : relancez la même commande avec --protocol-era legacy pour couvrir les deux. Plus de détails sur la page tester un serveur avec MCP Inspector.
Brancher le serveur à Claude Desktop
Dans claude_desktop_config.json, sous mcpServers :
{
"mcpServers": {
"weather": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/index.js"]
}
}
}
Le chemin doit être absolu. Enregistrez puis redémarrez Claude Desktop. Le dépannage est détaillé sur la page installer un serveur MCP dans Claude Desktop.
Et ensuite
Pour exposer le serveur sur le réseau plutôt qu'en local, passez au transport Streamable HTTP et à l'autorisation OAuth (le standard de délégation d'accès du web) : voir stdio ou Streamable HTTP et MCP distant et OAuth. Le même exercice en Python est sur la page créer un serveur MCP en Python.
Questions fréquentes
Quelle version de Node.js faut-il pour un serveur MCP en TypeScript ?
Le tutoriel officiel demande Node.js 20 ou plus.
Faut-il encore utiliser StdioServerTransport ?
La documentation indique qu'un serveur branché avec server.connect(new StdioServerTransport()) compile toujours mais ne sert que les clients de l'ère 2025. serveStdio sert à la fois ces clients et ceux de la version 2026-07-28.
Sources
Pages consultées pour écrire cet article :