Nicolas Dabene
Retour au blog
12 November 2025 Nicolas Dabene 6 min

Créer votre premier outil MCP : readFile

Créer votre Premier Outil MCP : L’Outil readFile Expliqué

IA développement Tutoriel Intelligence Artificielle automatisation
Créer votre premier outil MCP : readFile

Créer votre Premier Outil MCP : L’Outil readFile Expliqué

Créer votre Premier Outil MCP : L’Outil readFile Expliqué

Vous avez configuré votre environnement TypeScript dans l’article précédent ? Parfait ! Maintenant, place au moment magique où la théorie devient réalité. Nous allons créer ensemble votre tout premier outil MCP : une fonction qui permettra à une IA de lire des fichiers sur votre machine. C’est simple, concret, et surtout : ça fonctionne vraiment.

Introduction

Dans ma carrière de développeur, j’ai toujours adoré ces moments où le code prend vie. Vous savez, quand vous lancez votre application et qu’elle fait exactement ce que vous aviez imaginé ? C’est ce que nous allons vivre ensemble aujourd’hui. Après avoir posé les fondations dans les articles précédents, nous allons construire quelque chose de tangible : un outil MCP qui lit des fichiers.

Imaginez : vous demandez à Claude “Lis-moi le fichier rapport.txt”, et il peut réellement le faire grâce à votre serveur. Ce n’est plus de la théorie, c’est votre code qui rend cela possible. Et le plus beau ? Une fois que vous maîtriserez la création d’un outil, vous pourrez en créer des dizaines d’autres.

Rappel : Qu’est-ce qu’un Outil MCP ?

Avant de coder, rappelons brièvement ce qu’est un outil MCP. C’est essentiellement une fonction que vous exposez à l’IA avec trois informations essentielles :

Le nom de l’outil : Comment l’IA va l’appeler (par exemple “readFile”)

La description : Ce que fait l’outil, pour que l’IA comprenne quand l’utiliser

Les paramètres : Les informations dont l’outil a besoin pour fonctionner

C’est comme créer une fonction dans votre code, mais avec une carte d’identité que l’IA peut lire et comprendre. Simple, non ?

Anatomie d’un Outil MCP

Visualisons la structure complète d’un outil MCP. Voici le squelette que nous allons remplir :

<span class="c1">// 1. Interface pour les paramètres d'entrée</span>
<span class="kr">interface</span> <span class="nx">ToolParams</span> <span class="p">{</span>
  <span class="c1">// Les données que l'IA nous envoie</span>
<span class="p">}</span>

<span class="c1">// 2. Interface pour la réponse</span>
<span class="kr">interface</span> <span class="nx">ToolResponse</span> <span class="p">{</span>
  <span class="nl">success</span><span class="p">:</span> <span class="nx">boolean</span><span class="p">;</span>
  <span class="nl">content</span><span class="p">?:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">error</span><span class="p">?:</span> <span class="kr">string</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// 3. La fonction qui fait le travail</span>
<span class="k">async</span> <span class="kd">function</span> <span class="nx">monOutil</span><span class="p">(</span><span class="nx">params</span><span class="p">:</span> <span class="nx">ToolParams</span><span class="p">):</span> <span class="nb">Promise</span><span class="o"><</span><span class="nx">ToolResponse</span><span class="o">></span> <span class="p">{</span>
  <span class="c1">// Logique métier ici</span>
<span class="p">}</span>

<span class="c1">// 4. La définition de l'outil (le "menu")</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">monOutilDefinition</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">monOutil</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Ce que fait mon outil</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">parameters</span><span class="p">:</span> <span class="p">{</span>
    <span class="c1">// Description des paramètres attendus</span>
  <span class="p">}</span>
<span class="p">};</span>

Cette structure en quatre parties est votre modèle pour créer n’importe quel outil MCP. Gardons-la en tête pour la suite.

Créer la Structure de Dossiers

Commençons par organiser notre code proprement. Dans votre projet mcp-server, créez la structure suivante :

<span class="nb">mkdir</span> <span class="nt">-p</span> src/tools
<span class="nb">mkdir</span> <span class="nt">-p</span> src/types

Cette organisation va nous aider à garder un code maintenable. Le dossier tools contiendra nos outils MCP, et types nos définitions TypeScript réutilisables.

