Open source · MIT · MCP

Deixe seu agente de IA depurar a WebView no celular do seu usuário.

Adicione uma tag script à sua página H5 ou à WebView do seu app. Seu usuário dita um código do dispositivo curto e o Claude Code, o Codex, o Cursor ou qualquer cliente MCP já consegue ver a página, ler o console e a rede e ir clicando até o bug — enquanto o usuário acompanha e pode assumir o controle a qualquer momento.

  • Sem cabo USB
  • Sem porta de depuração remota
  • Sem recompilar o app: só um script
  • Funciona depois que o bug aconteceu

01Demo ao vivoMão na massa

Um bug real, resolvido em um celular “real”Agora teste com o seu próprio agente

O celular desta demo roda o SDK de verdade dentro de uma loja de demonstração. O gateway dele é simulado no seu navegador, então nada sai desta aba — mas todo snapshot, clique, linha de console e patch ao vivo aqui embaixo é real.

Esta aqui é real: um gateway de demonstração público em demo.debugger.site, separado de todo o resto e apagado todos os dias. A loja no celular é carregada de lá — pegue uma chave, aponte seu agente para ela e veja o agente trabalhar aqui mesmo.

Pronto
Aguardando a loja ficar online…
demo.debugger.site

Agente de IA

conectado ao servidor MCP do rwd

Veja um agente se conectar ao celular, reproduzir um bug no checkout, achar a causa raiz e verificar a correção ao vivo.

  1. Pegue uma chave sua

    Um clique, sem cadastro. A chave só funciona no gateway de demonstração e vale até a demo ser reiniciada.

    Pegue uma chave e ela é preenchida no comando abaixo.

  2. Adicione o gateway de demonstração ao seu agente

    Rode o comando uma vez no terminal, ou coloque-o nas configurações do seu cliente MCP. A chave já vem preenchida.

    terminal
    claude mcp add --transport http rwd-demo https://demo.debugger.site/v1/mcp \
      --header "Authorization: Bearer rwd_sk_live_…"
  3. Peça ao seu agente

    O código do dispositivo da loja no celular já está no prompt. Quando o agente pedir para se conectar, toque em Permitir na loja e veja o agente trabalhar; você pode Assumir ou Encerrar a qualquer momento.

    Prompt
    Use o servidor MCP rwd-demo e conecte-se ao dispositivo XXXX-XXXX. Na loja, escolha a embalagem de presente (“Gift box”) de um produto, vá para o checkout e descubra por que o total aparece como “--”.

    Troque XXXX-XXXX pelo código mostrado na loja.

Limites da demo

  • Uma chave por visitante: seu agente alcança apenas a página cujo código você der a ele, depois que você permitir
  • Somente o nível interact: sem scripts, corpos de requisição ou armazenamento
  • Um agente fica com uma página por no máximo 15 minutos (5 se ficar ocioso)
  • 120 requisições MCP por minuto por IP
  • Apagado todo dia às 04:00 (UTC+8) — não insira dados pessoais reais

Celular do clienteK7Q2-9M4X

A loja de demonstração, ao vivo····-····

Aguardando a loja ficar online…

Escaneie para abrir no seu celular
Abrir em uma nova aba

Esta é a própria demo.debugger.site, rodando o SDK de verdade. Escaneie o código para abri-la no seu celular.

Roda inteirinho no seu navegador: o SDK de verdade (sdk.js) em um iframe, um shim de WebSocket que faz um túnel até um gateway simulado na própria página e um agente roteirizado emitindo RPCs reais. As mensagens do agente seguem o idioma da página; os resultados das ferramentas vêm no idioma do gateway (inglês ou chinês).

02Como funciona

Três passos entre “quebrou no meu celular” e a causa raiz

  1. Adicione o SDK da página

    Uma tag script no <head>, o mais no início possível, para que console e rede sejam gravados desde a primeira linha. Em um app, injete o mesmo script no início do documento.

  2. O usuário compartilha um código do dispositivo

    Todo celular ganha um código permanente como K7Q2-9M4X em uma pequena pílula. O usuário pode tocar em Solicitar assistência, e o dispositivo vai para o topo da lista do agente.

  3. Seu agente se conecta via MCP

    Adicione o endpoint MCP hospedado pelo gateway com uma chave de API. Depois é só descrever o problema — o agente encontra o dispositivo, pede a aprovação e começa a trabalhar.

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>

Fixe uma versão em produção, ou use a cópia que o seu gateway serve em /v1/sdk.js (com SRI, disponível no console).

terminal
claude mcp add --transport http rwd https://rwd.example.com/v1/mcp \
  --header "Authorization: Bearer rwd_sk_live_…"
O dispositivo K7Q2-9M4X não consegue finalizar a compra — o total aparece como “--”. Descubra por quê.

03O que o agente ganha

