La plupart des plateformes IA se connectent aux services externes via des API REST. Cela fonctionne pour les données structurées — lire un contact CRM, créer un ticket Jira — mais manque tout ce qui se passe dans le navigateur. Le brouillon d’email dans Gmail, le fil Slack que vous lisez, le formulaire à moitié rempli dans ServiceNow.
Nous avons construit une extension navigateur qui comble ce fossé en utilisant le Model Context Protocol (MCP). Cet article couvre les décisions d’architecture, les problèmes rencontrés et le fonctionnement du système de bout en bout.
Le problème : l’état du navigateur est invisible pour les API
Les API vous donnent des enregistrements de base de données. Elles ne vous donnent pas ce qui est à l’écran. Un commercial composant un email de suivi dans Gmail a un contexte qu’aucune API ne peut capturer.
Vue d’ensemble de l’architecture
L’extension est construite sur WXT 0.20 (Manifest V3) avec Svelte 5 et TypeScript. Elle implémente un client MCP qui se connecte au serveur JieGou via WebSocket, exposant 60+ outils d’automatisation navigateur que les workflows IA peuvent invoquer.
Le flux de messages :
Serveur MCP → WebSocket → Background Service Worker → Content Script → Page
Quand une recette ou un workflow a besoin d’interaction navigateur, il envoie un appel d’outil JSON-RPC 2.0 à travers la connexion WebSocket.
Pont WebSocket
Le proxy WebSocket gère l’authentification, les heartbeats, la reconnexion et le rafraîchissement de tokens.
L’authentification se fait à la connexion — le client envoie un message authenticate avec un token JWT.
Les heartbeats s’exécutent toutes les 15 secondes au niveau applicatif. Si un pong n’arrive pas dans les 5 secondes, la connexion est considérée morte.
La reconnexion automatique utilise un délai de 3 secondes avec backoff exponentiel. Le rafraîchissement de token se fait proactivement 5 minutes avant l’expiration du JWT.
Pipeline d’exécuteurs d’outils
Tous les outils étendent une classe BaseBrowserToolExecutor qui fournit des helpers communs.
Les outils se répartissent en catégories :
Interaction page — click_element, fill_form_field, select_dropdown, scroll_page et navigate.
Lecture de contenu — read_page parse le DOM et assigne des IDs de référence stables aux éléments interactifs.
Extracteurs spécifiques aux plateformes — web_fetcher a des parseurs spécialisés pour Gmail, Slack, Jira, Salesforce, ServiceNow et HubSpot.
Internes navigateur — javascript exécute du code arbitraire via Chrome DevTools Protocol, network_capture surveille le trafic HTTP, screenshot capture le viewport.
Scripts d’injection : exécution dans le monde de la page
La partie la plus délicate de l’architecture. Les content scripts s’exécutent dans un monde isolé. Nous avons 16 modules TypeScript bundlés comme IIFEs via un plugin esbuild personnalisé et injectés dans le monde MAIN.
Ce que nous avons appris
Les service workers Manifest V3 sont éphémères. Nous avons dû rendre la connexion WebSocket résiliente aux redémarrages.
Le parsing spécifique aux plateformes bat le scraping générique. Écrire des parseurs ciblés pour chaque plateforme (6 à ce jour) a considérablement amélioré la fiabilité.
MCP est un bon protocole pour cela. La base JSON-RPC 2.0 avec la découverte tools/list et l’invocation typée tools/call est simple à implémenter mais suffisamment structurée pour être fiable.