playwright-trace-decoder-mcp

Servidor MCP para descompactar e analisar arquivos trace.zip do Playwright

Documentação

🎭 playwright-trace-decoder-mcp

npm version npm downloads CI License: MIT

Um servidor MCP que descompacta e estrutura arquivos trace.zip do Playwright para que agentes de IA possam realizar análise de causa raiz em falhas de CI — sem se afogar em JSON bruto ou estourar a janela de contexto.

🤔 O Problema

Quando um teste do Playwright falha no CI, você recebe um trace.zip. É um blob binário. LLMs não conseguem lê-lo nativamente, e despejar o conteúdo bruto excede a janela de contexto. Engenheiros acabam copiando trechos de logs para o ChatGPT manualmente, como se estivéssemos em 2022.

Este servidor MCP resolve isso: 16 ferramentas focadas que expõem exatamente o sinal que um agente precisa para diagnosticar uma falha, com paginação e compressão ARIA para manter os custos de tokens baixos.

🐸 Exemplo de Investigação de Falha E2E

Aqui está uma visão rápida de como um agente de IA usa as novas ferramentas na v0.3.0 para encontrar e inspecionar uma falha instantaneamente:

  1. Localize o bug exato no código-fonte via map_locator_to_source:

    // Request arguments
    { "trace_path": "/path/to/trace.zip" }
    
    // Response payload
    {
      "action_type": "Click locator('#super-toad-not-found')",
      "locator": "#super-toad-not-found",
      "error": "TimeoutError: locator.click: Timeout 5000ms exceeded.",
      "step_title": "Click locator('#super-toad-not-found')",
      "stack": [
        {
          "file": "/Users/albertdev/Projects/ideas/sample-playwright-project/tests/google-pom.spec.ts",
          "line": 18,
          "column": 17
        }
      ],
      "source_location": {
        "file": "/Users/albertdev/Projects/ideas/sample-playwright-project/tests/google-pom.spec.ts",
        "line": 18,
        "column": 17
      }
    }
    

    Chega de adivinhar! O agente sabe exatamente qual arquivo, linha e coluna causou o timeout.

  2. Extraia quadros visuais críticos em torno da falha via extract_critical_frames:

    // Request arguments
    { "trace_path": "/path/to/trace.zip", "limit": 1 }
    
    // Response payload
    [
      {
        "timestamp": 1779137404287,
        "mime_type": "image/jpeg",
        "step_title": "Clicking #super-toad-not-found element",
        "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/..." // Base64 JPEG
      }
    ]
    

    Permite que o agente verifique visualmente o estado da página imediatamente antes/depois da falha sem puxar listas enormes de imagens.

  3. Apare o trace para economizar armazenamento/custos de transferência no CI via trim_trace_archive:

    // Request arguments
    { "trace_path": "/path/to/trace.zip" }
    
    // Response payload
    {
      "original_size_bytes": 2449682,
      "trimmed_size_bytes": 511698,
      "compression_ratio_percent": 79,
      "trimmed_trace_path": "/path/to/trace.trimmed.zip"
    }
    

    Reduz traces grandes excluindo screenshots fora da janela crítica de falha. Economizou 79% de espaço em disco!

🛠️ Ferramentas

As ferramentas são agrupadas pela ordem em que um agente deve usá-las ao diagnosticar uma falha.

Inspeção — leitura de dados do trace

FerramentaArgumentosO que retorna
get_test_metadatatrace_pathNavegador, plataforma, viewport, título do teste, horário de início em wall-clock
get_trace_summarytrace_pathAção com falha + erro de nível superior + contagem total de ações
get_action_timelinetrace_path, limit, offsetLista paginada de todas as ações com nomes de API, localizadores e tempos
get_filtered_network_logstrace_path, limit, offsetApenas respostas 4xx/5xx — ativos estáticos (CSS, JS, fontes, imagens) removidos
get_console_errorstrace_path, limit, offsetExceções de JS e avisos do console do navegador
get_element_state_at_failuretrace_pathLocalizador com falha, mensagem de erro e metadados brutos antes/depois
extract_trace_metadata_stricttrace_pathVersão do formato, detalhamento de sessões de retry, modo de payload HAR (embed/attach/omit)

Todas as ferramentas que retornam listas suportam paginação com limit (1–500, padrão 50) e offset com um flag has_more.

trace_path aceita um caminho local absoluto ou uma URL HTTPS — o servidor baixa o arquivo automaticamente e o armazena em cache para a sessão.

Análise de DOM / UI

