← Retour au blog MCP

Construire un Serveur MCP Custom : Guide Pratique

2 juil. 20268 min

MCP (Model Context Protocol) est le protocole d’Anthropic qui permet à Claude de disposer d’outils personnalisés : appels API, requêtes base de données, manipulation de fichiers. Voici comment construire votre propre serveur MCP.

Ce que Fait un Serveur MCP

Un serveur MCP expose des tools (fonctions appelables par Claude) et optionnellement des resources (données lisibles) et prompts (templates pré-définis).

Claude décide lui-même quand appeler un outil, avec quels paramètres, et comment utiliser le résultat — comme avec l’API tool use, mais via un protocole standardisé.

Setup Minimal

npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript tsx @types/node

Serveur MCP Basique

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "mon-serveur-mcp",
  version: "1.0.0",
});

// Définir un outil
server.tool(
  "recherche_client",
  "Recherche un client dans la base de données par nom ou email",
  {
    query: z.string().describe("Nom ou email du client"),
    limit: z.number().optional().default(5).describe("Nombre max de résultats"),
  },
  async ({ query, limit }) => {
    // Votre logique ici — base de données, API interne, etc.
    const results = await searchDatabase(query, limit);
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(results, null, 2),
        },
      ],
    };
  }
);

// Démarrer le serveur
const transport = new StdioServerTransport();
await server.connect(transport);

Ajouter une Resource

Les resources sont des données que Claude peut lire à la demande — pas des fonctions appelables.

server.resource(
  "config",
  "config://app/settings",
  async (uri) => ({
    contents: [
      {
        uri: uri.href,
        mimeType: "application/json",
        text: JSON.stringify({ env: "production", version: "2.1.0" }),
      },
    ],
  })
);

Gestion des Erreurs

Un outil MCP doit toujours retourner quelque chose de lisible — pas lever une exception nue.

server.tool("appel_api_externe", "...", { url: z.string() }, async ({ url }) => {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      return {
        content: [{ type: "text", text: `Erreur HTTP ${response.status}: ${response.statusText}` }],
        isError: true,
      };
    }
    const data = await response.json();
    return { content: [{ type: "text", text: JSON.stringify(data) }] };
  } catch (err) {
    return {
      content: [{ type: "text", text: `Erreur réseau: ${err instanceof Error ? err.message : String(err)}` }],
      isError: true,
    };
  }
});

Configuration dans Claude Code

Ajoutez votre serveur dans ~/.claude/settings.json (ou le settings.json du projet) :

{
  "mcpServers": {
    "mon-serveur": {
      "command": "npx",
      "args": ["tsx", "/chemin/vers/serveur.ts"],
      "env": {
        "DATABASE_URL": "postgresql://..."
      }
    }
  }
}

Cas d’Usage Réels

Serveur MCP interne que j’utilise : accès à une base PostgreSQL + appels à des APIs internes métier. Claude peut interroger directement les données en langage naturel sans que je code un endpoint à chaque fois.

Pattern recommandé : gardez votre serveur MCP simple et spécifique. Un serveur par domaine métier (CRM, facturation, support) plutôt qu’un seul serveur omniscient — plus facile à maintenir et à sécuriser.

SC

Stéphanie Caumont

Product Owner IA · En savoir plus