# EXP-003 — MCP + WordPress en lecture seule

## Objectif

Connecter réellement un client MCP au WordPress de test, mesurer la surface découverte et lire uniquement les métadonnées de découverte, sans exécuter d’Ability métier ni d’écriture WordPress.

## Hypothèse

MCP Adapter 0.5.0 peut démarrer sur WordPress 7.0.4, fournir son serveur par défaut en STDIO et HTTP, et limiter les Abilities métier au marquage explicite `meta.mcp.public`.

## Environnement

URL canonique : `https://www.lab.quantumdev.fr` ; racine : `/home/vawa9743/lab.quantumdev.fr` ; WordPress 7.0.4 ; PHP 8.4.24 ; WP-CLI 2.12.0 ; MariaDB 11.4.12 ; SSH fonctionnel.

## Préconditions

EXP-001 et EXP-002 validés. Les preuves précédentes sont conservées. Le dump DB pré-MCP a été créé et vérifié avant installation. Aucun secret n’est inclus dans les preuves textuelles.

## Documentation officielle utilisée

- [Release officielle WordPress/mcp-adapter v0.5.0](https://github.com/WordPress/mcp-adapter/releases/tag/v0.5.0), artefact GitHub téléchargé et hashé.
- [Documentation WordPress Developer sur MCP Adapter](https://developer.wordpress.org/news/2026/02/from-abilities-to-ai-agents-introducing-the-wordpress-mcp-adapter/).
- [Dépôt officiel WordPress/mcp-adapter](https://github.com/WordPress/mcp-adapter).
- [Spécification MCP — transports](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports).

## Rollback préalable

READY avant installation. Dump complet : `lab/rollback/EXP-003-pre-mcp/database.sql`, taille 866610 octets, permissions restrictives. Inventaire plugins et état pré-MCP : `plugins-before.txt` et `state-before.txt`. Aucun dépôt Git local n’existait ; le dump est hors versionnement. Procédure préparée : révoquer tout credential (aucun créé), supprimer `quantumdev_mcp_lab`, désactiver puis supprimer MCP Adapter, restaurer le dump si nécessaire, et revalider l’état EXP-002.

## MCP Adapter

### Version

0.5.0, version explicitement retenue pour la reproductibilité.

### Source

Release GitHub officielle : `https://github.com/WordPress/mcp-adapter/releases/download/v0.5.0/mcp-adapter.zip`. SHA-256 : `a13f253c7bf4314b6cce7e238be2d5857eee66242bfe5ff5cb5576f74dc41593`. Taille : 372587 octets. Test ZIP réussi.

### Installation

Installation comme plugin WordPress autonome, puis activation de ce seul plugin. Statut observé : `mcp-adapter` actif, version 0.5.0. Le site et REST restent HTTP 200 ; les plugins antérieurs, thèmes et contenus restent inchangés.

### Configuration

Aucune configuration WordPress ajoutée. Le serveur par défaut observé est `mcp-adapter-default-server`, route HTTP `/wp-json/mcp/mcp-adapter-default-server`, avec 3 outils, 0 ressource et 0 prompt.

## Transport

STDIO et HTTP sont présents dans l’adaptateur. STDIO a été réellement utilisé via `wp mcp-adapter serve`; il convient au lab distant via SSH/local subprocess. HTTP est enregistré et protégé par le callback de transport par défaut `is_user_logged_in()`, mais aucun POST MCP n’a été envoyé conformément à la politique de l’expérience. SSE séparé non démontré ; le code 0.5.0 indique que le streaming SSE n’est pas implémenté dans le handler HTTP.

## Authentification

Pour STDIO, l’identité est fournie par `wp mcp-adapter serve --user=quantumdev_mcp_lab`. L’utilisateur dédié est un Subscriber, sans mot de passe conservé, sans Application Password et sans donnée personnelle réelle. Aucun compte administrateur principal n’a été utilisé. Pour HTTP distant, l’authentification par Application Password/proxy n’a pas été configurée ni testée.

## Client MCP

`exp-003-stdio-probe` 1.0 : probe JSON-RPC ligne par ligne utilisant le bridge STDIO WP-CLI déjà installé. Aucun client npm externe n’a été installé. Détails dans [client.txt](../../lab/output/EXP-003/client.txt).

## Handshake

Handshake réussi avec protocole négocié `2025-06-18`, serveur `MCP Adapter Default Server`, version `v1.0.0`. Capabilities annoncées : tools, resources et prompts (listChanged/subscribe selon la primitive). Preuve : [handshake.txt](../../lab/output/EXP-003/handshake.txt).

## Outils découverts

3 outils : `mcp-adapter-discover-abilities`, `mcp-adapter-get-ability-info`, `mcp-adapter-execute-ability`. Le troisième est annoté `readOnlyHint=false`, `destructiveHint=true`, `idempotentHint=false` ; il n’a pas été appelé. Preuve structurée : [tools-list.json](../../lab/output/EXP-003/tools-list.json).

## Ressources découvertes

0 (`resources/list` retourne `[]`).

## Prompts découverts

0 (`prompts/list` retourne `[]`).

## Abilities exposées

Après activation, 11 Abilities sont enregistrées : les 8 précédentes et les 3 Abilities de l’adaptateur. Seules `ai/get-post-details` et `ai/get-post-terms` ont `meta.mcp.public=true`. Elles déclarent `readonly`, `destructive` et `idempotent` à `null`; elles n’ont donc pas satisfait le seuil de sécurité pour exécution. Les trois outils d’adaptateur sont présents mais leurs Abilities internes ne sont pas `mcp.public`. Preuve : [mcp-public-abilities.txt](../../lab/output/EXP-003/mcp-public-abilities.txt).

## Test non authentifié

STDIO sans `--user` : handshake et listes réussis. GET HTTP anonyme sur `/wp-json/mcp/mcp-adapter-default-server` : HTTP 401 `rest_forbidden`. Aucun POST JSON-RPC HTTP anonyme n’a été envoyé.

## Test authentifié

STDIO avec `quantumdev_mcp_lab` (Subscriber) : handshake, `tools/list`, `resources/list` et `prompts/list` réussis. Les résultats sont identiques à la session anonyme STDIO pour ces primitives de découverte.

## Première lecture contrôlée

Ability : `mcp-adapter/discover-abilities` via `tools/call` STDIO authentifié.

Résultat : deux Abilities MCP-public retournées, avec nom, label et description : `ai/get-post-details` et `ai/get-post-terms`.

Utilisateur : `quantumdev_mcp_lab` (Subscriber).

Permission : contexte utilisateur WP-CLI authentifié ; Ability d’adaptateur annotée readonly, non destructive et idempotente.

Aucune Ability métier n’a été exécutée. Preuve : [selected-read.txt](../../lab/output/EXP-003/selected-read.txt).

## Permissions observées

Le serveur MCP par défaut utilise un callback de transport par défaut fondé sur `is_user_logged_in()`. Les permissions propres aux Abilities restent appliquées par leurs callbacks WordPress. Les deux Abilities AI exposées sont connues comme MCP-public, mais leurs effets/annotations nulles et leurs callbacks n’ont pas été contournés.

## Logs / observabilité

Le bridge STDIO écrit un démarrage/arrêt sur STDERR. Le client local voit les requêtes et résultats ; l’utilisateur n’est pas réémis par le log par défaut. Aucun journal serveur distinct horodaté par appel n’a été démontré. Preuve : [logging.txt](../../lab/output/EXP-003/logging.txt).

## Surface exposée

Voir [exposure-matrix.md](../../lab/output/EXP-003/exposure-matrix.md). Résumé : STDIO découverte anonyme et authentifiée ; HTTP GET anonyme 401 ; 3 tools ; 0 resources ; 0 prompts ; 2 Abilities métier MCP-public mais non exécutées.

## Résultat attendu

Installer officiellement MCP Adapter, valider un rollback, établir un serveur et un handshake MCP, distinguer découverte anonyme/authentifiée et n’exécuter qu’une lecture strictement sûre.

## Résultat observé

Tous ces points sont démontrés. La seule lecture effectuée est la découverte des Abilities publiques via l’outil read-only de l’adaptateur. Aucun contenu, réglage ou Ability métier n’a été exécuté.

## Écart attendu / observé

HTTP est disponible mais n’a pas été utilisé en session MCP, car l’expérience interdit les POST anonymes et aucun credential HTTP n’a été créé. STDIO a donc été le transport réel. Les deux Abilities AI MCP-public ne sont pas suffisamment annotées pour une exécution prudente.

## Risques

Le serveur expose un outil générique annoté destructif (`execute-ability`) et deux Abilities AI publiques dont les annotations d’effets sont nulles. Leur présence constitue une surface à traiter avant toute utilisation agentique élargie. Le compte Subscriber dédié limite le contexte utilisateur, mais ne remplace pas une revue d’Ability.

## Rollback

READY : supprimer/revoquer le credential s’il existait (aucun), supprimer `quantumdev_mcp_lab`, désactiver MCP Adapter, supprimer son répertoire plugin, puis restaurer `database.sql` si une restauration DB est nécessaire. Revalider plugins, contenus, utilisateurs et Abilities contre `state-before.txt` et EXP-002.

## Conclusion

MCP Adapter 0.5.0 fonctionne sur WordPress 7.0.4. Le handshake et la découverte sont validés en STDIO avec et sans identité. La surface effective est petite mais inclut un outil d’exécution destructif et deux Abilities AI MCP-public ; aucune exécution métier n’est acceptable dans cette expérience. EXP-003 peut être fermée sous cette réserve.

## Niveau de confiance

fort

## Production

acceptable sous conditions

## Matière éditoriale

### Fait

Le serveur MCP fonctionne, négocie MCP `2025-06-18` et expose exactement 3 tools, 0 resource et 0 prompt.

### Surprise

Le STDIO sans utilisateur permet le handshake et les listes, alors que la route HTTP GET anonyme renvoie 401.

### Chiffre

11 Abilities après installation ; 2 MCP-public ; 1 lecture de découverte ; 0 Ability métier exécutée.

### Erreur

Une vérification initiale demandait un champ WP-CLI `update` invalide pour `plugin get`; elle a été corrigée sans réinstallation ni effet WordPress.

### Décision QuantumDev

Conserver MCP Adapter installé pour cette expérience, mais ne pas exposer davantage d’Abilities ni appeler l’outil générique d’exécution avant une expérience dédiée aux effets et permissions.

### Capture exploitable

`tools/list` révèle l’outil `mcp-adapter-execute-ability` avec `destructiveHint=true`, tandis que les deux listes de primitives restent vides pour resources/prompts.

### Angle LinkedIn

« Connecter un agent n’est pas encore lui donner le droit d’agir : le handshake, la découverte et l’exécution doivent être mesurés séparément. »

### Niveau de preuve

démontré