FerramentaArgumentosO que retorna
get_aria_accessibility_treetrace_path, action_index?Árvore de acessibilidade ARIA como YAML compacto (~90% menos tokens que HTML bruto). Padrão: snapshot na ação com falha.
get_dom_mutation_deltatrace_path, action_indexDiff de conjunto das linhas ARIA antes vs. depois de uma ação específica — apenas elementos adicionados/removidos, não dois dumps completos de DOM
get_screenshot_at_failuretrace_path, screenshot_index?Screenshot JPEG em base64 mais próximo do momento da falha. Use quando a árvore ARIA estiver vazia (captcha, página em branco). screenshot_index permite percorrer toda a linha do tempo visual.
analyze_race_conditionstrace_pathRequisições de rede em andamento quando uma interação ou asserção disparou
correlate_dom_and_networktrace_pathPara cada ação em que um fetch foi concluído e o DOM sofreu mutação dentro de ±100ms: URL de gatilho, status da resposta, trecho do corpo e nós exatos adicionados/removidos
extract_critical_framestrace_path, lookback_ms?, lookforward_ms?, limit?Extrai screenshots-chave do screencast (base64) de uma janela temporal em torno da falha, resolvidos com títulos de etapas

Análise de causa raiz

FerramentaArgumentosO que retorna
get_causal_chain_for_failuretrace_path, lookback_ms?Cadeia cronológica de ações anteriores, erros de rede e erros de console que levaram à falha (janela padrão: 5 s)
generate_error_signaturetrace_pathHash SHA-1 estável de 12 caracteres do erro normalizado — use para agrupar falhas duplicadas em execuções paralelas de CI
compare_tracespassing_trace_path, failing_trace_pathSequência de ações alinhada por LCS entre uma execução com falha e uma bem-sucedida: divergência estrutural, anomalias de tempo (>500 ms), ações sem correspondência, delta de rede
map_locator_to_sourcetrace_path, action_index?Mapeia uma interação de navegador com falha (ou índice de ação específico) para a linha exata do código de teste via pilha de execução do runner

Análise de desempenho

FerramentaArgumentosO que retorna
detect_performance_anomaliestrace_path, slow_action_threshold_ms?, frame_drop_threshold_ms?Lista classificada de ações lentas e quedas de frames com suspected_cause (thread principal bloqueada / saturação de rede / timeout de navegação). Também reporta duração p50/p95 das ações e um flag de vazamento de memória.
trim_trace_archivetrace_path, divergence_only?Reduz o zip do trace excluindo screenshots fora da janela crítica de falha (t_fail - 5s até t_fail + 1s). Retorna o caminho aparado e o delta de tamanho.

💬 Fluxo de trabalho sugerido para o agente

get_trace_summary              ← what failed?
get_causal_chain_for_failure   ← what led up to it?
get_aria_accessibility_tree    ← what did the page look like?
get_screenshot_at_failure      ← ARIA empty? get the actual screenshot
get_dom_mutation_delta         ← what changed right before the failure?
analyze_race_conditions        ← was a network request still pending?
correlate_dom_and_network      ← which fetch caused which DOM change?
compare_traces                 ← flaky? compare to a passing run
detect_performance_anomalies   ← timeout but no JS error? check for Long Tasks

🚀 Configuração

Compilar a partir do código-fonte

git clone https://github.com/vola-trebla/playwright-trace-decoder-mcp.git
cd playwright-trace-decoder-mcp
npm install
npm run build

Adicionar ao seu cliente MCP

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json)

{
  "mcpServers": {
    "playwright-trace-decoder": {
      "command": "node",
      "args": ["/absolute/path/to/playwright-trace-decoder-mcp/dist/index.js"]
    }
  }
}

Cursor (.cursor/mcp.json) ou VS Code (.vscode/mcp.json)

{
  "mcpServers": {
    "playwright-trace-decoder": {
      "command": "node",
      "args": ["/absolute/path/to/playwright-trace-decoder-mcp/dist/index.js"]
    }
  }
}

Claude Code

claude mcp add playwright-trace-decoder \
  node /absolute/path/to/playwright-trace-decoder-mcp/dist/index.js

Docker

docker build -t playwright-trace-decoder-mcp .
{
  "mcpServers": {
    "playwright-trace-decoder": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "-v", "/path/to/traces:/traces", "playwright-trace-decoder-mcp"]
    }
  }
}

💬 Exemplos de uso

Análise básica de falha

Pergunte ao seu agente:

"A execução do CI falhou. Aqui está o trace: /tmp/trace.zip. O que deu errado e por quê?"

O agente chama get_trace_summaryget_causal_chain_for_failureget_aria_accessibility_tree, aprofundando conforme necessário — sem você precisar copiar e colar nada.

Quando a página estava em branco ou redirecionada

"A árvore ARIA está vazia. Você pode me mostrar o que estava realmente na tela quando falhou?"

