Código abierto · MIT · MCP

Deja que tu agente de IA depure la WebView del teléfono de tu usuario.

Añade un script a tu página H5 o a la WebView de tu app. Tu usuario te dicta un código de dispositivo corto y Claude Code, Codex, Cursor o cualquier cliente MCP puede ver la página, leer la console y la red, y recorrer el bug a base de clics, mientras el usuario lo mira todo y puede tomar el control en cualquier momento.

  • Sin cable USB
  • Sin puerto de depuración remota
  • Sin recompilar la app: solo un script
  • Funciona después de que ocurra el bug

01Demo en vivoManos a la obra

Un bug real, resuelto en un teléfono “real”Ahora pruébalo con tu propio agente

El teléfono de esta demo ejecuta el SDK de página de verdad dentro de una tienda de demostración. Su gateway está simulado en tu navegador, así que nada sale de esta pestaña, pero cada instantánea, clic, línea de console y parche en vivo que ves abajo es real.

Esta es de verdad: un gateway de demostración público en demo.debugger.site, aislado de todo lo demás y borrado cada día. La tienda del teléfono se carga desde ahí: consigue una clave, apunta tu agente a ella y míralo trabajar aquí mismo.

Listo
Esperando a que la tienda se conecte…
demo.debugger.site

Agente de IA

conectado al servidor MCP de rwd

Mira cómo un agente se conecta al teléfono, reproduce un bug del pago, encuentra la causa raíz y verifica la solución en vivo.

  1. Consigue tu propia clave

    Un clic, sin registro. La clave solo funciona en el gateway de demostración y dura hasta que la demo se reinicia.

    Consigue una clave y se rellenará en el comando de abajo.

  2. Añade el gateway de demostración a tu agente

    Ejecuta el comando una vez en una terminal, o añádelo a los ajustes de tu cliente MCP. La clave ya viene rellenada.

    terminal
    claude mcp add --transport http rwd-demo https://demo.debugger.site/v1/mcp \
      --header "Authorization: Bearer rwd_sk_live_…"
  3. Pídeselo a tu agente

    El código de dispositivo de la tienda del teléfono ya está en el prompt. Cuando el agente pida conectarse, toca Permitir en la tienda y míralo trabajar; puedes usar Tomar control o Finalizar en cualquier momento.

    Prompt
    Usa el servidor MCP rwd-demo y conéctate al dispositivo XXXX-XXXX. En la tienda, elige el paquete “Gift box” de un producto, ve a la página de pago y averigua por qué el total muestra “--”.

    Sustituye XXXX-XXXX por el código que se muestra en la tienda.

Límites de la demo

  • Una clave por visitante: tu agente solo llega a la página cuyo código le des, y después de que lo permitas
  • Solo nivel interact: sin scripts, sin cuerpos de solicitudes y sin almacenamiento
  • Un agente se queda con una página 15 minutos como máximo (5 si está inactivo)
  • 120 solicitudes MCP por minuto y por IP
  • Se borra cada día a las 04:00 (UTC+8): no introduzcas datos personales reales

Teléfono del clienteK7Q2-9M4X

La tienda de demostración, en vivo····-····

Esperando a que la tienda se conecte…

Escanea para abrirlo en tu teléfono
Abrir en una pestaña nueva

Esto es demo.debugger.site en persona, ejecutando el SDK real. Escanea el código para abrirlo en tu teléfono.

Todo ocurre en tu navegador: el SDK real (sdk.js) en un iframe, un shim de WebSocket que lo conecta con un gateway simulado en la propia página y un agente con guion que envía RPC de verdad. Los mensajes del agente siguen el idioma de la página; los resultados de las herramientas están en el idioma del gateway (inglés o chino).

02Cómo funciona

Tres pasos desde “en mi teléfono no funciona” hasta la causa raíz

  1. Añade el SDK de página

    Un script en <head>, lo más arriba posible, para que la console y la red se graben desde la primera línea. En una app, inyecta el mismo script al inicio del documento.

  2. El usuario comparte un código de dispositivo

    Cada teléfono recibe un código permanente como K7Q2-9M4X en una pequeña píldora. El usuario puede tocar Solicitar asistencia y el dispositivo salta al principio de la lista del agente.

  3. Tu agente se conecta por MCP

    Añade el endpoint MCP que aloja el gateway con una clave de API. Después basta con describir el problema: el agente encuentra el dispositivo, pide aprobación y se pone a trabajar.

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>

Fija una versión en producción, o usa la copia que lleva tu propio gateway en /v1/sdk.js (con SRI desde la consola).

terminal
claude mcp add --transport http rwd https://rwd.example.com/v1/mcp \
  --header "Authorization: Bearer rwd_sk_live_…"
El dispositivo K7Q2-9M4X no puede pagar: el total muestra “--”. Averigua por qué.

03Lo que recibe el agente

