Open source · MIT · MCP

Laissez votre agent IA déboguer la WebView sur le téléphone de votre utilisateur.

Ajoutez un seul script à votre page H5 ou à la WebView de votre application. Votre utilisateur vous lit un court code d’appareil, et Claude Code, Codex, Cursor ou n’importe quel client MCP peut voir la page, lire la console et le réseau, et cliquer jusqu’au bug — pendant que l’utilisateur regarde et peut reprendre la main à tout moment.

  • Sans câble USB
  • Sans port de débogage distant
  • Rien à reconstruire, juste un script
  • Fonctionne même après le bug

01Démo en directEn pratique

Un vrai bug, corrigé sur un « vrai » téléphoneMaintenant, essayez avec votre propre agent

Le téléphone de cette démo exécute le véritable SDK de page dans une boutique de démonstration. Sa passerelle est simulée dans votre navigateur : rien ne quitte cet onglet — mais chaque instantané, chaque clic, chaque ligne de console et chaque correctif à chaud ci-dessous est réel.

Celle-ci est réelle : une passerelle de démonstration publique sur demo.debugger.site, isolée de tout le reste et remise à zéro chaque jour. La boutique dans le téléphone est chargée depuis cette passerelle — récupérez une clé, pointez votre agent dessus et regardez-le travailler ici même.

Prêt
En attente de la mise en ligne de la boutique…
demo.debugger.site

Agent IA

connecté au serveur MCP rwd

Regardez un agent se connecter au téléphone, reproduire un bug de paiement, en trouver la cause racine et vérifier le correctif en direct.

  1. Récupérez votre propre clé

    Un clic, sans inscription. La clé ne fonctionne que sur la passerelle de démonstration et expire à la prochaine remise à zéro.

    Obtenez une clé : elle sera insérée dans la commande ci-dessous.

  2. Ajoutez la passerelle de démonstration à votre agent

    Lancez la commande une fois dans un terminal, ou ajoutez-la aux réglages de votre client MCP. La clé est déjà renseignée.

    terminal
    claude mcp add --transport http rwd-demo https://demo.debugger.site/v1/mcp \
      --header "Authorization: Bearer rwd_sk_live_…"
  3. Demandez à votre agent

    Le code d’appareil de la boutique dans le téléphone est déjà dans l’invite. Quand l’agent demande à se connecter, touchez Autoriser dans la boutique et regardez-le travailler ; vous pouvez Reprendre ou Terminer à tout moment.

    Invite
    Utilise le serveur MCP rwd-demo et connecte-toi à l’appareil XXXX-XXXX. Dans la boutique, choisis le conditionnement « Gift box » pour un produit, passe au paiement et trouve pourquoi le total affiche « -- ».

    Remplacez XXXX-XXXX par le code affiché dans la boutique.

Limites de la démo

  • Une clé par visiteur : votre agent n’atteint que la page dont vous lui donnez le code, et seulement après votre autorisation
  • Niveau interact uniquement : pas de scripts, pas de corps de requête, pas de stockage
  • Un agent garde une page 15 minutes au maximum (5 s’il reste inactif)
  • 120 requêtes MCP par minute et par IP
  • Remise à zéro chaque jour à 04:00 (UTC+8) — n’y saisissez aucune donnée personnelle réelle

Téléphone du clientK7Q2-9M4X

La boutique de démonstration, en direct····-····

En attente de la mise en ligne de la boutique…

Scannez pour l’ouvrir sur votre téléphone
Ouvrir dans un nouvel onglet

Ceci est demo.debugger.site lui-même, avec le vrai SDK. Scannez le code pour l’ouvrir plutôt sur votre téléphone.

Tout se passe dans votre navigateur : le vrai SDK (sdk.js) dans une iframe, une surcouche WebSocket qui tunnelise vers une passerelle simulée dans la page, et un agent scripté qui émet de vrais RPC. Les messages de l’agent suivent la langue de la page ; les résultats des outils sont dans la langue de la passerelle (anglais ou chinois).

02Comment ça marche

Trois étapes entre « ça ne marche pas sur mon téléphone » et la cause racine

  1. Ajoutez le SDK de page

    Un script dans <head>, le plus tôt possible, pour que la console et le réseau soient enregistrés dès la première ligne. Dans une application, injectez le même script au début du document.

  2. L’utilisateur communique un code d’appareil

    Chaque téléphone reçoit un code permanent comme K7Q2-9M4X, affiché dans une petite pastille. L’utilisateur peut toucher Demander une assistance : l’appareil passe alors en tête de la liste de l’agent.

  3. Votre agent se connecte via MCP

    Ajoutez le point d’accès MCP hébergé par la passerelle, avec une clé d’API. Décrivez ensuite simplement le problème : l’agent trouve l’appareil, demande l’autorisation et se met au travail.

