Guide — Mise en service MCP (step-by-step)
Ce guide part d'une install telaria-app locale fonctionnelle et amène à un serveur MCP branché et vérifié dans Claude Code. À répéter pour chaque instance Claude de l'écosystème.
Prérequis : telaria-app installée sous WSL2, BDD up, php accessible dans WSL.
Étape 1 — Appliquer les migrations MCP
Les tables MCP (mcp_tenant, mcp_project, mcp_api_client, mcp_tool_audit_log) sont créées par une migration dédiée. Vérifier qu'elles sont appliquées (depuis WSL) :
cd /mnt/c/src/telaria-app php bin/console doctrine:migrations:status
Si la migration Version20260529221628 apparaît dans "not migrated" :
php bin/console doctrine:migrations:migrate --no-interaction
Vérification rapide :
php bin/console doctrine:query:sql "SHOW TABLES LIKE 'mcp_%'" # Attendu : mcp_api_client, mcp_project, mcp_tenant, mcp_tool_audit_log
Étape 2 — Vérifier que mcp:serve démarre
Avant de créer des tokens, s'assurer que le serveur démarre sans erreur (depuis WSL) :
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | php /mnt/c/src/telaria-app/bin/console mcp:serve
Réponse attendue (1 ligne JSON) :
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-11-25","capabilities":{"tools":{"listChanged":false}},"serverInfo":{"name":"tlr-mcp","version":"1.0.0"}}}
Si le serveur répond avec une erreur Symfony (manque de config, BDD inaccessible…), résoudre avant de continuer.
Étape 3 — Émettre un token par instance
Lancer app:mcp:seed une fois par instance Claude à brancher. Le token n'est affiché qu'une seule fois — le noter immédiatement.
Les commandes s'exécutent depuis WSL (wsl en PowerShell, ou directement dans un terminal WSL).
Atlas (instance tlr-doc)
php /mnt/c/src/telaria-app/bin/console app:mcp:seed \ --tenant="telaria" \ --project="telaria-doc" \ --root="/mnt/c/src/telaria-doc" \ --scopes="tool:list_docs,tool:read_doc,tool:search_docs,project:telaria-doc"
Lead Tech Telaria (instance telaria-app)
php /mnt/c/src/telaria-app/bin/console app:mcp:seed \ --tenant="telaria" \ --project="telaria-doc" \ --root="/mnt/c/src/telaria-doc" \ --scopes="tool:list_docs,tool:read_doc,tool:search_docs,project:telaria-doc"
Chef (instance tlr-blueprint)
php /mnt/c/src/telaria-app/bin/console app:mcp:seed \ --tenant="telaria" \ --project="telaria-doc" \ --root="/mnt/c/src/telaria-doc" \ --scopes="tool:list_docs,tool:read_doc,tool:search_docs,project:telaria-doc"
Démo vitrine (Claude Desktop)
php /mnt/c/src/telaria-app/bin/console app:mcp:seed \ --tenant="telaria" \ --project="telaria-doc" \ --root="/mnt/c/src/telaria-doc" \ --scopes="tool:search_docs,project:telaria-doc"
--root= chemin WSL de la racine des fichiers Markdown. En local WSL2 :/mnt/c/src/telaria-doc. Sur le VPS (V1.1, HTTP Streamable) :/var/www/telaria/docs.
Le seed est idempotent sur le tenant et le projet : s'ils existent déjà , ils sont réutilisés. Un nouvel
ApiClientest créé à chaque appel — ce qui permet d'émettre plusieurs tokens pour le même projet.
Étape 4 — Écrire le .mcp.json dans chaque repo
Dans le repo de travail de chaque instance, créer (ou compléter) .mcp.json à la racine avec le token obtenu à l'étape précédente.
PHP tournant sous WSL2, la commande passe par wsl. WSLENV=MCP_TOKEN est obligatoire pour que la variable traverse la frontière Windows → Linux.
C:/src/tlr-doc/.mcp.json (Atlas) :
{ "mcpServers": { "tlr-mcp": { "command": "wsl", "args": ["-e", "php", "/mnt/c/src/telaria-app/bin/console", "mcp:serve"], "env": { "MCP_TOKEN": "<token-atlas>", "WSLENV": "MCP_TOKEN" } } } }
C:/src/telaria-app/.mcp.json (Lead Tech Telaria) :
{ "mcpServers": { "tlr-mcp": { "command": "wsl", "args": ["-e", "php", "/mnt/c/src/telaria-app/bin/console", "mcp:serve"], "env": { "MCP_TOKEN": "<token-leadtech>", "WSLENV": "MCP_TOKEN" } } } }
C:/src/tlr-blueprint/.mcp.json (Chef) :
{ "mcpServers": { "tlr-mcp": { "command": "wsl", "args": ["-e", "php", "/mnt/c/src/telaria-app/bin/console", "mcp:serve"], "env": { "MCP_TOKEN": "<token-chef>", "WSLENV": "MCP_TOKEN" } } } }
Ces fichiers sont ignorés par
.gitignoreou versionnés avec un placeholder — la valeur réelle est renseignée manuellement après clonage.
Étape 5 — Vérifier dans Claude Code
Ouvrir une session Claude Code dans le repo concerné :
cd C:/src/tlr-doc claude
Au démarrage, Claude Code détecte .mcp.json et lance mcp:serve en sous-processus. Pour vérifier :
- Demander : « Quels outils MCP tu as ? » — doit lister
list_docs,read_doc,search_docs. - Test fonctionnel : « Cherche dans la documentation ce qui concerne le MCP. » — doit déclencher
search_docset retourner des passages avec scores et chemins de fichiers.
Étape 6 — Confirmer en BDD
-- Voir les clients créés SELECT id, scopes, revoked, expires_at FROM mcp_api_client; -- Voir les premiers appels d'audit SELECT tool_name, status, error_code, timestamp FROM mcp_tool_audit_log ORDER BY timestamp DESC LIMIT 10;
Un appel search_docs réussi apparaît avec status = 'success' et error_code = NULL.
Seed depuis le VPS (prod / HTTP Streamable)
En production, le MCP tourne en transport HTTP Streamable (V1.1, TLR-006). Le seed se fait directement sur le VPS via SSH, pas via WSL.
ssh telaria-vps cd /var/www/telaria-fr php bin/console app:mcp:seed \ --tenant="telaria-fr" \ --project="tlt-doc" \ --root="/var/www/telaria-fr/docs" \ --scopes="tool:list_docs,tool:read_doc,tool:search_docs,project:telaria-doc"
Paramètres
| Paramètre | Description | Exemple |
|---|---|---|
--tenant |
Identifiant du locataire — correspond à l'app déployée | telaria-fr |
--project |
Slug du projet en base (slug court, lisible) | tlt-doc |
--root |
Chemin absolu des fichiers Markdown sur le VPS | /var/www/telaria-fr/docs |
--scopes |
Liste de scopes séparés par virgule — contrôle les accès | voir ci-dessous |
Scopes disponibles
| Scope | Effet |
|---|---|
tool:list_docs |
Autorise l'outil list_docs |
tool:read_doc |
Autorise l'outil read_doc |
tool:search_docs |
Autorise l'outil search_docs (RAG) |
project:<slug> |
Restreint au projet <slug> — obligatoire pour éviter FORBIDDEN_PROJECT |
Le scope
project:doit correspondre exactement à ce que le serveur MCP attend (vérifié à chaque appel). Si le projet a été renommé, l'ancien token est invalide — re-seeder avec le nouveau scope.
Comportement du seed
- Tenant existant → réutilisé tel quel
- Projet existant → root mis à jour si différent
- ApiClient → toujours créé (un nouvel ID à chaque seed) — permet d'émettre plusieurs tokens pour le même projet
- Token → affiché une seule fois dans le terminal ; stocker immédiatement dans
.mcp.json
.mcp.json côté client (transport HTTP)
Le transport HTTP Streamable ne passe pas par wsl + mcp:serve. La config pointe directement l'URL du serveur :
{ "mcpServers": { "telaria": { "type": "http", "url": "https://mcp.telaria.dev/mcp", "env": { "MCP_TOKEN": "<token-obtenu-au-seed>" } } } }
WSLENVn'est pas nécessaire en transport HTTP (pas de frontière Windows→WSL).
Dépannage rapide
| SymptĂ´me | Cause probable | Action |
|---|---|---|
mcp:serve ne démarre pas |
Dépendance manquante ou BDD inaccessible | Vérifier .env.local, BDD up, composer install |
AUTH_REQUIRED Ă chaque appel |
MCP_TOKEN absent ou mal recopié dans .mcp.json |
Vérifier la valeur (le token brut, pas le hash) |
FORBIDDEN_PROJECT |
Scope project:<slug> absent au seed |
Re-seed avec les bons scopes |
tools/list renvoie 0 outil |
Tags Symfony manquants (bug DI) | Vérifier ContainerWiringTest — cf. v0.1.3 |
| Le serveur ne se connecte pas dans Claude Code | wsl introuvable ou PHP absent dans WSL |
Vérifier wsl --status en PowerShell et which php dans WSL |
AUTH_REQUIRED malgré un token valide |
WSLENV=MCP_TOKEN absent dans env |
L'ajouter — sans lui la variable ne traverse pas la frontière Windows→WSL |
Pour aller plus loin
- Gouvernance tokens/scopes : mcp-gouvernance-instances.md
- Tuto Claude Code CLI : brancher-mcp-claude-code.md
- Déploiement VPS (V1.1) : mcp-vps.md