Articles
Pourquoi nous avons construit un serveur MCP natif pour les rétrospectives

Kelly Lewandowski
Dernière mise à jour 19/05/20267 min de lecture
"Natif" ne veut pas dire "code différent"
/api/v1/ que n'importe qui détenant un token d'accès personnel peut appeler directement. Les mêmes handlers, les mêmes schémas Zod, les mêmes vérifications de permission. Si nous changeons une règle dans l'un, l'autre suit.Décision 1 : moins d'outils, avec des bascules au lieu de paires
retro_create_reaction et un retro_delete_reaction, à l'image de nos routes REST qui séparent la création de la suppression. Deux outils par réaction emoji. Multipliez ça par les items et les commentaires et vous dépensez de vrais tokens en bruit avant même que le modèle n'ait fait quoi que ce soit d'utile.retro_toggle_reaction est un outil unique qui active ou désactive un emoji selon que l'appelant a déjà réagi ou non. Il renvoie "added" ou "removed" dans la réponse, pour que le modèle puisse raconter ce qui s'est passé sans avoir à stocker des identifiants de réaction dont il n'aurait besoin que pour appeler delete.Décision 2 : glisser les indices dans les descriptions, pas dans la doc
userId et un kudoType et renvoyait une erreur sympathique si vous passiez quelqu'un qui n'était pas dans l'espace. Les modèles inventaient systématiquement un identifiant utilisateur, touchaient l'erreur, s'excusaient et demandaient à l'utilisateur de coller le bon identifiant. Inutile.retro_create_item s'il n'y en
a pas). Le destinataire doit être membre de l'espace de la rétrospective —
utilisez organization_list_users (qui supporte un filtre de
recherche) pour retrouver l'identifiant utilisateur par son nom.organization_list_users avec le nom que l'utilisateur a dit à voix haute, récupère l'identifiant et donne les kudos d'un coup. Le handler n'a pas changé. L'indice, oui.
retro_update prévient dans sa description que supprimer une colonne supprime aussi tous les items qu'elle contient. retro_cast_item_vote mentionne explicitement le plafond de votes par tableau et par colonne, pour que le modèle puisse alerter l'utilisateur avant de se prendre le 400. Chaque "il faut savoir ceci pour m'appeler correctement" passe dans l'outil, pas dans un guide séparé que personne ne lit.Décision 3 : un outil de recherche sémantique, pas une chaîne lister-puis-filtrer
retro_list, puis retro_list_items pour chaque résultat, puis charge tout en contexte. C'est une tempête d'appels d'outils qui coûte de l'argent à l'utilisateur et produit une réponse pire que celle de grep.search qui lance une recherche sémantique sur tout l'espace en une fois. Il renvoie items de rétrospective, commentaires, action items, réponses de standup, réponses de sondage, réponses de brise-glace et notes, classés par similarité cosinus avec la requête, regroupés par type. Le modèle obtient les 20 résultats pertinents en un appel au lieu de s'éparpiller sur des centaines d'enregistrements.Décision 4 : consentement par fonctionnalité au moment de l'OAuth
Ce que ça donne au tableau de rétrospective
Préremplir le tableau
"Ouvre la rétrospective de ce sprint et ajoute des items à partir des postmortems qu'on a écrits dans Linear ces deux dernières semaines, un par incident, dans la colonne What Could Improve." Le modèle crée les items, les marque comme anonymes là où le ticket source l'était, et s'arrête. Retrouver du contexte dans d'anciennes rétrospectives
"On a déjà parlé de l'instabilité de la CI ?" La recherche sémantique renvoie les trois rétrospectives où le sujet est ressorti et les action items qui en ont découlé, en un seul appel. Transformer la discussion en action items
"Fais des action items à partir des trois items les plus votés du tableau, assigne-les à la personne qui les a écrits, échéance vendredi." retro_list_itemspuis quelques appels àaction_item_create. Le modèle fait l'assignation depuis l'auteur de l'item.Donner des kudos par leur nom
"Donne des kudos à Priya pour avoir débloqué la migration." Le modèle appelle organization_list_usersavec une recherche sur "Priya", puis rattache les kudos.
Ce qu'on referait, ce qu'on éviterait
retro_get. Les modèles ont alors résumé le résumé, et la latence a triplé. L'ennuyeux a gagné. L'outil MCP renvoie la même forme que l'endpoint REST. L'IA par-dessus, c'est à l'utilisateur de la déclencher via prompt, pas à nous de la cuire dans le protocole./api/v1/. Le travail intéressant se trouve dans les définitions
d'outils : le nommage, le regroupement, les indices et le choix des actions à
fusionner en une seule bascule. La logique backend est partagée.retro_create_item accepte un drapeau
anonymous, et retro_create_item_comment aussi.
Quand il est activé, la réponse omet l'identifiant utilisateur de l'auteur,
comme le fait l'interface. L'anonymat est appliqué au niveau du handler, pas
dans la description.retro_update prévient que supprimer
une colonne supprime aussi tous les items qu'elle contient. On compte sur le
modèle pour le signaler à l'utilisateur avant de l'appeler, comme un
développeur lisant la doc remarquerait l'avertissement. Il n'y a pas d'étape
de confirmation séparée à l'intérieur du protocole.