Revue de presse tech du 2 au 8 novembre 2026 : failles WordPress exploitées, *sshole, PHP2Shell et agents IA
Symfony AI Mate et Claude : cadrer l’IA avec du contexte vérifié

Symfony AI Mate et Claude : cadrer l’IA avec du contexte vérifié

Un assistant IA qui ne connaît pas votre projet devine. Une IA qui devine finit par inventer des services, des routes ou des colonnes qui n’existent pas. B

Mise à jour importante (novembre 2026). Depuis Symfony AI 0.13, Symfony AI Mate n’est plus un serveur MCP. D’après le blog Symfony, le serveur MCP a été retiré, et la documentation des commandes ne contient plus de commande serve. Mate est maintenant une simple CLI que l’agent appelle directement. L’article tient compte de ce changement : la démarche reste la même (donner à l’IA un contexte vérifié), mais Mate ne se branche plus comme un serveur MCP.

1. Le vrai problème : une IA qui travaille à l’aveugle

Si l’on demande à un assistant IA d’« ajouter l’envoi d’un e-mail de confirmation après une commande » sans lui donner accès au projet, il répond avec les conventions génériques de Symfony. Il suppose que le service voulu est autowiré. Il invente une route plausible, par exemple app_order_confirm. Il déduit des colonnes du nom de l’entité : Order aurait un status et un customer_email. Le code a l’air juste, et c’est précisément pour cela que le problème est sérieux.

Le coût n’apparaît pas tout de suite. Ce code passe parfois l’analyse et compile, puis échoue à l’exécution. Il peut aussi contourner l’architecture réelle : un appel direct au mailer alors que l’équipe passe par un bus Messenger dédié, un EntityManager utilisé à la place du repository métier, une configuration de services.yaml ignorée. Ces erreurs se repèrent tard, souvent en revue de code ou en recette.

Le palliatif habituel consiste à coller des extraits dans le chat : un bout de configuration, la sortie de debug:router, une trace d’erreur. Cela reste partiel et vite obsolète. Surtout, le résultat dépend de ce que le développeur a pensé à coller. Une autre personne, ou la même une semaine plus tard, n’obtiendra pas le même résultat, et la session ne peut pas être rejouée.

2. MCP et Symfony AI Mate : de quoi parle-t-on exactement ?

Le Model Context Protocol en bref

Le Model Context Protocol (MCP) est un protocole ouvert. Il permet à un client IA, comme Claude Code, d’appeler des outils et de lire des ressources qu’expose un serveur, souvent un processus local lancé en stdio. Le client découvre ce que le serveur propose, et le modèle choisit d’appeler tel outil avec tels paramètres. Chaque appel apparaît dans la session.

Le rôle de Symfony AI Mate

Symfony AI Mate est le composant de l’écosystème Symfony AI qui donne à un agent de code accès à l’exécution de l’application : profiler, conteneur, logs. Il s’appuie sur ce que fournissent déjà les commandes de la console (debug:container, debug:router…) et le profiler, et le présente sous forme d’outils que l’agent peut interroger.

Jusqu’à la version 0.12, Mate était bien un serveur MCP lancé par vendor/bin/mate serve (transport stdio). Depuis la 0.13, les mainteneurs ont choisi une CLI couplée à une couche de découverte. Selon le blog Symfony, mate init crée le répertoire mate/ et écrit les instructions pour l’agent, puis mate discover réécrit un bloc géré du fichier AGENTS.md et ajoute l’import @AGENTS.md dans CLAUDE.md (documentation des commandes). Des skills sont aussi installées dans .agents/skills/, avec un miroir dans .claude/skills/. Toujours selon les mainteneurs, un benchmark a montré que les agents utilisaient cette couche de découverte aussi bien que l’ancien serveur MCP.

D’après la documentation officielle, l’installation se fait ainsi :

composer require --dev symfony/ai-mate
vendor/bin/mate init

# Extensions recommandées pour une application Symfony
composer require --dev symfony/ai-symfony-mate-extension symfony/ai-monolog-mate-extension

# Lister les outils réellement disponibles
vendor/bin/mate tools:list

# Exemple d'appel documenté : le dernier profil enregistré
vendor/bin/mate tools:call symfony-profiler-list --limit=1

Ne vous fiez pas à une liste d’outils figée, y compris celle de cet article. Le périmètre dépend de la version et des extensions installées (il existe aussi des extensions communautaires, recensées par awesome-mate). La commande qui fait foi est vendor/bin/mate tools:list dans votre projet.

3. Un contexte fiable, source par source

Conteneur de services et routes

Avant d’écrire du code qui dépend d’un service, l’agent vérifie que ce service existe, regarde ses alias et ses arguments. L’extension Symfony de Mate couvre le conteneur avec symfony-services (recherche) et symfony-service-detail (détail d’un service). Pour les routes, nous n’avons pas trouvé d’outil Mate dédié clairement documenté, et bin/console debug:router nom_de_route reste la référence. Dans les deux cas, l’agent part d’un fait vérifié et non d’une convention supposée :