Définir les Types TypeScript

Créons d’abord nos interfaces TypeScript. Créez le fichier src/types/mcp.ts :

<span class="c1">// src/types/mcp.ts</span>

<span class="c1">// Type générique pour les paramètres d'un outil</span>
<span class="k">export</span> <span class="kr">interface</span> <span class="nx">ToolParams</span> <span class="p">{</span>
  <span class="p">[</span><span class="nx">key</span><span class="p">:</span> <span class="kr">string</span><span class="p">]:</span> <span class="kr">any</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// Type pour la réponse standard d'un outil</span>
<span class="k">export</span> <span class="kr">interface</span> <span class="nx">ToolResponse</span> <span class="p">{</span>
  <span class="nl">success</span><span class="p">:</span> <span class="nx">boolean</span><span class="p">;</span>
  <span class="nl">content</span><span class="p">?:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">error</span><span class="p">?:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">metadata</span><span class="p">?:</span> <span class="p">{</span>
    <span class="p">[</span><span class="na">key</span><span class="p">:</span> <span class="kr">string</span><span class="p">]:</span> <span class="kr">any</span><span class="p">;</span>
  <span class="p">};</span>
<span class="p">}</span>

<span class="c1">// Type pour la définition d'un outil (le "menu")</span>
<span class="k">export</span> <span class="kr">interface</span> <span class="nx">ToolDefinition</span> <span class="p">{</span>
  <span class="nl">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">description</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">parameters</span><span class="p">:</span> <span class="p">{</span>
    <span class="p">[</span><span class="na">paramName</span><span class="p">:</span> <span class="kr">string</span><span class="p">]:</span> <span class="p">{</span>
      <span class="na">type</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
      <span class="nl">description</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
      <span class="nl">required</span><span class="p">:</span> <span class="nx">boolean</span><span class="p">;</span>
    <span class="p">};</span>
  <span class="p">};</span>
<span class="p">}</span>

<span class="c1">// Type spécifique pour les paramètres de readFile</span>
<span class="k">export</span> <span class="kr">interface</span> <span class="nx">ReadFileParams</span> <span class="kd">extends</span> <span class="nx">ToolParams</span> <span class="p">{</span>
  <span class="nl">chemin_du_fichier</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
<span class="p">}</span>

Ces types vont nous aider à avoir de l’auto-complétion et à éviter des erreurs stupides. TypeScript devient notre meilleur ami pour ce genre de projet.

Créer l’Outil readFile

Maintenant, le moment que vous attendiez : créons notre outil ! Créez le fichier src/tools/readFile.ts :

<span class="c1">// src/tools/readFile.ts</span>
<span class="k">import</span> <span class="nx">fs</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">fs/promises</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="nx">path</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">path</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">ReadFileParams</span><span class="p">,</span> <span class="nx">ToolResponse</span><span class="p">,</span> <span class="nx">ToolDefinition</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">../types/mcp</span><span class="dl">'</span><span class="p">;</span>

<span class="cm">/**
 * Lit le contenu d'un fichier texte
 * @param params - Paramètres contenant le chemin du fichier
 * @returns Réponse avec le contenu du fichier ou une erreur
 */</span>
<span class="k">export</span> <span class="k">async</span> <span class="kd">function</span> <span class="nx">readFile</span><span class="p">(</span><span class="nx">params</span><span class="p">:</span> <span class="nx">ReadFileParams</span><span class="p">):</span> <span class="nb">Promise</span><span class="o"><</span><span class="nx">ToolResponse</span><span class="o">></span> <span class="p">{</span>
  <span class="k">try</span> <span class="p">{</span>
    <span class="c1">// Étape 1 : Validation des paramètres</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">params</span><span class="p">.</span><span class="nx">chemin_du_fichier</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="p">{</span>
        <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
        <span class="na">error</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Le paramètre 'chemin_du_fichier' est requis</span><span class="dl">"</span>
      <span class="p">};</span>
    <span class="p">}</span>

    <span class="c1">// Étape 2 : Sécurité - Résoudre le chemin absolu</span>
    <span class="c1">// Cela évite les tentatives d'accès à des chemins relatifs dangereux</span>
    <span class="kd">const</span> <span class="nx">absolutePath</span> <span class="o">=</span> <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">params</span><span class="p">.</span><span class="nx">chemin_du_fichier</span><span class="p">);</span>

    <span class="c1">// Étape 3 : Vérifier que le fichier existe</span>
    <span class="k">try</span> <span class="p">{</span>
      <span class="k">await</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">access</span><span class="p">(</span><span class="nx">absolutePath</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">catch</span> <span class="p">{</span>
      <span class="k">return</span> <span class="p">{</span>
        <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
        <span class="na">error</span><span class="p">:</span> <span class="s2">`Fichier introuvable : </span><span class="p">${</span><span class="nx">params</span><span class="p">.</span><span class="nx">chemin_du_fichier</span><span class="p">}</span><span class="s2">`</span>
      <span class="p">};</span>
    <span class="p">}</span>

    <span class="c1">// Étape 4 : Obtenir les informations du fichier</span>
    <span class="kd">const</span> <span class="nx">stats</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">stat</span><span class="p">(</span><span class="nx">absolutePath</span><span class="p">);</span>

    <span class="c1">// Étape 5 : Vérifier que c'est bien un fichier (pas un dossier)</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">stats</span><span class="p">.</span><span class="nx">isFile</span><span class="p">())</span> <span class="p">{</span>
      <span class="k">return</span> <span class="p">{</span>
        <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
        <span class="na">error</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Le chemin spécifié n'est pas un fichier</span><span class="dl">"</span>
      <span class="p">};</span>
    <span class="p">}</span>

    <span class="c1">// Étape 6 : Limiter la taille (sécurité - éviter de lire des fichiers énormes)</span>
    <span class="kd">const</span> <span class="nx">MAX_FILE_SIZE</span> <span class="o">=</span> <span class="mi">10</span> <span class="o">*</span> <span class="mi">1024</span> <span class="o">*</span> <span class="mi">1024</span><span class="p">;</span> <span class="c1">// 10 MB</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">stats</span><span class="p">.</span><span class="nx">size</span> <span class="o">></span> <span class="nx">MAX_FILE_SIZE</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="p">{</span>
        <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
        <span class="na">error</span><span class="p">:</span> <span class="s2">`Fichier trop volumineux (max </span><span class="p">${</span><span class="nx">MAX_FILE_SIZE</span> <span class="o">/</span> <span class="mi">1024</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">}</span><span class="s2"> MB)`</span>
      <span class="p">};</span>
    <span class="p">}</span>

    <span class="c1">// Étape 7 : Lire le contenu du fichier</span>
    <span class="kd">const</span> <span class="nx">content</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span><span class="p">(</span><span class="nx">absolutePath</span><span class="p">,</span> <span class="dl">'</span><span class="s1">utf-8</span><span class="dl">'</span><span class="p">);</span>

    <span class="c1">// Étape 8 : Retourner le succès avec métadonnées</span>
    <span class="k">return</span> <span class="p">{</span>
      <span class="na">success</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
      <span class="na">content</span><span class="p">:</span> <span class="nx">content</span><span class="p">,</span>
      <span class="na">metadata</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">path</span><span class="p">:</span> <span class="nx">absolutePath</span><span class="p">,</span>
        <span class="na">size</span><span class="p">:</span> <span class="nx">stats</span><span class="p">.</span><span class="nx">size</span><span class="p">,</span>
        <span class="na">lastModified</span><span class="p">:</span> <span class="nx">stats</span><span class="p">.</span><span class="nx">mtime</span>
      <span class="p">}</span>
    <span class="p">};</span>

  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="na">error</span><span class="p">:</span> <span class="kr">any</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Gestion des erreurs inattendues</span>
    <span class="k">return</span> <span class="p">{</span>
      <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
      <span class="na">error</span><span class="p">:</span> <span class="s2">`Erreur lors de la lecture : </span><span class="p">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="p">}</span><span class="s2">`</span>
    <span class="p">};</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="cm">/**
 * Définition de l'outil pour le protocole MCP
 * C'est ce que l'IA "voit" quand elle découvre nos outils
 */</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">readFileToolDefinition</span><span class="p">:</span> <span class="nx">ToolDefinition</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">readFile</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Lit le contenu d'un fichier texte depuis le système de fichiers local</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">parameters</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">chemin_du_fichier</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">string</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Chemin absolu ou relatif vers le fichier à lire</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">required</span><span class="p">:</span> <span class="kc">true</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">};</span>