index.html
<!-- In <head>, before your own scripts; pin a version in production -->
<script src="https://cdn.jsdelivr.net/npm/remote-webview-debugger/dist/sdk.js"></script>
<script>
  RemoteWebviewDebugger.run("https://rwd.example.com/v1", "rwd_pk_…", {
    userId: currentUser?.id ?? null, // optional: find devices by user
    helpButton: true,                // show the “Request assistance” button
  })
</script>

Épinglez une version en production, ou utilisez la copie embarquée par votre passerelle sur /v1/sdk.js (avec le SRI fourni par la console).

terminal
claude mcp add --transport http rwd https://rwd.example.com/v1/mcp \
  --header "Authorization: Bearer rwd_sk_live_…"
L’appareil K7Q2-9M4X ne peut pas payer — le total affiche « -- ». Trouve pourquoi.

03Ce que reçoit l’agent

Le flux de travail des DevTools, via MCP, sur le téléphone de quelqu’un d’autre

  • Instantanés d’accessibilité

    Du YAML à la façon de Playwright, avec des ref d’éléments. L’agent lit la page comme une structure, pas comme des pixels — et agit sur des ref.

  • De vraies interactions

    click, fill, type, press, select, hover, scroll, drag — avec vérification de l’actionnabilité et les événements que React et Vue acceptent.

  • Console et réseau

    Enregistrés dès le chargement de la page dans des tampons bornés : les erreurs survenues avant l’arrivée de l’agent sont toujours là. Les corps sur demande.

  • Sessions multipages

    Liste → fiche produit → paiement, ou une seconde WebView : toutes les pages d’un appareil forment une seule session, avec une chronologie commune.

  • Les changements de session, poussés

    Chaque résultat d’outil se termine par ce qui a changé — nouvelle page, navigation, erreur, reprise en main par l’utilisateur. Aucun sondage.

  • Carte de tâche sur le téléphone

    L’agent affiche son plan et sa progression sur l’appareil : l’utilisateur sait toujours ce qu’il fait, et pourquoi.

  • Captures d’écran

    Les pixels natifs quand l’application fournit un pont, un rendu du DOM sinon. Le masquage s’applique aux deux.

  • Journal de session sur l’appareil

    Pages, touchers, console et chaque requête depuis le lancement de l’application, conservés sur le téléphone dans IndexedDB — lisibles après coup.

  • Correctifs à chaud

    Au niveau advanced, l’agent peut modifier la page en cours d’exécution avec evaluate_script et vérifier un correctif sur place.

  • Réseaux capricieux

    Un battement de cœur léger avec temporisation progressive ; après trois échecs, un sondage de présence une fois par minute, et la passerelle réveille la page quand il faut.

  • 11 langues

    Interface du téléphone, console et textes destinés à l’agent en 11 langues, arabe de droite à gauche inclus. Apportez vos propres packs et vos propres formulations.

  • Tout client MCP

    Streamable HTTP sur /v1/mcp pour Claude Code, Codex, Cursor et compagnie ; un petit pont stdio pour tout le reste.

Tous les outils 34

  • list_devices
  • connect_device
  • wait_for_device
  • list_pages
  • select_page
  • wait_for_page
  • take_snapshot
  • find_elements
  • take_screenshot
  • click
  • fill
  • type_text
  • press_key
  • select_option
  • hover
  • scroll
  • drag
  • batch_actions
  • navigate_page
  • go_back
  • reload_page
  • wait_for
  • list_console_messages
  • list_network_requests
  • get_network_request
  • get_storage
  • evaluate_script
  • set_task
  • get_session_timeline
  • get_session_overview
  • get_session_log
  • wait_for_event
  • wait_for_control
  • disconnect_device

04Points forts

Pensé pour les bugs qui n’arrivent que dehors

Trois choses qu’un câble, un port de débogage distant ou une capture vidéo ne vous donneront pas.

Journal de session · conservé sur l’appareil

Le bug a déjà eu lieu ? Le journal est encore sur le téléphone.

Dès le lancement de l’application, le SDK écrit un journal de session dans l’IndexedDB de l’appareil : pages visitées, touchers et saisies de l’utilisateur, sorties console et chaque requête — celles qui ont échoué avec leurs en-têtes et leurs corps. Rien n’est diffusé où que ce soit ; tout reste sur le téléphone, sous les mêmes règles de masquage, jusqu’à ce qu’un agent autorisé par l’utilisateur le demande avec get_session_overview et get_session_log. Les trois derniers lancements sont conservés, jusqu’à 10 Mo chacun.