bin/console debug:container 'App\Messenger\OrderBus'
bin/console debug:router app_order_show

Logs et profiler

C’est sans doute le gain le plus net. Face à une erreur 500, l’agent n’a plus à deviner la cause : il ouvre le profil de la requête concernée (requêtes SQL exécutées, temps de rendu, événements déclenchés) et lit les logs Monolog associés. Le correctif proposé s’appuie alors sur la trace réelle et non sur une hypothèse générique.

Base de données

Pour écrire des requêtes Doctrine ou des migrations cohérentes, l’agent doit connaître le schéma effectif, pas celui qu’il déduit des noms d’entités. Nous n’avons pas trouvé d’outil Mate officiel dédié à la base de données : seules les requêtes SQL exécutées sont visibles, via le collecteur db du profiler. Les sources possibles sont bin/console doctrine:mapping:info, bin/console doctrine:schema:validate, une extension communautaire ou un serveur MCP générique de base de données branché en lecture seule sur la base de dev. Quelques lignes représentatives suffisent : inutile de déverser des tables entières dans le contexte.

4. Limiter les hallucinations et les dérives

L’objectif est de passer du « je pense que » au « j’ai vérifié que ». Avec un projet outillé, chaque affirmation technique de l’agent peut reposer sur un appel visible dans la session, et le relecteur peut demander : « quel outil vous a donné cette information ? ». Il faut quand même l’écrire noir sur blanc. Claude Code lit un fichier CLAUDE.md à la racine du projet, et Mate s’en sert déjà pour importer AGENTS.md. Voici un exemple volontairement court :

# Consignes de travail — projet Symfony

@AGENTS.md