Prenons un moment pour comprendre ce code. Chaque étape est numérotée et expliquée :

Validation : On vérifie que le paramètre nécessaire est présent. Toujours valider les entrées !

Sécurité : On résout le chemin absolu pour éviter les chemins relatifs malveillants comme ../../etc/passwd.

Vérification existence : On s’assure que le fichier existe avant d’essayer de le lire.

Vérification type : On confirme que c’est un fichier, pas un dossier.

Limite de taille : On évite de charger un fichier de 2 GB en mémoire par erreur.

Lecture : On lit enfin le contenu en UTF-8.

Réponse enrichie : On retourne non seulement le contenu, mais aussi des métadonnées utiles.

Gestion d’erreurs : On capture toute erreur inattendue proprement.

Créer un Gestionnaire d’Outils

Maintenant, créons un fichier qui va centraliser tous nos outils. Créez src/tools/index.ts :

<span class="c1">// src/tools/index.ts</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">ToolDefinition</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">../types/mcp</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">readFile</span><span class="p">,</span> <span class="nx">readFileToolDefinition</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./readFile</span><span class="dl">'</span><span class="p">;</span>

<span class="c1">// Registre de tous nos outils</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">tools</span> <span class="o">=</span> <span class="p">{</span>
  <span class="nx">readFile</span>
