Isi-APP Docs fonctionnelles
Toutes les docs
Markdown brut
Connecteur MCP — ISI-APP dans un client Claude
Brouillon ai functional Revu le 2026-10-01 ai/mcp-server.md

Connecteur MCP — ISI-APP dans un client Claude

À quoi ça sert

ISI-APP expose un serveur MCP (« connecteur Claude ») : un client MCP externe — Claude Code dans un terminal, Claude Desktop — peut interroger directement les projets, sprints, backlogs et tâches de l'application, en langage naturel, sans ouvrir l'application.

Ce n'est pas un nouveau moteur d'IA ni une nouvelle logique métier. Les outils interrogés sont exactement ceux du tool-calling déjà utilisés par le chat IA interne (packs core et project, cf. ai-tool-calling-lot-bc.md) : le connecteur n'est qu'un second chemin d'accès à ces mêmes outils, pour un client qui n'est pas le chat d'ISI-APP.

Cas d'usage visé : un chef de projet ou un développeur qui travaille déjà dans Claude et veut poser une question sur l'état d'un projet sans changer d'outil.

Ce qu'il peut écrire, et ce qu'il ne peut pas

Le connecteur lit, et il sait créer et modifier des backlogs, créer et modifier des étapes, charger des mairies prospectes dans le CRM, et — pour les release notes client — générer un brouillon, le modifier, et gérer ses catégories (création, modification, suppression). Il permet aussi de saisir, corriger et supprimer vos propres temps (voir Saisir ses temps plus bas). Chaque outil d'écriture n'agit que sous confirmation explicite (voir plus bas). Tout le reste est hors de sa portée : les tâches, les tickets liés, les clients liés, les charges, et la suppression d'une release note elle-même, qui reste dans l'application.

Prospects CRM. crm_prospects_import charge un lot de 50 mairies au plus, avec leur DGS quand il est connu : chaque ligne est rapprochée d'une fiche existante (SIRET, SIREN, puis nom et département), l'aperçu détaille création ou avant/après, et la confirmation écrit tout le lot ou rien. Il faut le module CRM et les droits de création et de modification des fiches. Détail : Import de prospects.

