Aller au contenu
Cercle IA Tech · MCP Un site du réseau Cercle IA Tech

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 --version et npm --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 un inputSchema écrit avec zod. Le SDK en tire le schéma JSON que le client verra dans tools/list.
  • Le résultat est un objet avec un tableau content, ici un bloc de type text.
  • createServer est une fabrique : la documentation explique que serveStdio l'appelle chaque fois qu'il a besoin d'une instance, y compris pour une sonde server/discover abandonnée si le client revient à l'ancienne poignée de main initialize. Chaque appel doit donc renvoyer un nouveau McpServer.

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 :

  1. https://modelcontextprotocol.io/docs/2026-07-28/develop/build-server.md
  2. https://modelcontextprotocol.io/docs/2026-07-28/sdk.md

À lire aussi