O agente chama get_screenshot_at_failure e obtém o JPEG tirado mais próximo do momento da falha — útil para capturar captchas, páginas de erro ou redirecionamentos inesperados.

Diagnóstico de flakiness

"Este teste passa localmente, mas falha no CI. Compare esses dois traces e me diga o que foi diferente."

O agente chama compare_traces, que alinha por LCS ambas as sequências de ações e revela a primeira divergência estrutural, anomalias de tempo e requisições de rede que só apareceram na execução com falha.

Agrupando falhas duplicadas em execuções paralelas de CI

"Temos 12 traces com falha deste pipeline. São todos a mesma falha?"

Chame generate_error_signature em cada um — assinaturas idênticas significam causa raiz idêntica, sem necessidade de ler cada trace.

Diagnosticando qual chamada de API causou uma mudança no DOM

"O modal apareceu, mas não sei qual fetch o acionou."

correlate_dom_and_network une o log HAR e os snapshots de DOM automaticamente. Exemplo de saída:

{
  "total_correlations": 1,
  "correlations": [
    {
      "action_id": "4:Locator.click",
      "triggering_request_url": "https://api.example.com/cart/items",
      "response_status_code": 200,
      "response_body_snippet": "{\"items\":[{\"id\":\"abc\",\"qty\":1}]}",
      "time_to_dom_mutation_ms": 38,
      "resulting_dom_mutations": [
        { "type": "added", "selector": "heading \"Cart (1 item)\"" },
        { "type": "removed", "selector": "button \"Add to cart\" [disabled]" }
      ]
    }
  ]
}

Timeouts de desempenho — não apenas elementos ausentes

"O teste dá timeout em goto, mas não há erro de JS. O que está bloqueando a página?"

detect_performance_anomalies inspeciona lacunas nos frames do screencast e sinaliza Long Tasks. Exemplo de saída:

{
  "anomalies": [
    {
      "kind": "slow_action",
      "blocked_action_id": "2:Frame.goto",
      "task_duration_ms": 4200,
      "threshold_ms": 500,
      "concurrent_network_load": 9,
      "frame_drop_count": 0,
      "worst_frame_gap_ms": 0,
      "suspected_cause": "network_saturation"
    }
  ],
  "suspected_memory_leak_flag": false,
  "p50_action_duration_ms": 95,
  "p95_action_duration_ms": 780,
  "total_frame_drop_count": 0
}

suspected_cause distingue uma thread principal bloqueada (main_thread_blocked — lacunas de frames presentes), uma cascata de fetches concorrentes (network_saturation — ≥5 em andamento) e um timeout de navegação/hard (timeout_or_navigation — duração >3 s sem outros sinais).

Verificando qual versão do Playwright e modo HAR um trace usa

"O trace veio de uma configuração de CI desconhecida. Os dados do corpo da resposta estão disponíveis?"

extract_trace_metadata_strict inspeciona o arquivo antes de você executar qualquer outra ferramenta:

{
  "format_version": 6,
  "har_mode": "embed",
  "retry_sessions": [
    { "session_id": "s1", "failed": false },
    { "session_id": "s2", "failed": true }
  ],
  "failed_session_id": "s2"
}

har_mode: "embed" significa que os trechos do corpo estão inline. "attach" significa que estão em arquivos de recursos separados. "omit" significa apenas cabeçalhos — nesse caso, correlate_dom_and_network retornará response_body_snippet vazio.

🏗️ Arquitetura

trace.zip
  ├── *.trace          → JSONL: before/after action pairs, console events, frame snapshots
  ├── *.network        → JSONL: HAR resource-snapshot entries
  └── resources/
      ├── page@*.jpeg  → screenshots taken during the run
      └── ...          → fonts, stylesheets, other captured resources

O parser transmite cada arquivo linha por linha (sem divisão de buffer completo) e armazena resultados em cache no processo com um LRU (máx. 50 entradas), indexado por caminho + mtime. Reler o mesmo trace não modificado custa zero I/O.

Os snapshots de frames armazenam o DOM como arrays aninhados (["TAG", {attrs}, ...children]). O tradutor ARIA percorre essa árvore e gera YAML compacto, reduzindo o custo de tokens em ~90% em comparação com HTML bruto.

🏗️ Stack

  • @modelcontextprotocol/sdk — runtime do servidor MCP
  • adm-zip — extração de zip
  • zod v4 — validação de schema de entrada
  • TypeScript, ESLint, Prettier, Husky, GitHub Actions CI

📋 Scripts

npm run build        # compile TypeScript → dist/
npm run lint         # ESLint
npm run format       # Prettier --write
npm run format:check # Prettier check (used in CI)

📄 Licença

MIT