Release notes client. Six outils, réservés aux comptes ISI-admin (indépendamment de tout module souscrit) :

  • release_notes — lecture seule, sans confirmation : liste les release notes (brouillons compris) et rend la taxonomie des catégories avec leurs id. C'est le seul moyen de retrouver les identifiants attendus par les cinq outils suivants.
  • release_note_create — génère puis crée une release note à partir d'un changelog technique : l'IA catégorise chaque entrée en réutilisant une catégorie existante par son nom exact, ou en proposant une nouvelle catégorie sans jamais la créer d'elle-même. La génération IA a lieu dès le premier appel, donc l'aperçu montre déjà le résultat définitif.
  • release_note_update — modifie une release note existante : sa version, sa date, et ses items (texte, type, catégories, ajout, suppression, réordonnancement). Une catégorie inconnue est refusée, jamais créée à la volée — c'est release_note_category_create qui s'en charge.
  • release_note_category_create / release_note_category_update — créent et modifient une catégorie (nom, couleur, icône). Le nom doit rester unique, insensible à la casse et aux accents.
  • release_note_category_delete — supprime définitivement une catégorie : l'aperçu annonce combien d'items en perdent le rattachement, et combien appartiennent à une release note déjà publiée. Suppression dure (la table n'a pas de colonne de suppression logique) : c'est le seul outil du connecteur qui détruit des données, et le seul dont le client MCP est prévenu par un destructiveHint à part.

Toutes les release notes créées le sont toujours en brouillon (blactive = false), et release_note_update ne porte aucun paramètre pour publier : la publication reste un geste manuel dans l'admin, après relecture humaine. Voir La confirmation en deux temps plus bas.

L'outil de migration de backlogs entre sprints (migrate_sprint_backlogs), qui existe dans le pack project du chat IA, est volontairement exclu : le connecteur expose une liste d'outils nommés un par un, jamais un pack entier.

La confirmation en deux temps

Un client MCP n'a pas d'écran pour afficher un bouton « Confirmer ». Le cycle est donc porté par le protocole :

  1. Claude appelle l'outil sans jeton : rien n'est écrit. Il reçoit l'avant/après champ par champ, et la liste des répercussions.
  2. Il vous les présente, et attend votre accord.
  3. Il rappelle l'outil avec le jeton reçu — et la modification appliquée est celle qui vous a été montrée, pas celle des paramètres du second appel.

Le jeton ne sert qu'une fois, expire au bout de 5 minutes, n'est valable que pour son porteur, et devient caduc si le backlog a changé entre-temps : dans ce cas Claude doit refaire un aperçu, parce que l'avant/après que vous avez validé ne décrit plus la réalité.

La limite honnête de ce dispositif. Rien, côté serveur, ne peut contraindre Claude à vous montrer l'aperçu avant de confirmer : c'est une consigne, doublée du fait que les outils s'annoncent au client comme modifiants, ce qui déclenche sa demande d'autorisation. Si vous lancez votre client en mode permissions permissives, ou que vous autorisez l'outil de façon permanente, l'enchaînement peut se faire sans que vous voyiez l'aperçu. Le protocole MCP n'offre pas aujourd'hui de moyen de rendre cette étape contraignante côté serveur.

Saisir ses temps

À quoi ça sert. Déclarer sa journée sans quitter Claude Code. Le cas visé est celui du développeur qui, en fin de journée, dit ce qu'il a fait : le travail sur le sprint s'impute sur la mission « Évolutions / Sprints » (libellé habituel « Dev »), la revue de PR sur la mission « Tests » (libellé habituel « PR »). Claude retrouve la mission, propose la saisie, et n'écrit qu'après votre accord.

Quatre outils, ouverts à tout compte disposant du module CRM (B2B) :

  • my_times — lecture seule : vos temps jour par jour sur une période (par défaut, du lundi de la semaine courante à aujourd'hui), avec le total de chaque jour et la liste des jours manquants (jours ouvrés, week-ends et jours fériés exclus, dont le total est inférieur à une journée). Chaque temps indique s'il est modifiable ou supprimable.
  • my_time_create — déclare un ou plusieurs temps (jusqu'à 20 d'un coup, par exemple une quinzaine entière en une seule confirmation). Tout le lot passe, ou rien.
  • my_time_update — corrige un de vos temps : date, période, horaires, mission, libellé, catégorie, lieu, description.
  • my_time_delete — supprime un de vos temps.

Pour retrouver la bonne mission, Claude s'appuie sur la liste des missions que vous pouvez imputer (time_missions_list, déjà utilisée par le chat IA) ; il ne devine jamais un identifiant.

Journée ou demi-journée. Chaque temps porte une période :

  • day — une journée entière (1 jour), sans horaires ;
  • morning / afternoon — une demi-journée (0,5 jour) avec horaires, par défaut 08:00–12:30 le matin et 13:30–17:00 l'après-midi. Vous pouvez les modifier à la demande (« matin de 9h à 12h ») ; un début postérieur ou égal à la fin est refusé, et on ne précise pas d'horaires sur une journée entière.

Ce que Claude complète à votre place, comme le fait le formulaire de saisie : la catégorie et le libellé de votre dernier temps sur la même mission (à défaut, le libellé de la mission ; la catégorie est alors à préciser), le lieu (celui d'un autre temps du même jour, sinon le bureau — Claude vous le demande si vous ne l'avez pas précisé), et le tarif jour, qui n'est pas modifiable mais figure dans l'aperçu. Un temps créé est toujours programmé.

Exemples de phrases.

  • « Quels jours me manque-t-il du temps cette semaine ? »
  • « Déclare ma journée d'hier sur Évolutions / Sprints. »
  • « Mets lundi, mardi et mercredi en journée sur le sprint, et jeudi matin en revue de PR. »
  • « Ajoute demain après-midi sur la mission Tests, libellé "PR", de 14h à 17h. »
  • « Décale mon temps de jeudi matin au vendredi. »
  • « Supprime le temps que j'ai saisi deux fois lundi. »

Le cycle aperçu → confirmation est celui des autres outils d'écriture (voir La confirmation en deux temps). L'aperçu liste chaque temps tel qu'il sera enregistré (date, période, horaires, mission, libellé, catégorie, lieu, tarif) et les points d'attention : une date un week-end ou un jour férié, ou hors des dates de la mission, est signalée mais pas refusée. Si le temps a changé entre l'aperçu et la confirmation, la confirmation est refusée et Claude refait un aperçu.

Les limites.

  • Vos temps uniquement. Vous ne pouvez ni voir, ni modifier, ni supprimer ceux d'un collègue ; un temps qui n'est pas le vôtre est traité comme introuvable.
  • Pas d'absences. Congés, RTT et autres catégories d'absence déclenchent une validation par le manager dans l'application : ils se saisissent là-bas. Une mission clôturée, ou sur laquelle vous n'êtes pas affecté, est refusée.
  • Pas de synchronisation Outlook. Un temps créé depuis le connecteur n'est pas poussé dans votre calendrier, et un temps déjà lié à un événement Outlook ne peut être ni modifié ni supprimé ici : passez par l'application.
  • Un jour ne dépasse pas une journée déclarée. Si le total du jour, avec la saisie demandée, dépasse 1, elle est refusée et Claude vous montre les temps déjà présents ce jour-là. Deux demi-journées dont les horaires se chevauchent sont également refusées.
  • L'état n'est jamais modifiable depuis le connecteur (programmé, réalisé, validé) : il suit son cycle dans l'application.
  • Un temps validé n'est pas modifiable, et seul un temps programmé peut être supprimé — mêmes règles que dans l'application. La suppression est définitive (la table n'a pas de suppression logique) ; les totaux de la mission sont recalculés.

Ce qu'on peut demander

Trente outils sont exposés : le contexte de l'utilisateur (me), la résolution d'un nom en identifiant (resolve), les projets (projects), les tâches de projet (project_tasks), les backlogs (backlogs), le texte intégral d'un backlog (backlog_description_get), les sous-tâches de checklist (backlog_tasks), quatre outils d'écriture sur les backlogs et les étapes — création (backlog_create, sprint_create) et modification (backlog_update, sprint_update) —, six outils sur les tickets support : la fiche (tickets), la demande intégrale (ticket_description_get), les échanges avec le client et les commentaires internes (ticket_messages_get), l'inventaire des pièces jointes (ticket_attachments_get), l'historique (ticket_history_get) et les sujets (ticket_subjects_list) —, et six outils sur les release notes client, réservés aux comptes ISI-admin : la lecture (release_notes), la génération d'un brouillon (release_note_create), sa modification (release_note_update), et la gestion des catégories (release_note_category_create, release_note_category_update, release_note_category_delete) —, et deux outils sur les journaux d'erreurs applicatives, réservés eux aussi aux comptes ISI-admin : l'agrégat par signature (error_logs_summary, ce qui casse le plus sur une période) et la consultation détaillée (error_logs, listing ou fiche d'une ligne) —, et, pour vos temps, la consultation de la semaine (my_times), la liste des missions imputables (time_missions_list) et trois outils d'écriture : my_time_create, my_time_update, my_time_delete.

Concrètement, cela permet des questions du type :

  • « Où en est mon sprint en cours ? » — me renvoie directement vos sprints en cours avec leur identifiant, Claude enchaîne sur backlogs filtré sur ce sprint et fait la synthèse par statut.
  • « Donne-moi tout le contexte du ticket 71958 avant qu'on le corrige. » — la fiche, la demande, les échanges avec le client, les commentaires internes et l'inventaire des pièces jointes. De quoi lancer une correction en connaissant le dossier.

Sur les pièces jointes. Claude obtient leurs métadonnées — nom, type, taille, auteur, URL — jamais leur contenu. Une capture d'écran citée dans un échange ne lui est donc pas lisible : il est instruit de te demander ce qu'elle montre plutôt que de le supposer.

  • « Quels backlogs sont bloqués sur le projet Alpha ? » — resolve retrouve l'identifiant du projet à partir de son nom, puis backlogs filtre sur le statut Bloqu.
  • « Détaille-moi le backlog des imprimantes OCS. » — backlogs en mode détail rend la fiche : la demande elle-même, la proposition technique, le demandeur, les charges estimées et réelles, la branche git, les tickets liés.
  • « Liste mes tâches en retard, projet par projet. » — project_tasks avec le filtre « mes tâches », qui couvre aussi les tâches que vous avez créées sans les affecter.
  • « Qui porte quoi sur le projet Alpha ? » — un backlog peut avoir plusieurs assignés ; la réponse rend tous les noms et leurs identifiants, pour que le regroupement par personne soit fiable même en cas d'homonymes.
  • « Quels jours me manque-t-il du temps cette semaine ? » — my_times rend la semaine jour par jour et liste les jours incomplets ; Claude propose ensuite la saisie.
  • « Qu'est-ce qui plante le plus cette semaine ? » — error_logs_summary renvoie les signatures d'erreur (classe + fichier + ligne) triées par nombre d'occurrences, avec la sévérité maximale observée ; Claude enchaîne sur error_logs pour la fiche complète d'une occurrence, avant d'aller lire le code concerné.

Les listes sont paginées : Claude est instruit de parcourir les pages plutôt que de conclure sur la première. Depuis le connecteur, il peut demander jusqu'à 50 résultats par appel — lire un projet entier par pages de 10 coûtait 139 allers-retours, contre 28. Le chat IA d'ISI-APP conserve ses pages de 10.

Les champs de texte riche (la demande, la proposition) sont mis au texte brut — ils sont saisis dans un éditeur WYSIWYG et la moitié d'entre eux contient du HTML — puis tronqués à 4 000 caractères, ce qui rend environ 99 % des backlogs en entier. Au-delà, la réponse porte request_truncated: true et Claude enchaîne sur backlog_description_get pour le texte complet.

Mise en route

1. Obtenir un jeton

Un jeton personnel est nécessaire ; il vaut « agir en tant que cet utilisateur, sur les outils du connecteur ». Deux façons de l'obtenir.

Depuis l'écran d'administration — le plus simple, et la voie recommandée : Administration → onglet Actions → Jetons MCP, ou directement /admin/mcp-tokens.

L'écran liste les comptes autorisés — profil 1 de l'entité ISI, une dizaine aujourd'hui — avec leurs jetons, leur dernier usage et leur expiration. Un bouton par compte émet un jeton ; un bouton par jeton le révoque, après confirmation.

Après l'émission, l'écran affiche une seule fois le jeton et la commande complète à coller dans le terminal de son porteur, jeton compris. Le clair n'existe qu'à cet instant : la base n'en garde qu'une empreinte, et quitter l'écran le perd définitivement. À transmettre par un canal sûr, jamais par e-mail en clair.

En ligne de commande, côté serveur, si tu n'as pas accès à l'écran :

php artisan isi:mcp:token prenom.nom@exemple.fr

Options utiles : --days=0 pour un jeton sans expiration (90 jours par défaut), --list pour lister ses jetons, --revoke=<id> pour en révoquer un. Lister et révoquer restent possibles même pour un compte devenu inéligible — c'est justement le moment où l'on en a besoin.

Les deux voies partagent la même logique, donc les mêmes règles : un compte hors profil 1 de l'entité ISI se voit refuser l'émission, et le jeton ne porte que la capacité du connecteur.

2. Brancher son client

Le client local lance le serveur en stdio — un processus dédié, piloté par le client :

{
    "mcpServers": {
        "isi-app": {
            "command": "php",
            "args": ["/chemin/vers/isi-app/artisan", "isi:mcp:serve"],
            "env": {
                "ISI_MCP_TOKEN": "COLLER_ICI_LE_JETON"
            }
        }
    }
}

Un modèle est fourni à la racine du dépôt dans .mcp.json.example.

3. Choisir le transport

Transport Comment Quand le choisir
stdio php artisan isi:mcp:serve, jeton dans ISI_MCP_TOKEN Poste de dev, client local ayant accès au code et à la base. C'est le cas courant.
HTTP POST /mcp, jeton en en-tête Authorization: Bearer … Client distant qui ne peut pas exécuter l'application (client hébergé, poste sans accès au serveur).

Les deux transports servent le même serveur : mêmes outils, mêmes droits. Seule l'origine de l'identité change.

Règles d'accès

  • Réservé à l'équipe de développement ISI. Le temps de la mise au point, seuls les comptes de profil 1 de l'entité ISI peuvent ouvrir une session ou se faire émettre un jeton. Un compte 1 chez un client ne passe pas : la condition porte sur l'entité et le profil. La commande de jeton refuse d'en émettre pour tout autre compte, et le message d'erreur ne dit pas pourquoi — les autres comptes n'ont pas à découvrir l'existence du connecteur. Un seul réglage (mcp.isi_admins_only) l'ouvrira le jour où ce sera décidé.
  • Vous ne voyez que votre propre périmètre. L'acteur est toujours l'utilisateur propriétaire du jeton : le client ne peut pas demander à agir pour quelqu'un d'autre. Exception : les deux outils de journaux d'erreurs (error_logs, error_logs_summary) sont une vue plateforme et couvrent toutes les entités — pas seulement la vôtre. C'est volontaire (diagnostiquer une régression qui touche plusieurs clients), et sans risque supplémentaire : le connecteur est déjà réservé à l'équipe ISI.
  • L'entité et les droits s'appliquent normalement. Le connecteur rejoue l'ACL de l'application : filtrage multi-entités, projets confidentiels (blsecret), ACL ressources. Ce que votre profil ne vous montre pas dans ISI-APP, il ne le montre pas ici.
  • Les modules souscrits filtrent les outils. Une personne dont l'entité n'a pas le module projet obtient un connecteur sans aucun outil projet — pas un outil qui échoue, un outil qui n'existe pas pour elle. Il ne reste alors que me et resolve.
  • La liste d'outils est calculée à chaque connexion. Deux personnes branchées sur le même serveur ne voient donc pas forcément les mêmes outils.
  • Le jeton ne vaut que pour ce connecteur : il porte la seule capacité mcp:read et ne sert pas de jeton d'API générique.

Points d'attention

  • Un jeton = un utilisateur réel, en lecture, sur tout son périmètre. Un jeton fuité donne accès aux projets et backlogs visibles par cette personne : le révoquer (--revoke) est la seule réponse.
  • Entité de rattachement. La session ouverte par le connecteur retient l'entité du profil favori de l'utilisateur, comme un login normal. Il n'y a pas de moyen de changer d'entité depuis le client MCP ; pour interroger une autre entité, il faut basculer son profil favori dans l'application.
  • Une absence de résultat n'est pas une absence de donnée : ce peut être un défaut de droits. Le connecteur transmet cette consigne au modèle, mais la nuance mérite d'être gardée en tête quand une réponse paraît trop vide.
  • Statuts terminés. Valid et Real valent « terminé » : ils ne doivent pas être comptés comme du reste à faire. Cette sémantique est fournie au modèle avec la liste d'outils.
  • Un jeton ne s'affiche qu'une fois. Ni l'écran ni la commande ne peuvent le réafficher : la base n'en conserve qu'une empreinte. S'il est perdu, il faut le révoquer et en émettre un autre.
  • Le mode assistance n'est pas couvert : un assistant ISI qui impersonne un client dans l'application ne peut pas le faire via le connecteur — le jeton désigne toujours son propriétaire.

Ce qui est prévu ensuite

La suppression reste hors périmètre pour les backlogs, les étapes et les release notes elles-mêmes (les temps programmés de l'utilisateur, eux, sont supprimables), et le restera sans décision explicite : elle est irréversible côté backlog (la table n'a pas de suppression logique) et l'application la gère bien. Seule exception, délibérée : les catégories de release note (release_note_category_delete), dont la suppression est déjà dure côté application — le connecteur ne fait qu'exposer un geste déjà sans filet, sous confirmation explicite et un destructiveHint dédié.

Les autres pistes non engagées : élargir l'écriture aux tâches et aux liens (tickets, clients), une capacité de jeton distincte pour la lecture et l'écriture (aujourd'hui un seul mcp:read ouvre les deux), et l'ouverture du connecteur au-delà de l'équipe de développement.

Autres pistes non engagées : élargissement à d'autres domaines déjà couverts par des packs d'outils (contrats), la saisie des absences et la synchronisation Outlook des temps depuis le connecteur.

Voir aussi