---
title: 'Exposer un outil Symfony avec le bundle MCP'
description: 'Configure un serveur MCP local dans Symfony, expose un outil PHP en lecture seule et vérifie sa découverte avec MCP Inspector.'
pubDate: 2025-10-10
family: 'intelligence-artificielle'
tags: []
heroImage: /images/comment-creer-un-serveur-mcp-pour-coder-plus-vite-avec-symfony.webp
videoUrl: 'https://youtu.be/_OKwAqmqcEQ'
updatedDate: 2026-10-13
---

Un serveur MCP permet à un client IA de découvrir et d'appeler des outils que ton application expose explicitement. Dans Symfony, le bundle MCP relie ces capacités au conteneur de services : tu conserves tes services PHP et tu ajoutes une interface dédiée au client.[4]

L'objectif ici est volontairement réduit : exposer une information de diagnostic en lecture seule, puis vérifier son appel avant de brancher un assistant de code. La vidéo de 2025 reste disponible ; les configurations ci-dessous suivent la **documentation du bundle 0.14.1**. Le parcours Inspector reste documenté, non exécuté ici. Les contrôles locaux ont été exécutés avec PHP 8.4.26, Symfony 7.4.20 et le bundle MCP 0.14.1 : syntaxe PHP et YAML valides, `debug:mcp` a recensé `symfony-version`, `debug:router` a montré `/mcp`, et l'appel direct de la méthode a renvoyé `7.4.20`. Ces contrôles ne valident pas la connexion HTTP d'un client MCP.

## 1. Partir d'une application compatible

Prévois une application Symfony fonctionnelle, Composer, PHP compatible avec ses dépendances et Node.js 22.19 ou plus récent pour lancer Inspector.[5] Travaille en développement, pas sur un serveur contenant des secrets de production.

```bash
composer require 'symfony/mcp-bundle:^0.14'
composer check-platform-reqs
php bin/console about
```

Symfony Flex active normalement le bundle via sa recette. Sans Flex, vérifie son enregistrement dans `config/bundles.php`. Consulte la [documentation versionnée du bundle](https://github.com/symfony/ai/blob/v0.14.1/docs/bundles/mcp-bundle.rst) si ta configuration diffère : les anciens exemples ne correspondent pas nécessairement à la structure actuelle.[4]

## 2. Déclarer le serveur HTTP

Dans `config/packages/mcp.yaml`, configure un serveur nommé `default` et limite son registre à une seule classe :

```yaml
mcp:
  servers:
    default:
      name: 'symfony-diagnostic'
      transports:
        http: true
      http:
        path: /mcp
      registry:
        tools: ['App\Mcp\DiagnosticTool']
```

Ajoute l'import de routes dans `config/routes/mcp.yaml` :

```yaml
mcp:
  resource: .
  type: mcp
```

Le registre est une liste d'exposition, pas seulement une option de découverte. Une classe portant un attribut MCP doit aussi être un service Symfony et être sélectionnée par ce registre.[4] Évite d'exposer automatiquement tout le conteneur : une liste explicite rend le périmètre vérifiable.

## 3. Créer un outil sans commande arbitraire

Crée `src/Mcp/DiagnosticTool.php`. L'outil renvoie uniquement la version du framework : il n'exécute pas de commande transmise par le modèle et ne lit aucun fichier utilisateur.

```php
<?php

namespace App\Mcp;

use Mcp\Capability\Attribute\McpTool;
use Symfony\Component\HttpKernel\Kernel;

final class DiagnosticTool
{
    #[McpTool(name: 'symfony-version')]
    public function version(): string
    {
        return Kernel::VERSION;
    }
}
```

Cet exemple adapte le mécanisme d'attributs documenté par le bundle.[4] Avec la configuration Symfony habituelle, les classes de `src/` sont enregistrées et autoconfigurées. Si tu as exclu le dossier `Mcp` dans `services.yaml`, réenregistre la classe comme service.

Contrôle ensuite la configuration :

```bash
php -l src/Mcp/DiagnosticTool.php
php bin/console lint:yaml config/packages/mcp.yaml config/routes/mcp.yaml
php bin/console debug:mcp
php bin/console debug:router
```

**Résultat attendu** : le diagnostic MCP recense l'outil exposé, et le routeur contient le point d'entrée `/mcp`. Aucune sortie de ces commandes n'est présentée ici comme un résultat observé.

## 4. Appeler l'outil avec Inspector

Pour une démonstration locale uniquement, démarre l'application sur la boucle locale :

```bash
php -S 127.0.0.1:8000 -t public
```

Dans un autre terminal :

```bash
npx -y @modelcontextprotocol/inspector
```

Inspector fournit une interface de connexion et de test des outils.[5] Ouvre l'URL indiquée dans ton terminal, choisis le transport **Streamable HTTP**, puis connecte-toi à `http://127.0.0.1:8000/mcp`. Liste les outils et appelle `symfony-version` sans argument.

**Résultat attendu** : l'outil apparaît et son appel renvoie la version Symfony installée. Vérifie cette valeur contre `php bin/console about`. Une page ouverte dans le navigateur ne constitue pas ce test : MCP implique une initialisation de session et des messages de protocole, pas seulement un GET sur une route.[5]

## 5. Étendre le diagnostic sans ouvrir trop de droits

Après validation, remplace ou complète la démonstration par une capacité métier étroite : un résumé de statut, une lecture filtrée ou une recherche limitée. Garde des paramètres typés et impose les autorisations dans le code serveur. Le nom d'un outil ne protège pas son implémentation.

N'expose pas une méthode qui accepte une commande shell libre, un chemin de fichier arbitraire ou une requête SQL fournie par le modèle. Pour des actions modifiant des données, ajoute une validation humaine et conserve une trace des opérations. Un client IA n'est pas une autorité de sécurité.[8]

## Erreurs courantes et limite de ce guide

Si l'outil manque, vérifie l'attribut importé, son enregistrement comme service et sa présence dans `registry`. Si la route manque, vérifie l'import `type: mcp`. Si Composer ou le conteneur refuse une ancienne configuration, compare-la avec la documentation de la version installée avant de renommer des clés au hasard.[4]

Ce serveur reste local et n'a pas d'authentification configurée. Ne le publie pas tel quel. Le [guide de déploiement MCP distant](/blog/comment-creer-et-mettre-en-ligne-un-serveur-mcp/) traite séparément du transport réseau, du reverse proxy et du contrôle d'accès. Regarde la vidéo associée pour retrouver le contexte du serveur Symfony d'origine.

## Sources

[4] https://github.com/symfony/ai/blob/v0.14.1/docs/bundles/mcp-bundle.rst
[5] https://modelcontextprotocol.io/docs/tools/inspector
[8] https://modelcontextprotocol.io/specification/latest/basic/security_best_practices
