Le Model Context Protocol est une manière standard de donner un ensemble d'outils à un agent IA. Vous décrivez ce que votre produit sait faire, le client de l'agent se connecte, et à partir de là l'agent appelle ces outils pendant une conversation, comme il lit un fichier ou lance une commande.
La spécification est courte, et l'implémentation n'est pas le plus difficile. Un serveur qui fonctionne, c'est un après-midi de travail. Ce qui m'a demandé un vrai travail de conception, c'est d'amener un agent à s'en servir correctement : sans deviner les identifiants, sans aller chercher ce qu'il ne faut pas, sans conclure avec aplomb qu'une sortie vide signifie qu'il n'y a pas de données.
Voici les décisions qui ont compté quand j'ai lancé le serveur MCP de BugDump. Elles valent pour tout outil de développement qui envisage d'avoir le sien.
D'abord, ce que MCP change concrètement
Sans MCP, quand on branche un agent sur votre produit, c'est l'utilisateur qui sert d'intégration. Il ouvre votre tableau de bord, trouve les données utiles, les copie et les colle dans la conversation. Chaque bout de contexte est transporté à la main, si bien que l'agent n'a jamais plus de contexte que ce que la personne accepte de copier.
Avec MCP, l'agent va chercher les données lui-même. Chez BugDump, concrètement, c'est la différence entre :
Voici un rapport de bug. [colle 200 lignes de sortie console]
et :
Regarde la tâche #42 dans BugDump et corrige-la.
Dans la deuxième version, l'agent récupère la tâche, liste ses rapports, lit la télémétrie console et réseau, rapproche la stack trace des vrais fichiers source du dépôt et propose une modification. Personne n'a ouvert le tableau de bord. L'agent a eu accès au rapport entier, et non à la partie qu'un humain a jugé bon de copier. Or choisir ce qui mérite d'être copié, c'est précisément le jugement que le débogage doit produire, pas consommer.
Voilà ce qu'on y gagne, et c'est pourquoi l'objectif de conception n'est pas « exposer l'API », mais « exposer une API dans laquelle un agent se repère sans carte ».
1. Liez la clé à un périmètre, une fois pour toutes
Ma première version avait un paramètre de projet sur chaque outil. C'était la traduction évidente de l'API REST, et c'était une erreur à deux titres.
Une erreur pour la sécurité. Une clé MCP vit dans un fichier de configuration et sert à un processus autonome. Le rayon d'impact de cette clé doit rester aussi petit que le travail le permet.
Une erreur pour l'usage. Face à un paramètre projectId sans identifiant de projet sous la main, un agent essaie de le remplir. Il devine proj_1. Il passe le nom du projet. Il invente quelque chose de plausible, reçoit une erreur et tente une autre invention. Un paramètre qu'on peut deviner sera deviné.
Une clé MCP BugDump est donc liée à un seul projet, définitivement, et aucun outil ne prend d'argument de projet. Il n'y a rien à deviner. Si un utilisateur pose une question sur un autre projet, le serveur peut seulement dire à quel projet cette clé est limitée, via un outil get_current_project qui n'existe que pour que l'agent s'oriente au lieu de spéculer.
La règle générale : tout paramètre qu'un agent ne peut pas tirer d'une réponse précédente, il finira par l'halluciner. Supprimez-le, ou donnez à l'agent un moyen de le trouver.
2. Rendez explicite la chaîne d'appels, du général au détail
Mes outils forment une séquence voulue :
list_tasks → find a task, get its taskId
get_task → read one task
list_reports_for_task → list a task's reports, get each reportId
get_report → read one report
get_report_telemetry → page through everything in that report
Chaque identifiant passé à un outil doit provenir d'une réponse précédente. Les instructions du serveur le disent en ces termes, avec l'interdiction explicite de fabriquer des identifiants.
L'échec que cela évite est subtil et coûteux. Les agents parallélisent agressivement, et la plupart du temps ils ont raison. Mais un agent qui décide de lancer des appels get_report en parallèle avant d'avoir le moindre identifiant de rapport va les fabriquer, recevoir sept erreurs et brûler une bonne partie de son contexte à s'en remettre. L'instruction qui règle le problème est celle qui dit que les appels en parallèle ne sont sûrs que sur des identifiants que vous détenez déjà.
3. Acceptez les identifiants que les humains utilisent vraiment
Les tâches de BugDump ont à la fois un UUID et un identifiant public affiché sous la forme #42. Les utilisateurs disent « la tâche 42 ». Personne n'a jamais dit « la tâche 9f8c1a4e-... ».
get_task accepte les deux. C'est un petit aménagement à l'effet disproportionné, parce qu'il supprime toute une catégorie de premières tentatives ratées. L'agent essaie ce que l'humain a dit, et ça marche.
Cherchez l'identifiant que vos utilisateurs tapent dans Slack. C'est celui-là qu'il faut accepter.
4. Renvoyez un résumé par défaut, mais dites ce que vous avez coupé
Un seul rapport de bug peut contenir des milliers d'entrées de console, des centaines de requêtes réseau avec leurs corps, des captures d'écran et une relecture de session. Tout renvoyer par défaut noierait le contexte de l'agent dès le premier appel et ne laisserait aucune place au vrai travail.
get_report renvoie donc par défaut un résumé compact : les entrées de console récentes et les métadonnées réseau, sans les corps.
L'essentiel tient dans la phrase suivante de la réponse. Le résumé indique ce qui a été coupé. Pas en silence : explicitement, dans le payload.
La troncature silencieuse est le pire échec possible pour qui conçoit un outil, parce qu'elle ne produit pas d'erreur. Elle produit une mauvaise réponse, donnée avec assurance. Un agent qui reçoit un journal réseau tronqué sans aucune indication de troncature dira à l'utilisateur qu'aucune requête n'a échoué. Personne ne découvre l'erreur avant bien plus tard.
C'est la même discipline que --max-count dans un outil de recherche : signalez la limite atteinte. Si votre outil plafonne quoi que ce soit, le plafond doit figurer dans la sortie.
5. Donnez à l'agent un moyen d'obtenir le reste
Un résumé n'est acceptable que si une lecture complète reste possible. C'est le rôle de get_report_telemetry : il parcourt page par page la console, le réseau avec les corps ou les actions de l'utilisateur, par tranches chronologiques, avec offset et nextOffset, et un indicateur hasMore qui passe à false quand le flux est épuisé.
Deux propriétés rendent cela exploitable par un agent, et pas seulement par un programme.
Des tranches chronologiques, pas arbitraires. Avec un tri par date, une lecture partielle garde un sens. Un agent qui récupère les deux premières pages a le début de l'histoire, pas un échantillon pris au hasard.
Une condition d'arrêt explicite. hasMore: false est un fait sur lequel l'agent peut s'appuyer. « Le tableau est revenu plus court que la limite » est une déduction, et c'est sur les déductions, au bout de longues boucles d'appels, que les agents se mettent à improviser.
6. Écrivez les instructions pour l'agent, pas pour l'utilisateur
Un serveur MCP fournit un bloc d'instructions qui entre dans le contexte de l'agent. On est tenté d'y mettre du texte marketing. Cet espace sert bien mieux à écrire ce qu'on ne peut pas déduire des schémas des outils :
L'ordre dans lequel appeler les outils
L'interdiction d'inventer des identifiants
Les appels qu'on peut paralléliser, et ceux qu'on ne peut pas
Ce que « le résumé n'a rien montré » veut dire, et ce que ça ne veut pas dire
Ce dernier point mérite sa place. Mes instructions disent en substance : la réponse résumée indique ce qui a été coupé, ne supposez donc pas que « le résumé ne montre rien » signifie « il n'y a rien ». Cette seule phrase évite une conclusion erronée bien précise, que j'ai vu des agents tirer.
Traitez ce bloc comme une note pour un collègue compétent qui arrive en cours de tâche. Les signatures de types, il sait les lire. Ce qui lui manque, c'est ce qu'on n'apprend qu'en se trompant.
7. La lecture seule est une fonctionnalité
Le serveur MCP de BugDump expose sept outils, et les sept ne font que lire. Aucun ne crée de tâche, n'en ferme ni ne publie de commentaire.
C'était un choix réfléchi, pas un travail inachevé. Le workflow que permet le serveur, c'est l'enquête : rassembler les preuves, les rapprocher du code, proposer un correctif. Le volet écriture du workflow (décider qu'un bug est réel, que c'est un doublon, qu'il est réglé) est celui où le jugement humain fait le vrai travail.
Il y a aussi un argument plus simple. Une clé en lecture seule qui fuit pose un problème de divulgation. Une clé en lecture-écriture qui fuit, entre les mains d'un processus autonome, pose un problème d'intégrité des données. Entre les deux, et comme le workflow que je visais n'avait pas besoin d'écriture, la décision s'est prise toute seule.
Commencez en lecture seule. Ajoutez l'écriture quand un workflow l'exige, et donnez à ces clés leur propre périmètre.
La condition préalable qui dérange
Sous tout cela se trouve une condition qui n'a rien à voir avec la conception du protocole.
Un agent ne peut pas poser de question complémentaire. Il ne peut pas écrire à la personne qui a signalé le bug pour lui demander quel navigateur elle utilisait. Il n'a droit qu'à un seul essai avec les preuves disponibles, et si elles sont minces, il produira une réponse fluide, bien structurée et entièrement spéculative.
La valeur d'un serveur MCP est donc plafonnée par la qualité des données qui se trouvent derrière. Le mien fonctionne parce qu'un rapport BugDump contient déjà la console, le journal réseau, la relecture de session, les actions de l'utilisateur et tout l'environnement, capturés automatiquement au moment où le bug s'est produit. Le protocole ne fait que les transporter.
Si vous envisagez un serveur MCP pour votre propre outil, c'est la première question à trancher : les données qui sont derrière sont-elles assez complètes pour agir sans poser de question complémentaire ? Si oui, MCP est une couche fine qui vaut l'effort. Sinon, le protocole ne fera que rendre les trous plus faciles à atteindre.
Pour aller plus loin
Pourquoi les agents IA ont besoin de jetons personnels sur un serveur MCP — pourquoi une clé partagée ne suffit plus dès qu'un agent peut déplacer des tâches et écrire des commentaires.
Pourquoi votre agent IA fait 40 appels pour répondre à une seule question — le problème N+1, passé de l'ORM au serveur MCP, et les trois questions qui le règlent.
Déboguer les rapports de bug avec Claude Code et le serveur MCP de BugDump — comment un assistant IA lit la console, le réseau et la relecture d'un rapport pour trouver le bug dans votre code.