Correctif à chaud · evaluate_script

Vérifiez le correctif sur le téléphone du client, avant de livrer.

Avec l’accord advanced de l’utilisateur, evaluate_script s’exécute dans la page : l’agent peut corriger un état erroné, remplacer une fonction ou réafficher une vue, puis observer le résultat sur l’appareil réel — un correctif à chaud qui prouve le diagnostic. Il ne vit que dans la mémoire de cette page ; rien n’est conservé, et les clics sensibles demandent toujours l’accord de l’utilisateur.

Pensé pour les agents · MCP

Fait pour les agents, pas pour un humain avec des DevTools.

Chaque résultat d’outil se termine par ce qui a changé sur l’appareil depuis l’appel précédent : l’agent n’a jamais besoin de sonder. Le contenu des pages est transmis comme des données non fiables. Une carte de tâche sur le téléphone affiche le plan de l’agent, et la passerelle parle la langue de l’agent — descriptions et résultats des outils en 11 langues.

05Confidentialité et contrôle

Le téléphone de l’utilisateur reste le téléphone de l’utilisateur

Le débogage à distance ne fonctionne que si les gens lui font confiance. Chaque session est visible, autorisée et interruptible.

  • L’autorisation d’abord

    Un agent demande à se connecter ; l’utilisateur voit qui demande et choisit un niveau sur le téléphone. Seuls de vrais touchers comptent : un script ne peut pas s’autoriser lui-même.

  • Reprendre la main ou terminer, à tout moment

    Pendant que l’agent travaille, la page est verrouillée derrière une bordure lumineuse. Un toucher sur Reprendre met l’agent en pause ; Terminer le déconnecte.

  • Masqué par défaut

    Les mots de passe, et tout ce qui est marqué data-rwd-mask, apparaissent sous la forme •••• dans les instantanés, les captures d’écran, la console, les données réseau et le journal de session. Ajoutez vos sélecteurs et vos expressions régulières projet par projet.

  • Les clics sensibles demandent un oui

    Marquez les boutons avec data-rwd-confirm (« Valider la commande », « Supprimer le compte ») et l’utilisateur confirme chaque clic de l’agent dessus.

  • Niveaux d’accès

    observe lit, interact agit, advanced ajoute les scripts, les corps de requête et le stockage. Plafonné par clé et par projet.

  • Journal d’audit

    Chaque connexion, autorisation, RPC et reprise en main est enregistrée avec qui, quoi et quand — jamais le contenu des pages ni la valeur des paramètres.

06Applications natives

Dans votre application, c’est un seul script utilisateur

Téléchargez le SDK une fois et injectez-le au début du document — WKUserScript sur iOS, addDocumentStartJavaScript sur Android. Vos pages web ne changent pas d’une ligne.

  • Un seul code d’appareil partout

    Passez un deviceId stable (et conservez le deviceToken) pour que le code survive aux changements de WebView et de domaine.

  • Contrôles natifs

    Affichez vos propres boutons reprendre la main / rendre la main / terminer avec nativeControl() ; les scripts de la page ne peuvent pas l’appeler.

  • Boîtes de dialogue d’autorisation natives

    nativeApproval: true confie les demandes de connexion et les confirmations à l’interface de votre propre application.

  • Captures d’écran en pixels réels

    Un petit pont (snapshot WKWebView, bitmap Android) donne à l’agent de vrais pixels au lieu d’un rendu du DOM.

RemoteDebugger.swift
import WebKit

/// Call before webView.load(…): fetch the SDK once, inject it at document start.
func installRemoteDebugger(into controller: WKUserContentController,
                           userId: String?, done: @escaping () -> Void) {
    let gateway = "https://rwd.example.com/v1"
    URLSession.shared.dataTask(with: URL(string: gateway + "/sdk.js")!) { data, _, _ in
        DispatchQueue.main.async {
            defer { done() }
            guard let data, let sdk = String(data: data, encoding: .utf8) else { return }
            let options: [String: Any] = [
                "deviceId": stableDeviceId, // a UUID kept in UserDefaults
                "userId": userId ?? NSNull(),
                "helpButton": true,
            ]
            let json = String(data: try! JSONSerialization.data(withJSONObject: options), encoding: .utf8)!
            let boot = sdk + "\n;RemoteWebviewDebugger.run(\"\(gateway)\", \"rwd_pk_…\", \(json));"
            controller.addUserScript(WKUserScript(source: boot,
                                                  injectionTime: .atDocumentStart,
                                                  forMainFrameOnly: true))
        }
    }.resume()
}

07Auto-hébergé

Un seul binaire Go. Vos serveurs. Vos données.