El flujo de DevTools, por MCP, en el teléfono de otra persona

  • Instantáneas de accesibilidad

    YAML al estilo de Playwright con refs de elementos. El agente lee la página como estructura, no como píxeles, y actúa sobre las refs.

  • Interacciones reales

    click, fill, type, press, select, hover, scroll, drag, con comprobaciones de que el elemento es operable y con eventos que React y Vue aceptan.

  • Console y red

    Se graban desde que carga la página, en búferes acotados, así que los errores anteriores a la llegada del agente siguen ahí. Los cuerpos, a petición.

  • Sesiones con varias páginas

    Lista → detalle → pago, o una segunda WebView: todas las páginas de un dispositivo forman una sola sesión, con una línea de tiempo común.

  • Los cambios de sesión te llegan solos

    Cada resultado de herramienta termina con lo que cambió: una página nueva, una navegación, un error, el usuario tomando el control. Sin sondeos.

  • Tarjeta de tarea en el teléfono

    El agente muestra su plan y su progreso en el dispositivo, para que el usuario sepa siempre qué está haciendo y por qué.

  • Capturas de pantalla

    Píxeles nativos cuando la app ofrece un puente, y una representación del DOM si no. El enmascarado se aplica a las dos.

  • Registro de sesión en el dispositivo

    Páginas, toques, console y todas las solicitudes desde que se inició la app, guardados en el teléfono en IndexedDB y legibles a posteriori.

  • Parches en vivo

    En el nivel advanced, el agente puede parchear la página en marcha con evaluate_script y verificar una solución en el momento.

  • Redes malas

    Un heartbeat ligero con back-off; tras tres fallos, un sondeo de presencia una vez por minuto, y el gateway despierta la página cuando hace falta.

  • 11 idiomas

    Interfaz del teléfono, console y textos dirigidos al agente en 11 idiomas, incluido el árabe de derecha a izquierda. Trae tus propios paquetes y tus propios textos.

  • Cualquier cliente MCP

    Streamable HTTP en /v1/mcp para Claude Code, Codex, Cursor y compañía; un pequeño puente stdio para todo lo demás.

Todas las herramientas 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

04Lo destacado

Hecho para los bugs que solo pasan ahí fuera

Tres cosas que no te dará un cable, ni un puerto de depuración remota, ni una grabación de pantalla.

Registro de sesión · almacenado en frío en el dispositivo

¿El bug ya ocurrió? El registro sigue en el teléfono.

Desde que la app se inicia, el SDK escribe un registro de sesión en el IndexedDB del dispositivo: páginas visitadas, los toques y lo que escribió el usuario, la salida de console y todas las solicitudes — las fallidas con encabezados y cuerpos. Nada se transmite a ninguna parte: se queda en el teléfono, con las mismas reglas de enmascarado, hasta que un agente aprobado por el usuario lo pide con get_session_overview y get_session_log. Se conservan los tres últimos inicios, de hasta 10 MB cada uno.

Parche en vivo · evaluate_script

Verifica la solución en el teléfono del cliente, antes de publicarla.

Con la aprobación advanced del usuario, evaluate_script se ejecuta en la página, así que el agente puede corregir un estado erróneo, sustituir una función o volver a renderizar una vista y ver el resultado en el dispositivo real: un parche en vivo que demuestra el diagnóstico. Solo vive en la memoria de esa página; nada queda guardado, y los clics sensibles siguen necesitando el sí del usuario.

Nativo para agentes · MCP

Pensado para agentes, no para una persona con DevTools.

Cada resultado de herramienta termina con lo que cambió en el dispositivo desde la llamada anterior, así que el agente nunca sondea. El contenido de la página se entrega como datos no confiables. Una tarjeta de tarea en el teléfono muestra el plan del agente, y el gateway habla el idioma del agente: descripciones y resultados de las herramientas en 11 idiomas.

05Privacidad y control

El teléfono del usuario sigue siendo del usuario

La depuración remota solo funciona si la gente confía en ella. Cada sesión se ve, se aprueba y se puede interrumpir.

  • Primero, la aprobación

    Un agente pide conectarse; el usuario ve quién lo pide y elige un nivel en el teléfono. Solo cuentan los toques reales: un script no puede aprobarse a sí mismo.

  • Toma el control o finaliza, cuando quieras

    Mientras el agente trabaja, la página queda bloqueada detrás de un borde luminoso. Un toque en Tomar control pone al agente en pausa; Finalizar lo desconecta.

  • Enmascarado por defecto

    Las contraseñas, y todo lo marcado con data-rwd-mask, aparecen como •••• en instantáneas, capturas de pantalla, console, datos de red y el registro de sesión. Añade selectores y expresiones regulares por proyecto.

  • Los clics sensibles necesitan un sí

    Marca botones con data-rwd-confirm (“Hacer el pedido”, “Eliminar la cuenta”) y el usuario confirmará cada clic del agente sobre ellos.

  • Niveles de permiso

    observe lee, interact opera, advanced añade scripts, cuerpos de solicitudes y almacenamiento. Con un tope por clave y por proyecto.

  • Registro de auditoría

    Cada conexión, aprobación, RPC y toma de control se graba con quién, qué y cuándo; nunca el contenido de las páginas ni los valores de los parámetros.