## Règles
- Avant d'injecter un service : vérifier son existence et ses alias
  (`vendor/bin/mate tools:list`, puis l'outil conteneur, ou `bin/console debug:container <id>`).
- Avant d'utiliser une route : `bin/console debug:router <nom>`.
- Avant de proposer un correctif : lire les logs et le profil de la requête concernée.
- Ne jamais modifier le schéma sans générer une migration Doctrine (`bin/console make:migration`).
- Ne jamais lire `.env.local`, `.env.*.local` ni aucune clé d'API.
- Environnement de dev uniquement.
- Toujours terminer par `vendor/bin/phpunit` et `vendor/bin/phpstan analyse`.

Une consigne ne remplace pas une permission. Il faut donc aussi poser des limites techniques :

  • Base en lecture seule : un utilisateur SQL dédié qui n’a que le droit SELECT, sur la base de dev.
  • Environnement de dev uniquement : Mate et les extensions s’installent en --dev et ne doivent jamais arriver en production.
  • Validation humaine des actions sensibles (migrations, suppression de fichiers, commandes réseau) : laissez Claude Code demander une confirmation au lieu de tout autoriser.
  • Exclusion des secrets : bloquez explicitement leur lecture dans .claude/settings.json.
{
  "permissions": {
    "deny": [
      "Read(./.env.local)",
      "Read(./.env.*.local)",
      "Read(./config/secrets/**)"
    ]
  }
}

5. Rendre le travail reproductible et auditable

Une session outillée laisse une trace : outils appelés, données consultées, hypothèses vérifiées ou écartées. En revue de code, cette trace vaut plus qu’un « l’IA l’a proposé ». Dans l’équipe, elle permet de comprendre pourquoi une solution a été retenue.

Pour que chaque poste se comporte de la même façon, il faut versionner la configuration. Pour un serveur MCP, Claude Code lit un fichier .mcp.json à la racine du dépôt (portée « projet »). Ce fichier contient un objet mcpServers dont chaque entrée déclare command et args, et Claude Code demande d’approuver chaque serveur la première fois qu’il le rencontre. Pour Mate antérieur à 0.13, la configuration ressemblait à ceci (exemple indicatif, reconstitué à partir de l’ancienne commande serve : vérifiez-le avec la documentation de votre version) :

{
  "mcpServers": {
    "symfony-ai-mate": {
      "command": "./vendor/bin/mate",
      "args": ["serve"]
    }
  }
}

Ce fichier ne fonctionne plus avec Mate 0.13 et suivants, puisque serve a disparu. Certains projets fondés sur Mate retirent d’ailleurs cette déclaration au moment de la migration. Avec les versions actuelles, ce que l’on versionne pour garantir la reproductibilité, ce sont les fichiers AGENTS.md, CLAUDE.md, les skills générées, la configuration de Mate et le composer.lock qui fixe la version. Le fichier .mcp.json reste utile pour les autres serveurs MCP du projet, par exemple un serveur de base de données en lecture seule. N’y mettez aucun jeton : Claude Code développe les variables d’environnement (${VAR}) dans ce fichier, ce qui permet de garder les secrets hors du dépôt.

Le contexte réduit les erreurs, mais ne les élimine pas toutes. Seule la vérification automatique les attrape : PHPUnit pour le comportement, PHPStan pour les types et les appels inexistants. Faites tourner les deux à la fin de chaque tâche assistée, avec un résultat vert comme condition de fin.

6. Les équivalents dans les autres écosystèmes

Laravel

Laravel Boost (paquet officiel laravel/boost) est un serveur MCP, à la différence de Mate aujourd’hui. Il expose notamment les versions de PHP et de Laravel, le moteur de base de données, les modèles Eloquent, les logs du navigateur, Tinker et une recherche dans la documentation correspondant aux versions installées. L’installation confirmée par la documentation :

composer require laravel/boost --dev
php artisan boost:install

# Enregistrement manuel dans Claude Code si nécessaire
claude mcp add -s local -t stdio laravel-boost php artisan boost:mcp

Django, Node/JS et Rails

  • Django : django-mcp-server, paquet communautaire. Il publie des outils écrits en sous-classant MCPToolset, via un endpoint HTTP /mcp.
  • Next.js : next-devtools-mcp, maintenu par Vercel et cité par la documentation officielle. À partir de Next.js 16, le serveur de dev expose aussi un endpoint MCP à /_next/mcp.
  • NestJS : nous n’avons pas trouvé d’outil officiel lors de nos recherches, donc nous n’en citons aucun.
  • Ruby on Rails : rails-mcp-server, gem communautaire. Elle expose les fichiers, routes, modèles, le schéma et des documentations Rails/Turbo/Stimulus/Kamal.

Python : FastAPI et serveur maison

Pour FastAPI, fastapi-mcp (Tadata, communautaire) expose les endpoints existants en outils MCP. L’API a changé selon les versions : la documentation actuelle utilise mount_http(), les anciennes versions mount(). Vérifiez la version installée avec pip show fastapi-mcp.

from fastapi import FastAPI
from fastapi_mcp import FastApiMCP

app = FastAPI()
mcp = FastApiMCP(app)
mcp.mount_http()  # endpoint /mcp par défaut

Si aucun outil dédié n’existe pour votre stack, le SDK MCP Python officiel (paquet mcp) permet d’écrire en quelques lignes un serveur en lecture seule :

from pathlib import Path
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("schema-lecture-seule")

@mcp.tool()
def lire_schema() -> str:
    """Renvoie le schéma SQL versionné, sans rien modifier."""
    return Path("db/schema.sql").read_text()

if __name__ == "__main__":
    mcp.run()

Récapitulatif

  • Symfony – AI Mate (officiel, 0.x) : profiler, conteneur, logs, outils extensibles via #[MateTool]. Particularité : CLI et skills depuis 0.13, plus de serveur MCP. Son point fort est l’accès au profiler, c’est-à-dire à l’exécution réelle d’une requête.
  • Laravel – Boost (officiel) : versions, modèles, base, logs, documentation versionnée. Il reste un vrai serveur MCP, et sa recherche documentaire est plus aboutie que ce que Mate propose.
  • Django – django-mcp-server (communautaire) : un cadre pour écrire ses propres outils, plutôt qu’une introspection prête à l’emploi.
  • Next.js – next-devtools-mcp (officiel Vercel) : accès au serveur de dev en cours d’exécution.
  • Rails – rails-mcp-server (communautaire) : routes, modèles, schéma, documentation.
  • FastAPI – fastapi-mcp (communautaire) : expose les endpoints existants, ce qui n’est pas de l’introspection du projet.

Ces outils ont en commun les routes, le schéma, les logs et la documentation de la version exacte. Pour choisir, privilégiez les outils maintenus et en lecture seule par défaut, puis testez-les sur une tâche réelle avant de les généraliser.

7. Limites, coûts et bonnes pratiques de mise en place

Ni un serveur MCP ni une CLI d’introspection ne remplacent la compréhension métier ou les décisions d’architecture. Ils dépendent aussi de la qualité des données de dev : des fixtures incohérentes ou un schéma de dev qui a divergé de la production induisent l’IA en erreur avec autant d’assurance qu’une hallucination.

Surveillez la taille du contexte. Un fichier de logs entier ou un profil complet dilue l’information utile et augmente le coût de chaque échange. Préférez les appels ciblés : un profil précis, les dernières lignes de logs, un service nommé.

Enfin, commencez petit. Activez d’abord les outils en lecture (conteneur, routes, logs, profiler), mesurez le gain sur quelques tâches réelles (moins d’allers-retours, moins de corrections en revue), puis étendez progressivement. Et si vous migrez vers Mate 0.13, supprimez l’ancienne entrée mate serve de votre .mcp.json, relancez vendor/bin/mate discover et vérifiez que les fichiers générés sont bien versionnés.

Sources

Ajouter un commentaire

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. Découvrez comment les données de vos commentaires sont traitées.