O fluxo do DevTools, via MCP, no celular de outra pessoa

  • Snapshots de acessibilidade

    YAML no estilo do Playwright, com refs de elementos. O agente lê a página como estrutura, não como pixels — e age sobre as refs.

  • Interações reais

    click, fill, type, press, select, hover, scroll, drag — com verificação de acionabilidade e eventos que o React e o Vue aceitam.

  • Console e rede

    Gravados desde o carregamento da página em buffers limitados, então os erros de antes de o agente chegar continuam lá. Corpos sob demanda.

  • Sessões com várias páginas

    Lista → detalhe → checkout, ou uma segunda WebView: todas as páginas de um dispositivo formam uma sessão, com uma linha do tempo que atravessa as páginas.

  • Mudanças na sessão, na hora

    Todo resultado de ferramenta termina com o que mudou — página nova, navegação, um erro, o usuário assumindo o controle. Sem polling.

  • Cartão de tarefa no celular

    O agente mostra o plano e o progresso no dispositivo, para que o usuário sempre saiba o que ele está fazendo e por quê.

  • Capturas de tela

    Pixels nativos quando o app oferece uma bridge, renderização do DOM caso contrário. O mascaramento vale para as duas.

  • Log da sessão no dispositivo

    Páginas, toques, console e todas as requisições desde que o app abriu, guardados no celular no IndexedDB — e legíveis depois do fato.

  • Patches ao vivo

    No nível avançado, o agente pode aplicar um patch na página em execução com evaluate_script e verificar a correção na hora.

  • Redes ruins

    Um heartbeat leve com back-off; depois de três falhas, uma verificação de presença por minuto, e o gateway acorda a página quando for preciso.

  • 11 idiomas

    Interface do celular, console e textos para o agente em 11 idiomas, incluindo o árabe da direita para a esquerda. Traga seus próprios pacotes e a sua própria redação.

  • Qualquer cliente MCP

    Streamable HTTP em /v1/mcp para Claude Code, Codex, Cursor e companhia; uma bridge stdio minúscula para todo o resto.

Todas as ferramentas 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

04Destaques

Feito para os bugs que só acontecem lá fora

Três coisas que um cabo, uma porta de depuração remota ou uma gravação de tela não dão a você.

Log da sessão · guardado no dispositivo

O bug já aconteceu? O log ainda está no celular.

Desde o momento em que o app abre, o SDK escreve um log da sessão no IndexedDB do dispositivo: páginas visitadas, os toques e as digitações do usuário, a saída do console e todas as requisições — as que falharam com cabeçalhos e corpos. Nada é transmitido para lugar algum; o log fica no celular, sob as mesmas regras de mascaramento, até que um agente aprovado pelo usuário o peça com get_session_overview e get_session_log. As três últimas inicializações são mantidas, com até 10 MB cada.

Patch ao vivo · evaluate_script

Verifique a correção no celular do cliente, antes de publicar.

Com a aprovação avançada do usuário, evaluate_script roda dentro da página — então o agente pode corrigir um estado errado, sobrescrever uma função ou renderizar uma tela de novo e ver o resultado no aparelho de verdade: um patch ao vivo que prova o diagnóstico. Ele vive só na memória daquela página; nada é persistido, e cliques sensíveis continuam precisando do sim do usuário.

Nativo para agentes · MCP

Feito para agentes, não para uma pessoa com o DevTools aberto.

Todo resultado de ferramenta termina com o que mudou no dispositivo desde a última chamada, então o agente nunca fica fazendo polling. O conteúdo da página é entregue como dado não confiável. Um cartão de tarefa no celular mostra o plano do agente, e o gateway fala o idioma do agente — descrições e resultados das ferramentas em 11 idiomas.

05Privacidade e controle

O celular do usuário continua sendo do usuário

Depuração remota só funciona se as pessoas confiarem nela. Toda sessão é visível, aprovada e interrompível.

  • Aprovação antes de tudo

    Um agente pede para se conectar; o usuário vê quem está pedindo e escolhe um nível no celular. Só toques de verdade valem — um script não consegue se aprovar.

  • Assumir ou encerrar, quando quiser

    Enquanto o agente trabalha, a página fica bloqueada atrás de uma borda luminosa. Um toque em Assumir pausa o agente; Encerrar o desconecta.

  • Mascarado por padrão

    Senhas e tudo que estiver marcado com data-rwd-mask aparecem como •••• em snapshots, capturas de tela, console, dados de rede e no log da sessão. Adicione seletores e expressões regulares por projeto.

  • Cliques sensíveis precisam de um sim

    Marque botões com data-rwd-confirm (“Enviar pedido”, “Excluir conta”) e o usuário confirma cada clique do agente neles.

  • Níveis de permissão

    observe lê, interact opera, advanced acrescenta scripts, corpos de requisição e armazenamento. Com limite por chave e por projeto.

  • Log de auditoria

    Cada conexão, aprovação, RPC e tomada de controle é registrada com quem, o quê e quando — nunca o conteúdo da página nem os valores dos parâmetros.