<span class="p">};</span>

<span class="c1">// Définitions de tous nos outils (pour le "menu")</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">toolDefinitions</span><span class="p">:</span> <span class="nx">ToolDefinition</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[</span>
  <span class="nx">readFileToolDefinition</span>
<span class="p">];</span>

<span class="c1">// Fonction helper pour exécuter un outil par son nom</span>
<span class="k">export</span> <span class="k">async</span> <span class="kd">function</span> <span class="nx">executeTool</span><span class="p">(</span><span class="nx">toolName</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">params</span><span class="p">:</span> <span class="kr">any</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">tool</span> <span class="o">=</span> <span class="nx">tools</span><span class="p">[</span><span class="nx">toolName</span> <span class="k">as</span> <span class="kr">keyof</span> <span class="k">typeof</span> <span class="nx">tools</span><span class="p">];</span>

  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">tool</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span>
      <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
      <span class="na">error</span><span class="p">:</span> <span class="s2">`Outil '</span><span class="p">${</span><span class="nx">toolName</span><span class="p">}</span><span class="s2">' introuvable`</span>
    <span class="p">};</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="k">await</span> <span class="nx">tool</span><span class="p">(</span><span class="nx">params</span><span class="p">);</span>
<span class="p">}</span>

Ce fichier agit comme un registre central. Quand vous créerez de nouveaux outils, vous les ajouterez simplement ici.

Intégrer dans le Serveur Express

Modifions maintenant notre src/index.ts pour exposer nos outils via des routes HTTP :

<span class="c1">// src/index.ts</span>
<span class="k">import</span> <span class="nx">express</span><span class="p">,</span> <span class="p">{</span> <span class="nx">Request</span><span class="p">,</span> <span class="nx">Response</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">toolDefinitions</span><span class="p">,</span> <span class="nx">executeTool</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./tools</span><span class="dl">'</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span>
<span class="kd">const</span> <span class="nx">PORT</span> <span class="o">=</span> <span class="mi">3000</span><span class="p">;</span>

<span class="c1">// Middleware pour parser le JSON</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nx">json</span><span class="p">());</span>

<span class="c1">// Route de test</span>
<span class="nx">app</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">:</span> <span class="nx">Request</span><span class="p">,</span> <span class="nx">res</span><span class="p">:</span> <span class="nx">Response</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
  <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">({</span>
    <span class="na">message</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Serveur MCP opérationnel !</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">version</span><span class="p">:</span> <span class="dl">'</span><span class="s1">1.0.0</span><span class="dl">'</span>
  <span class="p">});</span>
<span class="p">});</span>

