Comment Link mesure
Ce fichier est la contrepartie d'un verdict publié : si nous écrivons qu'une
adresse ne répond pas, vous devez pouvoir savoir ce que nous avons envoyé, ce
que nous avons lu, et ce qui nous a fait conclure. Chaque entrée de
latest.json porte une clé sante.source qui renvoie à une section d'ici.
Il est publié à côté des données, sur le même hôte : une méthode dont l'URL ne répond pas ne vaut pas mieux que pas de méthode (#69, #93).
Trois règles qui valent pour toutes les sondes
1. Un code de retour n'est pas un verdict. Un 405 ou un 406 sur un
serveur qui attend du JSON-RPC en POST prouve qu'il répond, pas qu'il est mort.
Une première mesure faite sans cette règle annonçait 61 % de morts contre 19,9 %
réels. Un 401, 402 ou 403 est vivant mais protégé, jamais une panne. Un
5xx est ambigu : la panne peut être du jour.
2. La portée dit ce qui a été joué, pas ce qu'on espérait. Chaque contrôle
publie sante.portee :
portee | Ce qui a réellement eu lieu |
|---|---|
appel | un échange applicatif : handshake, ou requête à laquelle l'autre a répondu dans son protocole |
http | le contenu a été récupéré et analysé, sans échange applicatif |
| absente | rien au-delà d'un code de retour, ou contrôle antérieur au 24 août 2026 |
Un code de retour seul ne vaut jamais http. Le parsing réel du contenu est
la seule chose qui compte comme lecture.
3. Nous ne recopions jamais ce qu'un tiers affirme. Une version qu'un
registre publie pour un serveur, un status qu'un index affiche pour un agent :
ce sont des affirmations, pas des mesures. Nous les lisons chez l'intéressé
ou nous ne les publions pas. Mesuré : 94,4 % des serveurs MCP qui passaient pour
« à jour » ne faisaient que renvoyer la version qu'on leur demandait.
Et une réserve permanente : nos sondes partent d'un centre de données, sur
une seule adresse IP. Un 403 peut être une protection légitime comme un filtre
anti-robot. Nous ne le comptons jamais en panne, et nous le disons.
sonde : serveurs MCP
Ce qu'on envoie. Un POST JSON-RPC 2.0 initialize, en annonçant la version
courante de la spécification, avec l'en-tête MCP-Protocol-Version. Puis
notifications/initialized, puis tools/list.
Ce qu'on lit. La version que le serveur négocie dans sa réponse, et
c'est elle qu'on rejoue dans les requêtes suivantes, jamais celle qu'on avait
demandée. Insister sur la version courante fait échouer 45 % des serveurs avec
des messages trompeurs. La réponse est acceptée en JSON ou en SSE, sans se
fier au Content-Type.
Ce qui fait conclure. Une enveloppe JSON-RPC 2.0 conforme et une version
relue valent appel. Un corps lu mais non négociable s'arrête à http. Aucune
réponse (DNS mort, connexion refusée, délai dépassé) vaut mort.
Réserve publiée avec le chiffre. La version annoncée par un serveur n'est pas une preuve qu'il la connaît : voir la règle 3. Le taux de spécifications périmées que nous publions est un plancher, jamais une surestimation.
Un certificat expiré n'est pas une absence : le serveur répond encore, et c'est « ça répond » que nous mesurons.
sonde-registre : registres shadcn
Ce qu'on envoie. Un GET sur le registry.json du registre, à l'adresse
dérivée du gabarit d'item que l'index publie, la seule adresse que l'index
donne comme servie par le registre.
Ce qui fait conclure. Le parsing réel et la présence d'une liste items.
Ni la taille, ni l'absence d'erreur réseau, ni le Content-Type : un
registry.json parfaitement valide est servi en text/plain par
raw.githubusercontent.com, et exiger application/json tuait trois registres
vivants.
Le piège que ça évite. Un chemin inexistant ne rend pas toujours 404 :
Vercel, Netlify et tout site à page unique rendent 200 et des dizaines de
kilo-octets de page d'accueil. Sans parsing, un registre absent passerait pour
vivant.
Si le chemin dérivé rend 404, deux chemins de secours sont essayés avant de
conclure : un 404 peut prouver que notre chemin est faux, pas que le registre
est tombé.
Le plafond appel est inatteignable ici par construction, et la
documentation de shadcn le dit : « There is no configuration or capability
negotiation required. »
sonde-a2a : agents A2A
Ce qu'on lit d'abord. La carte de l'agent, chez l'agent, au chemin
conventionnel /.well-known/agent-card.json. C'est la seule origine acceptable
de la version que nous publions, le registre en publie une autre, que personne
n'a vérifiée, et les deux diffèrent pour 12 agents sur 134 comparables.
Ce qu'on envoie. Une lecture de tâche JSON-RPC 2.0 (tasks/get, ou
GetTask selon la version que l'agent revendique) sur un identifiant de tâche
qui n'existe pas, avec l'en-tête A2A-Version portant la version que l'agent a
déclarée. Aucun message n'est envoyé, aucune tâche n'est créée, aucun jeton
n'est consommé chez vous.
Ce qui fait conclure. Une enveloppe JSON-RPC 2.0 conforme vaut appel, y
compris quand elle porte une erreur. Un -32001 TaskNotFound est le succès
attendu de ce contrôle : c'est la preuve qu'une application a lu notre requête.
Ce qu'on compte. Le nombre de compétences déclarées dans la carte, parce que c'est là qu'A2A les publie. Aucun appel supplémentaire n'est fait pour remplir une colonne.
sonde-llmstxt : fichiers llms.txt
Ce qu'on envoie. Un GET sur l'adresse du fichier telle qu'une liste
publique la publie.
Ce qui fait conclure. La conformité au format de llmstxt.org (v2), qui n'a
qu'une section obligatoire : « An H1 with the name of the project or site.
This is the only required section. » L'H1 doit être en première position : un
titre arrivé après un paragraphe n'est pas l'H1 du document.
Le piège que ça évite, et il est massif ici. Un /llms.txt absent chez un
hébergeur de sites statiques rend 200 et la page d'accueil. Sur une population
faite de sites vitrines, juger sur le code aurait publié vivants des fichiers
qui n'existent pas.
Un fichier conforme et vide est sain : le format rend les listes de liens
facultatives. Nous publions alors outils.n = 0, un zéro mesuré, à
distinguer d'une absence de mesure.
Un 200 avec du texte mais sans H1 est ambigu, jamais mort : c'est
peut-être notre lecture qui est trop stricte.
Réserve permanente. La liste de départ est un annuaire tiers. La couverture de cette famille n'est jamais affichable en pourcentage : un dénominateur amorcé n'est pas un dénominateur.
sonde-marketplace : marketplaces Claude Code
Ce qu'on envoie. Un GET sur .claude-plugin/marketplace.json à la racine
du dépôt, le chemin que la référence impose.
Ce qui fait conclure. Les trois champs obligatoires du schéma publié :
name, owner.name, plugins. Et rien de plus : description, $schema
et owner.email sont facultatifs et ne sont jamais jugés. Un juge plus strict
que la spécification publie des non-conformités qu'elle n'a jamais exigées.
Ce que mort veut dire ici. La population vient d'un topic GitHub
déclaratif : un dépôt qui porte le topic sans avoir le fichier sort mort
parce que l'adresse publiée ne répond pas : il n'est pas tombé, il n'a jamais
été un marketplace. Lire ce chiffre comme un taux de panne est un contresens.
Ce qu'on ne juge pas. Les plugins eux-mêmes. Leur manifeste
.claude-plugin/plugin.json est facultatif : son absence est licite, donc il
ne peut pas juger quoi que ce soit.
sonde-openapi : spécifications OpenAPI
Ce qu'on envoie. Un GET sur l'adresse où le fournisseur publie sa
spécification, et non sur la copie que l'annuaire en héberge : les copies sont
toutes sur un seul hôte, les sonder ne mesurerait que sa disponibilité.
Ce qui fait conclure. Le parsing en JSON ou en YAML, sans se fier à
l'extension ni au Content-Type, puis la présence d'une version déclarée, d'un
objet info et d'un objet paths. paths est obligatoire jusqu'à 3.0 et
facultatif à partir de 3.1 : le juge suit la version déclarée plutôt que
d'imposer la plus stricte à tout le monde.
« Parsé » ne suffit pas : il faut que ce soit un document. Un analyseur YAML accepte une page HTML entière comme une simple chaîne de caractères : sans ce garde-fou, des fichiers disparus seraient rangés parmi les fichiers présents mais mal formés.
Ce qu'on compte. Les opérations (chemins × méthodes), seul compte fidèle à « décrit des appels » : un document à 40 chemins et 200 opérations décrit 200 appels, pas 40.
Réserve publiée avec le chiffre. Le corpus de départ est figé depuis avril 2023. Le retard que nous publions mesure ses fournisseurs, pas l'écosystème OpenAPI : une interface née depuis n'y figure pas.
sonde-nanda : documents AgentFacts
Ce qu'on envoie. Un GET sur le factsUrl que l'index publie pour l'agent.
Ce qui fait conclure. Les neuf champs obligatoires du schéma publié
(projnanda/agentfacts-format) : id, agent_name, label, description,
version, provider, endpoints, capabilities, skills. Les cinq champs
facultatifs ne sont jamais jugés.
Ce que mort veut dire ici, et c'est important. Il porte sur le document
de faits, pas sur l'agent. Mesuré le 25 août 2026 : sur 206 agents dont le
document ne répondait pas, 166 répondaient à leur point d'accès. Un document
absent ne prouve pas qu'un agent est tombé, et nous ne l'écrivons nulle part.
Ce que nous ne recopions pas. L'index publie un status par agent. Il
n'entre dans aucune de nos colonnes : republier la santé qu'un tiers affirme
n'est pas une mesure.
Ce qu'on compte. Les skills déclarés (ce que l'agent dit savoir faire)
et non ses capabilities, qui disent comment il parle.
mcp-scanner : audit de sécurité
Non branché à ce jour. L'en-tête de latest.json porte
sources["mcp-scanner"].etat = "non_execute", et aucune entrée ne porte de bloc
audit. Cette absence dit « non mesuré » ; elle ne dit pas « audité, rien
trouvé ».