playwright-trace-decoder-mcp
Servidor MCP para descompactar e analisar arquivos trace.zip do Playwright
Documentação
🎭 playwright-trace-decoder-mcp
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:
-
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.
-
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.
-
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
| Ferramenta | Argumentos | O que retorna |
|---|---|---|
get_test_metadata | trace_path | Navegador, plataforma, viewport, título do teste, horário de início em wall-clock |
get_trace_summary | trace_path | Ação com falha + erro de nível superior + contagem total de ações |
get_action_timeline | trace_path, limit, offset | Lista paginada de todas as ações com nomes de API, localizadores e tempos |
get_filtered_network_logs | trace_path, limit, offset | Apenas respostas 4xx/5xx — ativos estáticos (CSS, JS, fontes, imagens) removidos |
get_console_errors | trace_path, limit, offset | Exceções de JS e avisos do console do navegador |
get_element_state_at_failure | trace_path | Localizador com falha, mensagem de erro e metadados brutos antes/depois |
extract_trace_metadata_strict | trace_path | Versã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
| Ferramenta | Argumentos | O que retorna |
|---|---|---|
get_aria_accessibility_tree | trace_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_delta | trace_path, action_index | Diff 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_failure | trace_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_conditions | trace_path | Requisições de rede em andamento quando uma interação ou asserção disparou |
correlate_dom_and_network | trace_path | Para 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_frames | trace_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
| Ferramenta | Argumentos | O que retorna |
|---|---|---|
get_causal_chain_for_failure | trace_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_signature | trace_path | Hash SHA-1 estável de 12 caracteres do erro normalizado — use para agrupar falhas duplicadas em execuções paralelas de CI |
compare_traces | passing_trace_path, failing_trace_path | Sequê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_source | trace_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
| Ferramenta | Argumentos | O que retorna |
|---|---|---|
detect_performance_anomalies | trace_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_archive | trace_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_summary → get_causal_chain_for_failure → get_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 MCPadm-zip— extração de zipzodv4 — 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