<span class="c1">// Route pour découvrir les outils disponibles (le "menu")</span>
<span class="nx">app</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tools</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">:</span> <span class="nx">Request</span><span class="p">,</span> <span class="nx">res</span><span class="p">:</span> <span class="nx">Response</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
  <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">({</span>
    <span class="na">success</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="na">tools</span><span class="p">:</span> <span class="nx">toolDefinitions</span>
  <span class="p">});</span>
<span class="p">});</span>

<span class="c1">// Route pour exécuter un outil</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tools/:toolName</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">(</span><span class="nx">req</span><span class="p">:</span> <span class="nx">Request</span><span class="p">,</span> <span class="nx">res</span><span class="p">:</span> <span class="nx">Response</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
  <span class="kd">const</span> <span class="p">{</span> <span class="nx">toolName</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">;</span>
  <span class="kd">const</span> <span class="nx">params</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">;</span>

  <span class="k">try</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">executeTool</span><span class="p">(</span><span class="nx">toolName</span><span class="p">,</span> <span class="nx">params</span><span class="p">);</span>
    <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">result</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="na">error</span><span class="p">:</span> <span class="kr">any</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">500</span><span class="p">).</span><span class="nx">json</span><span class="p">({</span>
      <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
      <span class="na">error</span><span class="p">:</span> <span class="s2">`Erreur serveur : </span><span class="p">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="p">}</span><span class="s2">`</span>
    <span class="p">});</span>
  <span class="p">}</span>
<span class="p">});</span>

<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">PORT</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`✅ Serveur MCP lancé sur http://localhost:</span><span class="p">${</span><span class="nx">PORT</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`📋 Outils disponibles : http://localhost:</span><span class="p">${</span><span class="nx">PORT</span><span class="p">}</span><span class="s2">/tools`</span><span class="p">);</span>
<span class="p">});</span>

Notre serveur expose maintenant deux routes importantes :

GET /tools : Liste tous les outils disponibles (le fameux “menu”)

POST /tools/:toolName : Exécute un outil spécifique avec les paramètres fournis

Tester l’Outil

Moment de vérité ! Testons notre outil. D’abord, créons un fichier de test :

<span class="nb">echo</span> <span class="s2">"Ceci est un fichier de test pour le MCP !"</span> <span class="o">></span> test.txt

Lancez votre serveur :

npm run dev

Vous devriez voir :

✅ Serveur MCP lancé sur http://localhost:3000
📋 Outils disponibles : http://localhost:3000/tools

Test 1 : Découvrir les Outils

Ouvrez un nouveau terminal et testez la découverte :

curl http://localhost:3000/tools

Réponse attendue :

