vendredi 25 septembre 2026

À propos

Contact

IA & MCP

Écrire son propre serveur MCP pour piloter un site WordPress

Construire un serveur MCP en TypeScript qui expose des outils appuyés sur l'API REST WordPress, avec déclaration de schémas et tests via un client réel.

Par Clément Hadrot • 30 juillet 2025 • 4 min de lecture • Aucun commentaire
Écrire son propre serveur MCP pour piloter un site WordPress

Le Model Context Protocol, publié fin 2024, standardise la façon dont un agent ou un client d’IA peut découvrir et appeler des outils exposés par un serveur, via une connexion structurée en JSON-RPC. Plutôt que d’attendre l’arrivée d’un adaptateur officiel dans WordPress, nous avons construit notre propre serveur MCP en TypeScript pour un projet client, capable de lire et modifier du contenu via l’API REST existante. Cet article ne traite pas du MCP Adapter officiel du projet WordPress, sorti plus tard : ici, tout est fait main, avec un SDK MCP générique.

Voici la démarche complète, du choix des outils à exposer jusqu’aux tests avec un client MCP réel.

Choisir les outils à exposer, pas à tout exposer

La tentation initiale est de vouloir exposer l’intégralité de l’API REST WordPress comme autant d’outils MCP. Nous avons préféré partir des besoins réels du client : lister les articles récents, créer un brouillon, et rechercher du contenu par mot-clé. Trois outils, pas plus, avec l’idée d’en ajouter seulement si un usage concret l’exigeait.

Déclarer le serveur et ses outils

Chaque outil MCP se déclare avec un nom, une description et un schéma d’entrée en Zod, que le client peut lire avant même d’appeler l’outil. C’est cette description qui permet à un agent de comprendre quand et comment utiliser l’outil sans documentation externe.

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

const server = new McpServer({ name: 'wordpress-tools', version: '1.0.0' });

server.tool(
  'lister_articles_recents',
  { limite: z.number().min(1).max(20).default(5) },
  async ( { limite } ) => {
    const reponse = await fetch(
      `${process.env.WP_URL}/wp-json/wp/v2/posts?per_page=${limite}`,
      { headers: { Authorization: `Bearer ${process.env.WP_TOKEN}` } }
    );
    const articles = await reponse.json();
    return {
      content: [ { type: 'text', text: JSON.stringify( articles.map( ( a ) => ( {
        id: a.id, titre: a.title.rendered, url: a.link,
      } ) ) ) } ],
    };
  }
);
L'essentiel à retenir : Un serveur MCP déclare des outils avec un schéma d'entrée précis ; Chaque outil reste une fonction TypeScript classique en coulisses ; Tester avec un vrai client évite les mauvaises surprises de schéma

L’outil de création, avec vérification de permission

Pour l’outil de création de brouillon, nous ajoutons une vérification explicite côté serveur MCP avant même d’appeler l’API REST : un jeton d’application WordPress dédié, avec un rôle limité à la création de contenu en brouillon, jamais à la publication directe. Le serveur MCP ne fait que relayer un appel à une route existante, mais le contrôle des droits reste entièrement du côté de WordPress, via les jetons d’application classiques.

server.tool(
  'creer_brouillon',
  { titre: z.string().min(3), contenu: z.string().min(10) },
  async ( { titre, contenu } ) => {
    const reponse = await fetch( `${process.env.WP_URL}/wp-json/wp/v2/posts`, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.WP_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify( { title: titre, content: contenu, status: 'draft' } ),
    } );
    if ( ! reponse.ok ) {
      return { content: [ { type: 'text', text: 'Échec de la création du brouillon.' } ], isError: true };
    }
    const article = await reponse.json();
    return { content: [ { type: 'text', text: `Brouillon créé : ${article.link}` } ] };
  }
);

Tester avec un client MCP réel

Écrire un serveur sans le tester avec un vrai client masque des erreurs de schéma qui ne se voient qu’à l’usage : un champ optionnel mal typé, une description trop vague qui pousse l’agent à mal utiliser l’outil, ou un message d’erreur peu clair en cas d’échec. Nous connectons systématiquement notre serveur à un client de développement en local avant toute mise en production, en observant les appels réellement effectués par l’agent face à des consignes ambiguës volontairement testées.

Un piège rencontré

Sur la première version, le paramètre limite de l’outil de listing n’avait pas de valeur par défaut. Face à une consigne du type « montre-moi les derniers articles », certains clients envoyaient une valeur absurde ou omettaient le paramètre, provoquant une erreur silencieuse côté serveur. Ajouter une valeur par défaut dans le schéma Zod a réglé le problème sans changer une ligne de logique métier.

  • Commencer par un petit nombre d’outils réellement utiles, pas une couverture exhaustive
  • Toujours passer par des jetons d’application WordPress à droits limités
  • Donner une valeur par défaut à chaque paramètre optionnel du schéma
  • Tester avec un client MCP réel avant toute mise en production

Un serveur MCP n’est qu’une couche de traduction. La sécurité et les permissions restent, comme toujours, du côté de WordPress.

En résumé

Écrire son propre serveur MCP reste accessible avec les SDK actuels, à condition de limiter le périmètre des outils exposés et de ne jamais relâcher le contrôle des permissions côté WordPress. Ce projet nous a servi de brique de départ, reprise depuis sur d’autres clients avec des outils adaptés à chaque contexte métier.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi