02-ce-que-je-construis/specs/admin-mcp.md

Backoffice MCP — administration des clients et audit

Contexte : le serveur MCP (tlr-mcp) est opérationnel. Les tokens sont émis en CLI (app:mcp:seed) mais leur gestion quotidienne (voir qui est actif, révoquer, consulter l'activité) passe par du SQL brut — ce n'est pas tenable. Cette spec couvre la page d'administration qui résout ce problème.


1. Périmètre

Dans la spec :

  • Liste des clients MCP actifs/rĂ©voquĂ©s avec leurs scopes et leur dernière activitĂ©
  • RĂ©vocation et restauration d'un client en un clic
  • Log d'audit paginĂ© des appels outils

Hors de la spec :

  • CrĂ©ation de token via BO — reste CLI (app:mcp:seed) ; le token brut ne peut ĂŞtre affichĂ© qu'une fois et de façon sĂ©curisĂ©e, le terminal est le bon endroit pour ça
  • Modification des scopes d'un client existant — cas rare, SQL direct acceptable
  • Gestion des tenants et des projets — idem

2. Accès

  • Route parente : /admin/mcp
  • RĂ´le requis : ROLE_ADMIN
  • EntrĂ©e dans le menu admin : MCP (sous-section IA ou section dĂ©diĂ©e selon l'organisation du menu existant)

3. Vue principale — /admin/mcp

Page unique avec deux blocs verticaux : Clients en haut, Audit en bas.

3.1 Bloc Clients

Tableau listant tous les ApiClient du tenant courant.

Colonne Source Détail
ID mcp_api_client.id Référence interne
Scopes mcp_api_client.scopes Affichés en badges, un par scope
Statut mcp_api_client.revoked Badge Actif (vert) ou Révoqué (rouge)
Expiration mcp_api_client.expires_at Date ou « Aucune »
Dernier appel MAX(mcp_tool_audit_log.timestamp) WHERE api_client_id Date relative (ex. « il y a 2h ») ou « Jamais »
Actions — Bouton Révoquer (si actif) ou Restaurer (si révoqué)

Tri par défaut : ID décroissant (plus récent en premier).

Pas de pagination — le nombre de clients restera faible (< 20 sur toute la durée de vie de l'écosystème).

3.2 Bloc Audit

Log des 100 derniers appels tous clients confondus.

Colonne Source Détail
Date mcp_tool_audit_log.timestamp Format YYYY-MM-DD HH:mm:ss UTC
Client mcp_tool_audit_log.api_client_id Lien vers la ligne correspondante du bloc Clients
Outil mcp_tool_audit_log.tool_name list_docs, read_doc ou search_docs
Statut mcp_tool_audit_log.status Badge success (vert), refused (orange), error (rouge)
Code erreur mcp_tool_audit_log.error_code Affiché uniquement si non null — ex. FORBIDDEN_TOOL, RATE_LIMIT

Tri : timestamp décroissant. Pas de filtre en V1 — le log brut suffit pour un usage d'audit ponctuel.


4. Actions

Révoquer un client

  • Bouton RĂ©voquer sur la ligne du client actif
  • Confirmation modale : « RĂ©voquer ce client MCP ? Les appels en cours seront rejetĂ©s immĂ©diatement. »
  • Action : POST /admin/mcp/clients/{id}/revoke
  • Effet : UPDATE mcp_api_client SET revoked = 1 WHERE id = :id
  • Retour : rechargement de la page, flash de confirmation, ligne passe en statut RĂ©voquĂ©

Restaurer un client

  • Bouton Restaurer sur la ligne d'un client rĂ©voquĂ©
  • Pas de confirmation modale (action rĂ©versible)
  • Action : POST /admin/mcp/clients/{id}/restore
  • Effet : UPDATE mcp_api_client SET revoked = 0 WHERE id = :id
  • Retour : rechargement de la page, flash de confirmation, ligne passe en statut Actif

5. Implémentation Symfony

ContrĂ´leur

src/Controller/Admin/McpController.php

Méthodes :

Méthode Route HTTP
index() /admin/mcp GET
revoke() /admin/mcp/clients/{id}/revoke POST
restore() /admin/mcp/clients/{id}/restore POST

Toutes les routes sous l'attribut #[IsGranted('ROLE_ADMIN')].

RequĂŞtes

Clients avec dernier appel :

SELECT c.id, c.scopes, c.revoked, c.expires_at,
       MAX(l.timestamp) AS last_call
FROM mcp_api_client c
LEFT JOIN mcp_tool_audit_log l ON l.api_client_id = c.id
JOIN mcp_tenant t ON c.tenant_id = t.id
WHERE t.name = 'telaria'
GROUP BY c.id
ORDER BY c.id DESC

En Doctrine, via un QueryBuilder sur ApiClientRepository avec leftJoin sur ToolAuditLog.

Audit récent :

$repo->findBy([], ['timestamp' => 'DESC'], 100)

Template

templates/admin/mcp/index.html.twig

Étend le layout admin existant. Deux sections : <section id="clients"> et <section id="audit">.


6. Ce que ça ne remplace pas

La création d'un nouveau token reste impérativement CLI :

php bin/console app:mcp:seed --tenant="telaria" --project="telaria-doc" \
  --root="C:/src/telaria-doc" \
  --scopes="tool:list_docs,tool:read_doc,tool:search_docs,project:telaria-doc"

Le BO ne peut pas afficher un token brut de façon sécurisée — le terminal est le seul endroit où ce flux est maîtrisé.


7. Évolutions possibles (hors V1)

  • Filtre par outil ou par statut dans le log d'audit
  • Pagination du log au-delĂ  de 100 entrĂ©es
  • Export CSV de l'audit
  • Affichage du projet associĂ© au client (jointure mcp_project)

Références

Assistant documentaire

Posez une question sur la documentation. Les réponses citent leurs sources — un clic ouvre le document à gauche.

Loading…
Loading the web debug toolbar…
Attempt #