<span class="p">{</span><span class="w">
  </span><span class="nl">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
  </span><span class="nl">"tools"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"readFile"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Lit le contenu d'un fichier texte depuis le système de fichiers local"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"parameters"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"chemin_du_fichier"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Chemin absolu ou relatif vers le fichier à lire"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"required"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span>

Parfait ! L’IA peut maintenant découvrir votre outil.

Test 2 : Utiliser l’Outil

Maintenant, utilisons readFile pour lire notre fichier de test :

curl <span class="nt">-X</span> POST http://localhost:3000/tools/readFile <span class="se">\</span>
  <span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
  <span class="nt">-d</span> <span class="s1">'{"chemin_du_fichier": "test.txt"}'</span>

Réponse attendue :

<span class="p">{</span><span class="w">
  </span><span class="nl">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
  </span><span class="nl">"content"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Ceci est un fichier de test pour le MCP !</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"metadata"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/chemin/absolu/vers/test.txt"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"size"</span><span class="p">:</span><span class="w"> </span><span class="mi">42</span><span class="p">,</span><span class="w">
    </span><span class="nl">"lastModified"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-11-12T10:30:00.000Z"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span>

Ça fonctionne ! Votre serveur MCP peut maintenant lire des fichiers.

Test 3 : Gestion d’Erreurs

Testons avec un fichier inexistant :

curl <span class="nt">-X</span> POST http://localhost:3000/tools/readFile <span class="se">\</span>
  <span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
  <span class="nt">-d</span> <span class="s1">'{"chemin_du_fichier": "fichier_inexistant.txt"}'</span>

Réponse :

<span class="p">{</span><span class="w">
  </span><span class="nl">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
  </span><span class="nl">"error"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Fichier introuvable : fichier_inexistant.txt"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span>

Excellent ! Notre gestion d’erreurs fonctionne correctement.

Améliorer l’Outil

Maintenant que la base fonctionne, ajoutons quelques améliorations. Modifions src/tools/readFile.ts :

<span class="c1">// Ajout du support d'encodages multiples</span>
<span class="k">export</span> <span class="kr">interface</span> <span class="nx">ReadFileParams</span> <span class="kd">extends</span> <span class="nx">ToolParams</span> <span class="p">{</span>
  <span class="nl">chemin_du_fichier</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">encoding</span><span class="p">?:</span> <span class="dl">'</span><span class="s1">utf-8</span><span class="dl">'</span> <span class="o">|</span> <span class="dl">'</span><span class="s1">ascii</span><span class="dl">'</span> <span class="o">|</span> <span class="dl">'</span><span class="s1">base64</span><span class="dl">'</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">export</span> <span class="k">async</span> <span class="kd">function</span> <span class="nx">readFile</span><span class="p">(</span><span class="nx">params</span><span class="p">:</span> <span class="nx">ReadFileParams</span><span class="p">):</span> <span class="nb">Promise</span><span class="o"><</span><span class="nx">ToolResponse</span><span class="o">></span> <span class="p">{</span>
  <span class="k">try</span> <span class="p">{</span>
    <span class="c1">// ... validation existante ...</span>

    <span class="c1">// Support de différents encodages</span>
    <span class="kd">const</span> <span class="nx">encoding</span> <span class="o">=</span> <span class="nx">params</span><span class="p">.</span><span class="nx">encoding</span> <span class="o">||</span> <span class="dl">'</span><span class="s1">utf-8</span><span class="dl">'</span><span class="p">;</span>
    <span class="kd">const</span> <span class="nx">content</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span><span class="p">(</span><span class="nx">absolutePath</span><span class="p">,</span> <span class="nx">encoding</span><span class="p">);</span>

    <span class="k">return</span> <span class="p">{</span>
      <span class="na">success</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
      <span class="na">content</span><span class="p">:</span> <span class="nx">content</span><span class="p">,</span>
      <span class="na">metadata</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">path</span><span class="p">:</span> <span class="nx">absolutePath</span><span class="p">,</span>
        <span class="na">size</span><span class="p">:</span> <span class="nx">stats</span><span class="p">.</span><span class="nx">size</span><span class="p">,</span>
        <span class="na">encoding</span><span class="p">:</span> <span class="nx">encoding</span><span class="p">,</span>
        <span class="na">lastModified</span><span class="p">:</span> <span class="nx">stats</span><span class="p">.</span><span class="nx">mtime</span>
      <span class="p">}</span>
    <span class="p">};</span>

  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="na">error</span><span class="p">:</span> <span class="kr">any</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span>
      <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
      <span class="na">error</span><span class="p">:</span> <span class="s2">`Erreur lors de la lecture : </span><span class="p">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="p">}</span><span class="s2">`</span>
    <span class="p">};</span>
  <span class="p">}</span>
<span class="p">}</span>

Et mettons à jour la définition :

<span class="k">export</span> <span class="kd">const</span> <span class="nx">readFileToolDefinition</span><span class="p">:</span> <span class="nx">ToolDefinition</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">readFile</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Lit le contenu d'un fichier texte depuis le système de fichiers local</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">parameters</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">chemin_du_fichier</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">string</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Chemin absolu ou relatif vers le fichier à lire</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">required</span><span class="p">:</span> <span class="kc">true</span>
    <span class="p">},</span>
    <span class="na">encoding</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">string</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Encodage du fichier (utf-8, ascii, base64)</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">required</span><span class="p">:</span> <span class="kc">false</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">};</span>

Créer un Deuxième Outil : listFiles

Maintenant que vous maîtrisez la création d’un outil, créons-en un deuxième rapidement. Créez src/tools/listFiles.ts :

<span class="c1">// src/tools/listFiles.ts</span>
<span class="k">import</span> <span class="nx">fs</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">fs/promises</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="nx">path</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">path</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">ToolParams</span><span class="p">,</span> <span class="nx">ToolResponse</span><span class="p">,</span> <span class="nx">ToolDefinition</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">../types/mcp</span><span class="dl">'</span><span class="p">;</span>

<span class="k">export</span> <span class="kr">interface</span> <span class="nx">ListFilesParams</span> <span class="kd">extends</span> <span class="nx">ToolParams</span> <span class="p">{</span>
  <span class="nl">chemin_du_dossier</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">export</span> <span class="k">async</span> <span class="kd">function</span> <span class="nx">listFiles</span><span class="p">(</span><span class="nx">params</span><span class="p">:</span> <span class="nx">ListFilesParams</span><span class="p">):</span> <span class="nb">Promise</span><span class="o"><</span><span class="nx">ToolResponse</span><span class="o">></span> <span class="p">{</span>
  <span class="k">try</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">params</span><span class="p">.</span><span class="nx">chemin_du_dossier</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="p">{</span>
        <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
        <span class="na">error</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Le paramètre 'chemin_du_dossier' est requis</span><span class="dl">"</span>
      <span class="p">};</span>
    <span class="p">}</span>

    <span class="kd">const</span> <span class="nx">absolutePath</span> <span class="o">=</span> <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">params</span><span class="p">.</span><span class="nx">chemin_du_dossier</span><span class="p">);</span>

    <span class="c1">// Vérifier que c'est un dossier</span>
    <span class="kd">const</span> <span class="nx">stats</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">stat</span><span class="p">(</span><span class="nx">absolutePath</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">stats</span><span class="p">.</span><span class="nx">isDirectory</span><span class="p">())</span> <span class="p">{</span>
      <span class="k">return</span> <span class="p">{</span>
        <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
        <span class="na">error</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Le chemin spécifié n'est pas un dossier</span><span class="dl">"</span>
      <span class="p">};</span>
    <span class="p">}</span>

    <span class="c1">// Lire le contenu du dossier</span>
    <span class="kd">const</span> <span class="nx">files</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readdir</span><span class="p">(</span><span class="nx">absolutePath</span><span class="p">);</span>

    <span class="c1">// Obtenir les détails de chaque fichier</span>
    <span class="kd">const</span> <span class="nx">filesWithDetails</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">(</span>
      <span class="nx">files</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="k">async</span> <span class="p">(</span><span class="nx">file</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">filePath</span> <span class="o">=</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">absolutePath</span><span class="p">,</span> <span class="nx">file</span><span class="p">);</span>
        <span class="kd">const</span> <span class="nx">fileStats</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">stat</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>

        <span class="k">return</span> <span class="p">{</span>
          <span class="na">name</span><span class="p">:</span> <span class="nx">file</span><span class="p">,</span>
          <span class="na">type</span><span class="p">:</span> <span class="nx">fileStats</span><span class="p">.</span><span class="nx">isDirectory</span><span class="p">()</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">directory</span><span class="dl">'</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">file</span><span class="dl">'</span><span class="p">,</span>
          <span class="na">size</span><span class="p">:</span> <span class="nx">fileStats</span><span class="p">.</span><span class="nx">size</span><span class="p">,</span>
          <span class="na">lastModified</span><span class="p">:</span> <span class="nx">fileStats</span><span class="p">.</span><span class="nx">mtime</span>
        <span class="p">};</span>
      <span class="p">})</span>
    <span class="p">);</span>

    <span class="k">return</span> <span class="p">{</span>
      <span class="na">success</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
      <span class="na">content</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">filesWithDetails</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span>
      <span class="na">metadata</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">path</span><span class="p">:</span> <span class="nx">absolutePath</span><span class="p">,</span>
        <span class="na">count</span><span class="p">:</span> <span class="nx">filesWithDetails</span><span class="p">.</span><span class="nx">length</span>
      <span class="p">}</span>
    <span class="p">};</span>

  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="na">error</span><span class="p">:</span> <span class="kr">any</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span>
      <span class="na">success</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
      <span class="na">error</span><span class="p">:</span> <span class="s2">`Erreur lors de la lecture du dossier : </span><span class="p">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="p">}</span><span class="s2">`</span>
    <span class="p">};</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">listFilesToolDefinition</span><span class="p">:</span> <span class="nx">ToolDefinition</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">listFiles</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Liste les fichiers et dossiers dans un répertoire</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">parameters</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">chemin_du_dossier</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">string</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Chemin absolu ou relatif vers le dossier</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">required</span><span class="p">:</span> <span class="kc">true</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">};</span>