06Apps nativas

En tu app es un solo user script

Descarga el SDK una vez e inyéctalo al inicio del documento: WKUserScript en iOS, addDocumentStartJavaScript en Android. Tus páginas web no cambian en nada.

  • Un mismo código de dispositivo en todas partes

    Pasa un deviceId estable (y guarda el deviceToken) para que el código sobreviva entre WebViews y dominios.

  • Controles nativos

    Muestra tus propios botones de tomar control / devolver / finalizar con nativeControl(); los scripts de la página no pueden llamarlo.

  • Diálogos de aprobación nativos

    nativeApproval: true deja las solicitudes de conexión y las confirmaciones en manos de la interfaz de tu app.

  • Capturas con píxeles reales

    Un pequeño puente (snapshot de WKWebView, bitmap en Android) le da al agente píxeles de verdad en lugar de una representación del 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()
}

07Autoalojado

Un binario de Go. Tus servidores. Tus datos.

El gateway lleva integrados la consola web y el SDK de página. SQLite desde el primer momento, Postgres cuando lo necesites, Docker Compose y Caddy para el HTTPS.

  • Consola

    Dispositivos, claves de API, miembros y roles, invitaciones por QR, políticas y un registro de auditoría, más una guía de integración ya rellenada con tus propias claves.

  • Almacenamiento

    Un archivo SQLite por defecto; define RWD_DATABASE_URL=postgres://… para usar Postgres.

  • Operación

    Métricas de Prometheus en /v1/metrics, URL del SDK versionadas con SRI, comprobación de salud en /v1/healthz.

Guía de despliegue

Inicio rápido
# un contenedor: consola + gateway + 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

# o compílalo, despliégalo y consigue HTTPS con 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
# → consola  https://rwd.example.com
# → gateway  https://rwd.example.com/v1  (MCP en /v1/mcp)

Al servidor solo le hace falta Docker; compilar desde el código fuente necesita Go y Node.

08FAQ

Lo que suele preguntar la gente

¿Tiene que instalar algo el usuario?

No. En las páginas H5 el SDK forma parte de tu página. En una app lo inyectas desde el código nativo. El usuario solo ve una pequeña píldora con su código de dispositivo y, cuando un agente se conecta, un diálogo de aprobación.

¿Qué puede ver y hacer el agente?

Solo lo que el usuario aprobó: las páginas WebView de ese dispositivo, con el nivel concedido. Nunca controla nada fuera de la WebView. Los campos enmascarados siguen enmascarados, y el contenido de la página se le pasa al modelo como datos no confiables.

El bug ocurrió antes de que el agente se conectara. ¿Se perdió?

No. El SDK guarda en el dispositivo un registro de sesión desde que se inició la app (páginas, toques, console y solicitudes), así que un agente que se conecte después puede leer todo el camino hasta el bug con get_session_log. Por lo demás, nunca sale del teléfono.

¿Puede el agente arreglar el bug en el teléfono?

Puede verificar una solución: en el nivel advanced, evaluate_script parchea en memoria la página en marcha (corregir el estado, sustituir una función, volver a renderizar) y el agente ve si el problema desaparece. La solución de verdad sigue publicándose por tu proceso habitual; en el dispositivo no queda nada guardado.

¿Con qué agentes funciona?

Con cualquier cliente MCP. Claude Code, Codex y Cursor usan directamente el endpoint Streamable HTTP alojado; los clientes que solo hablan stdio usan rwd mcp, un pequeño puente al mismo endpoint.

¿Qué plataformas están soportadas?

Cualquier WebView o navegador móvil moderno: WKWebView en iOS, Android System WebView, navegadores dentro de apps y el Safari o el Chrome móvil de toda la vida. Los navegadores de escritorio también funcionan.

¿Y si la red es mala o los WebSockets están bloqueados?

La página mantiene un WebSocket de heartbeat ligero con back-off exponencial. Si no consigue conectarse tres veces seguidas, pasa a un sondeo de presencia una vez por minuto, y el gateway la despierta cuando un agente quiere conectarse.

¿Ralentiza mi página?

Es un solo script. Los registros de console y de red viven en búferes circulares acotados (500 entradas cada uno, cuerpos de respuesta con un tope de 5 MB), el registro de sesión se escribe en segundo plano y una conexión inactiva solo intercambia heartbeats.

¿Funciona junto a eruda, vConsole o PageSpy?

Sí: sus nodos se omiten en las instantáneas y en la detección de clics, nuestro propio tráfico no aparece en sus registros de red, y hasta puede vivir como una pestaña dentro de eruda.

¿La demo de arriba es real?

El SDK es real y sin modificar; solo el gateway está simulado en tu navegador. Un shim de WebSocket le lleva la conexión del SDK con postMessage, y un agente con guion envía las mismas RPC que enviaría un gateway real. Para verlo de verdad y de principio a fin, pruébalo con tu propio agente.