La passerelle embarque la console web et le SDK de page. SQLite d’emblée, Postgres quand il le faut, Docker Compose et Caddy pour le HTTPS.

  • Console

    Appareils, clés d’API, membres et rôles, invitations par QR code, règles et journal d’audit — plus un guide d’intégration déjà rempli avec vos propres clés.

  • Stockage

    Un fichier SQLite par défaut ; définissez RWD_DATABASE_URL=postgres://… pour utiliser Postgres.

  • Exploitation

    Métriques Prometheus sur /v1/metrics, URL de SDK versionnées avec SRI, contrôle de santé sur /v1/healthz.

Guide de déploiement

Démarrage rapide
# un seul conteneur : console + passerelle + SDK
docker run -d --name rwd -p 8080:8080 -v rwd-data:/data \
  -e RWD_ADMIN_PASSWORD='change-me' \
  ghcr.io/zanel1u/remote-webview-debugger:latest

# ou compilez-la, déployez-la et obtenez le HTTPS avec Caddy
git clone https://github.com/ZaneL1u/remote-webview-debugger
RWD_DOMAIN=rwd.example.com \
  remote-webview-debugger/deploy/platform/deploy.sh you@your-server amd64
# → console     https://rwd.example.com
# → passerelle  https://rwd.example.com/v1  (MCP sur /v1/mcp)

Docker suffit côté serveur ; compiler depuis les sources demande Go et Node.

08FAQ

Les questions qu’on nous pose

L’utilisateur doit-il installer quelque chose ?

Non. Pour une page H5, le SDK fait partie de votre page. Dans une application, vous l’injectez depuis le code natif. L’utilisateur ne voit qu’une petite pastille avec son code d’appareil et, quand un agent se connecte, une demande d’autorisation.

Que peut voir et faire l’agent ?

Seulement ce que l’utilisateur a autorisé : les pages WebView de cet appareil, au niveau accordé. Il ne pilote jamais rien en dehors de la WebView. Les champs masqués restent masqués, et le contenu des pages est transmis au modèle comme des données non fiables.

Le bug est survenu avant la connexion de l’agent. Est-il perdu ?

Non. Le SDK conserve sur l’appareil un journal de session depuis le lancement de l’application — pages, touchers, console et requêtes — et un agent qui se connecte plus tard relit tout le chemin jusqu’au bug avec get_session_log. En dehors de cela, le journal ne quitte jamais le téléphone.

L’agent peut-il corriger le bug sur le téléphone ?

Il peut vérifier un correctif : au niveau advanced, evaluate_script modifie en mémoire la page en cours d’exécution — corriger un état, remplacer une fonction, réafficher une vue — et l’agent voit si le problème disparaît. Le vrai correctif passe toujours par votre livraison habituelle ; rien n’est conservé sur l’appareil.

Quels agents fonctionnent avec ?

N’importe quel client MCP. Claude Code, Codex et Cursor utilisent directement le point d’accès Streamable HTTP hébergé ; les clients qui ne parlent que stdio passent par rwd mcp, un petit pont vers ce même point d’accès.

Quelles plateformes sont prises en charge ?

Toute WebView ou tout navigateur mobile moderne : WKWebView sur iOS, Android System WebView, navigateurs intégrés aux applications, ainsi que Safari ou Chrome mobile. Les navigateurs de bureau fonctionnent aussi.

Et sur un mauvais réseau, ou si les WebSockets sont bloqués ?

La page maintient un WebSocket de battement de cœur léger, avec temporisation exponentielle. Si la connexion échoue trois fois de suite, elle bascule sur un sondage de présence une fois par minute, et la passerelle la réveille quand un agent veut se connecter.

Est-ce que ça ralentit ma page ?

C’est un seul script. Les enregistrements de console et de réseau vivent dans des tampons circulaires bornés (500 entrées chacun, corps de réponse plafonnés à 5 Mo), le journal de session est écrit en arrière-plan, et une connexion inactive n’échange que des battements de cœur.

Est-ce que ça cohabite avec eruda, vConsole ou PageSpy ?

Oui — leurs nœuds sont ignorés par les instantanés et les tests de clic, notre propre trafic n’apparaît pas dans leurs journaux réseau, et le débogueur peut même s’installer comme un onglet dans eruda.

La démo ci-dessus est-elle réelle ?

Le SDK est réel et non modifié ; seule la passerelle est simulée dans votre navigateur. Une surcouche WebSocket tunnelise la connexion du SDK vers elle avec postMessage, et un agent scripté envoie les mêmes RPC qu’une vraie passerelle. Pour la version réelle de bout en bout, essayez avec votre propre agent.