Ajoutez-le dans src/tools/index.ts :

<span class="k">import</span> <span class="p">{</span> <span class="nx">listFiles</span><span class="p">,</span> <span class="nx">listFilesToolDefinition</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./listFiles</span><span class="dl">'</span><span class="p">;</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">tools</span> <span class="o">=</span> <span class="p">{</span>
  <span class="nx">readFile</span><span class="p">,</span>
  <span class="nx">listFiles</span>
<span class="p">};</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">toolDefinitions</span><span class="p">:</span> <span class="nx">ToolDefinition</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[</span>
  <span class="nx">readFileToolDefinition</span><span class="p">,</span>
  <span class="nx">listFilesToolDefinition</span>
<span class="p">];</span>

Relancez votre serveur et testez :

curl http://localhost:3000/tools

Vous verrez maintenant deux outils disponibles !

Bonnes Pratiques et Sécurité

Maintenant que vous savez créer des outils, parlons sécurité. Voici les règles d’or :

Toujours Valider les Entrées

Ne faites jamais confiance aux paramètres reçus. Validez tout : type, format, longueur, valeurs autorisées.

Limiter l’Accès aux Fichiers

Créez une liste de dossiers autorisés :

<span class="kd">const</span> <span class="nx">ALLOWED_DIRECTORIES</span> <span class="o">=</span> <span class="p">[</span>
  <span class="dl">'</span><span class="s1">/home/user/documents</span><span class="dl">'</span><span class="p">,</span>
  <span class="dl">'</span><span class="s1">/home/user/projects</span><span class="dl">'</span>
<span class="p">];</span>