06Apps nativos

No seu app, é um user script

Baixe o SDK uma vez e injete-o no início do documento — WKUserScript no iOS, addDocumentStartJavaScript no Android. Suas páginas web não mudam em nada.

  • Um código do dispositivo em toda parte

    Passe um deviceId estável (e guarde o deviceToken) para que o código continue o mesmo entre WebViews e domínios.

  • Controles nativos

    Mostre seus próprios botões de assumir / devolver / encerrar com nativeControl(); scripts da página não conseguem chamá-lo.

  • Diálogos de aprovação nativos

    nativeApproval: true entrega os pedidos de conexão e as confirmações para a interface do seu próprio app.

  • Capturas com pixels reais

    Uma bridge pequena (snapshot do WKWebView, bitmap no Android) dá ao agente pixels de verdade em vez de uma renderização do 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-hospedado

Um binário Go. Seus servidores. Seus dados.

O gateway embute o console web e o SDK da página. SQLite de fábrica, Postgres quando você precisar, Docker Compose e Caddy para o HTTPS.

  • Console

    Dispositivos, chaves de API, membros e papéis, convites por QR code, políticas e um log de auditoria — além de um guia de integração já preenchido com as suas chaves.

  • Armazenamento

    Arquivo SQLite por padrão; defina RWD_DATABASE_URL=postgres://… para usar Postgres.

  • Operação

    Métricas do Prometheus em /v1/metrics, URLs do SDK versionadas com SRI, health check em /v1/healthz.

Guia de implantação

Início rápido
# um contêiner: console + 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

# ou compile, publique e tenha HTTPS com o 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
# → gateway  https://rwd.example.com/v1  (MCP em /v1/mcp)

O servidor só precisa do Docker; compilar a partir do código-fonte exige Go e Node.

08Perguntas frequentes

O que as pessoas perguntam

O usuário precisa instalar alguma coisa?

Não. Em páginas H5, o SDK faz parte da sua página. Em um app, você o injeta pelo código nativo. O usuário só vê uma pequena pílula com o código do dispositivo e, quando um agente se conecta, um diálogo de aprovação.

O que o agente consegue ver e fazer?

Só o que o usuário aprovou: as páginas WebView daquele dispositivo, no nível concedido. Ele nunca controla nada fora da WebView. Campos mascarados continuam mascarados, e o conteúdo da página é passado ao modelo como dado não confiável.

O bug aconteceu antes de o agente se conectar. Está perdido?

Não. O SDK mantém um log da sessão no dispositivo desde que o app abriu — páginas, toques, console e requisições — então um agente que se conecta depois lê todo o caminho até o bug com get_session_log. Fora isso, o log nunca sai do celular.

O agente consegue corrigir o bug no celular?

Ele consegue verificar uma correção: no nível advanced, evaluate_script aplica um patch na página em execução, em memória — corrigir um estado, sobrescrever uma função, renderizar de novo — e o agente vê se o problema desaparece. A correção de verdade continua indo pelo seu processo de release normal; nada é persistido no dispositivo.

Com quais agentes funciona?

Com qualquer cliente MCP. O Claude Code, o Codex e o Cursor usam direto o endpoint Streamable HTTP hospedado; clientes que só falam stdio usam rwd mcp, uma bridge pequena para o mesmo endpoint.

Quais plataformas são suportadas?

Qualquer WebView ou navegador móvel moderno: WKWebView no iOS, Android System WebView, navegadores dentro de apps e o Safari ou o Chrome do celular. Navegadores de desktop também funcionam.

E em redes ruins ou com o WebSocket bloqueado?

A página mantém um WebSocket de heartbeat leve com back-off exponencial. Se ela não conseguir se conectar três vezes seguidas, passa a uma verificação de presença por minuto, e o gateway a acorda quando um agente quiser se conectar.

Isso deixa a minha página mais lenta?

É uma tag script. Os registros de console e de rede ficam em ring buffers limitados (500 entradas cada, corpos de resposta limitados a 5 MB), o log da sessão é escrito em segundo plano e uma conexão ociosa só troca heartbeats.

Funciona junto com eruda, vConsole ou PageSpy?

Sim — os nós deles são ignorados pelos snapshots e pelo hit-testing, o nosso próprio tráfego fica fora dos logs de rede deles, e ele pode até viver como uma aba dentro do eruda.

A demo acima é real?

O SDK é real e sem modificações; só o gateway é simulado no seu navegador. Um shim de WebSocket faz um túnel da conexão do SDK até ele com postMessage, e um agente roteirizado envia os mesmos RPCs que um gateway real enviaria. Para ver a coisa real de ponta a ponta, teste com o seu próprio agente.