La scène se répète chaque fois qu'un agent IA doit faire quelque chose sur un site web. Il prend une capture d'écran, lit le DOM, cherche le bouton, clique, attend, recommence. J'ai écrit ce genre d'automatisation pendant des mois : un champ de formulaire React qui ignore la saisie parce que el.value = ... ne passe pas les value trackers, un éditeur de commentaire qui se replie si on scrolle pendant la frappe, un sélecteur CSS qui casse à la mise à jour suivante. Un agent qui navigue comme un humain hérite de toute la fragilité d'un humain, sans les réflexes.
Le 8 août, j'ai pris le problème dans l'autre sens sur mon propre site : au lieu de laisser les agents deviner où est le bouton « Réserver un appel », la page le leur dit. Le mécanisme s'appelle WebMCP, et il tient en 158 lignes.
WebMCP : le contrat MCP, déplacé dans la page
Si vous connaissez MCP, le protocole qui permet de brancher des outils externes sur un LLM, vous connaissez déjà le principe. Un serveur MCP classique tourne quelque part, expose des tools avec un nom, une description et un schéma de paramètres, et l'agent les appelle. WebMCP reprend ce contrat et le déplace dans le navigateur : c'est la page web elle-même qui déclare ses tools, en JavaScript, via une nouvelle API du navigateur.
document.modelContext.registerTool({
name: 'open_booking_popup',
description: 'Open the Cal.com booking popup...',
inputSchema: { type: 'object', properties: { ... } },
execute: async (args) => { ... },
});
Un agent qui pilote le navigateur du visiteur découvre ces tools et les appelle directement. Pas de capture d'écran, pas de sélecteur CSS, pas de formulaire à deviner. Et comme le code s'exécute dans la page, il profite de la session du visiteur : panier, compte client, contexte de navigation.
Côté standard, c'est un brouillon du W3C porté par Google et Microsoft, dernière publication en avril 2026. Chrome l'a mis en origin trial des versions 149 à 156. L'API a d'ailleurs bougé en cours de route : elle vivait sur navigator.modelContext, elle vit maintenant sur document.modelContext, et Chrome 150 a déprécié l'ancienne surface pendant que l'origin trial la sert encore. Mon composant tente les deux, dans cet ordre. C'est le quotidien d'une spec en incubation, et une bonne raison d'isoler tout ça dans un seul fichier.
Trois tools, 158 lignes
Concrètement, mon site enregistre trois tools sur chaque page, dans un composant Next.js de 158 lignes monté dans le layout :
get_consulting_servicesrenvoie un JSON structuré : les services, les tarifs, le contact. Ce qu'un agent mettrait dix requêtes à reconstituer en scrapant, il l'obtient en un appel.get_booking_linkrenvoie le lien Cal.com direct de l'appel découverte, dans la bonne langue.open_booking_popupest le plus intéressant : il ouvre le popup de réservation Cal.com sur la page, prérempli avec le nom, l'email et le contexte que l'agent lui passe. L'agent prépare tout, l'humain n'a plus qu'à choisir le créneau.
Le tout en progressive enhancement strict : si le navigateur n'implémente pas l'API, le composant ne fait rien. Aucun risque pour les visiteurs actuels, aucune dépendance, aucun impact sur le chargement.
Un agent ne devrait pas avoir à deviner où est le bouton. La page peut le lui dire.
Le chaînon manquant : comment un agent sait que les tools existent
Enregistrer des tools, c'est la moitié du travail. L'autre moitié, dont la spec ne parle pas encore, c'est la découverte : un agent qui arrive de Google ne sait pas que votre page expose quoi que ce soit. Il n'existe aucune convention standard pour annoncer des tools WebMCP hors de la page.
En attendant qu'une convention émerge, j'ai posé trois couches qui se pointent l'une l'autre :
- le
llms.txt, que les agents lisent déjà, gagne une section « Agent Tools » qui liste les trois tools, leurs paramètres, et invite à charger une page plutôt qu'à scraper ; - le balisage schema.org de la page déclare une
ReserveActionpointant vers le booking, lisible par les crawlers classiques ; - le
robots.txtrenvoie vers la section dullms.txt.
Un agent qui fait une recherche, tombe sur le site et lit le llms.txt sait désormais qu'il a mieux à faire que de cliquer partout. C'est une redirection volontaire du trafic agent vers le chemin structuré.
Tester un standard que personne n'implémente encore
Problème d'implémenteur précoce : aucun assistant grand public n'appelle ces tools aujourd'hui. Pour vérifier que le mécanisme tient, j'ai injecté un mock de document.modelContext dans le navigateur, rechargé l'application, et joué le rôle de l'agent moi-même. Les trois tools s'enregistrent, et l'appel à open_booking_popup avec un nom et un email de test ouvre bien le popup Cal.com : les paramètres se retrouvent dans l'URL de l'iframe, le formulaire est prérempli.
J'ai aussi branché un compteur : chaque appel de tool envoie un événement webmcp_tool_call dans mes analytics. Le jour où un premier agent réel appellera un de ces tools, je le verrai. Pour l'instant, le compteur est à zéro, et c'est normal.
Le tool existe, personne ne l'appelle encore. C'est exactement le moment où l'installer coûte le moins cher.
Faut-il équiper votre site maintenant ?
La réponse honnête : rien ne presse, et le pari est asymétrique. L'origin trial court jusqu'à Chrome 156, la spec peut encore bouger, et vos visiteurs n'utilisent pas d'assistant navigateur. Mais le coût d'entrée est un composant de 158 lignes et deux fichiers texte, et la trajectoire est lisible : les navigateurs agentiques arrivent, et le jour où ils seront là, il y aura deux sortes de sites. Ceux qui exposent des actions propres, réservables, appelables. Et ceux que les agents continueront de scraper, avec la fiabilité que je décrivais en ouverture.
Pour un site vitrine de PME, la conversion la plus précieuse est souvent un rendez-vous pris. Rendre cette action appelable par un agent, c'est s'assurer que le jour où un dirigeant dira « trouve-moi un prestataire et cale un créneau », son assistant pourra le faire chez vous plutôt que chez le concurrent.
Si le sujet vous concerne, l'intégration d'agents et de MCP dans une stack existante est exactement le genre de chantier que je mène. On peut en parler.