<span class="kd">function</span> <span class="nx">isPathAllowed</span><span class="p">(</span><span class="nx">filePath</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">absolute</span> <span class="o">=</span> <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>
  <span class="k">return</span> <span class="nx">ALLOWED_DIRECTORIES</span><span class="p">.</span><span class="nx">some</span><span class="p">(</span><span class="nx">dir</span> <span class="o">=></span> <span class="nx">absolute</span><span class="p">.</span><span class="nx">startsWith</span><span class="p">(</span><span class="nx">dir</span><span class="p">));</span>
<span class="p">}</span>

Limiter les Tailles

Toujours définir des limites de taille de fichiers, de nombre de résultats, de profondeur de récursion.

Logger les Accès

Gardez une trace de qui accède à quoi :

<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`[</span><span class="p">${</span><span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">toISOString</span><span class="p">()}</span><span class="s2">] readFile: </span><span class="p">${</span><span class="nx">params</span><span class="p">.</span><span class="nx">chemin_du_fichier</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>

Conclusion

Félicitations ! Vous venez de créer votre premier outil MCP fonctionnel. Vous avez appris à :

  • Structurer un outil MCP avec TypeScript
  • Gérer les paramètres et les réponses
  • Valider les entrées et gérer les erreurs
  • Exposer vos outils via une API REST
  • Tester vos outils avec curl
  • Créer plusieurs outils et les enregistrer

La prochaine étape ? Dans le prochain article, nous verrons comment une IA découvre et utilise vos outils automatiquement. Nous implémenterons le protocole complet de découverte et d’exécution, puis nous connecterons votre serveur à Claude Desktop pour voir la magie opérer en conditions réelles.

En attendant, expérimentez ! Créez vos propres outils. Que diriez-vous d’un outil qui recherche dans des fichiers ? Ou qui renomme des fichiers en masse ? Ou qui analyse des données JSON ? Les possibilités sont infinies.


Article publié le 12 novembre 2025 par Nicolas Dabène - Expert PHP & PrestaShop avec 15+ ans d’expérience dans l’architecture logicielle et l’intégration d’IA

À lire aussi :

LinkedIn

Suivez mes analyses IA et e-commerce

Je partage des retours terrain sur les agents IA, PrestaShop, MCP et l automatisation pour les equipes e-commerce.

Me suivre sur LinkedIn