Playwright MCP no Claude Code/Codex: o snapshot de acessibilidade na prática
O Playwright MCP dá um navegador ao seu agente de código. Ele não manda captura de tela: manda o snapshot de acessibilidade, com uma referência (ref) em cada controle, e o agente age por essas refs. Nesta aula um script faz exatamente as chamadas que o agente faria, sem modelo, e depois você liga o servidor ao Claude Code ou ao Codex.
3O erro comum: tirar o snapshot antes de a página terminar
4Ligar ao Claude Code (.mcp.json) e ao Codex (config.toml)
Objetivo: fazer pelo Playwright MCP o que o agente faz: ler o snapshot, achar o controle pela ref e agir, e ligar o servidor ao seu agente.
01 · Do snapshot ao clique
Clique em cada bloco.
Depois de agir, um snapshot novo
Clique em cada bloco do diagrama para ver o que ele faz.
A ref vale para aquele snapshot. Mudou a página, tire outro.
02 · O que o agente recebe e o que ele faz
Lendo a saída do ensaio.
1. As ferramentas
O servidor expõe 25 ferramentas de navegador (browser_navigate, browser_snapshot, browser_click, browser_type, browser_select_option, browser_wait_for, browser_console_messages…). O agente vê todas na lista e escolhe.
A documentação do projeto hoje também recomenda um caminho por CLI e skills para agentes de código; o kit usa as ferramentas por MCP, que é o que o Claude Code e o Codex leem.
2. Refs, não coordenadas
No ensaio, o script achou textbox "Seu nome" = e13, combobox "Serviço" = e15 e button "Ver horários" = e18 e agiu por elas. Nada de pixel.
É por isso que o HTML do curso 0 importa: o rótulo vira nome, e o nome é como o agente acha a ref.
3. Esperar a prova
Os horários chegam 1,5 s depois do clique. Com browser_wait_for esperando o texto "horários livres para", o snapshot vem completo. Sem esperar, vem "Carregando horários…" e zero horários.
Espere pelo texto que prova o resultado, não por um número de segundos.
Quem paga o erroUm agente que tira o snapshot cedo demais responde "não há horários" com toda a confiança. A aula 7 volta a esse caso.
03 · O ensaio: as chamadas do agente, sem modelo
O ver-como-agente.mjs liga o Playwright MCP por stdio, como o Claude Code faria, e faz a tarefa "ver os horários de Revisão completa".
Terminal · fazer a tarefa pelo Playwright MCP
cd ~/projetos/formacao-webmcp-navegador-v72/kit
node ver-como-agente.mjs; echo "saída: $?"
Terminal · o mesmo, sem esperar a lista
cd ~/projetos/formacao-webmcp-navegador-v72/kit
node ver-como-agente.mjs --sem-esperar; echo "saída: $?"
Exemplo do repositório
→ browser_navigate {"url":"http://127.0.0.1:PORTA/agendar.html"}
→ browser_snapshot {}
achei: textbox "Seu nome" = e13 · combobox "Serviço" = e15 · button "Ver horários" = e18
→ browser_type {"target":"e13","text":"Ana"}
→ browser_select_option {"target":"e15","values":["Revisão completa"]}
→ browser_click {"target":"e18"}
→ browser_wait_for {"text":"horários livres para"}
→ browser_snapshot {}
status na página: 2 horários livres para Revisão completa em 2026-11-03.
tarefa: horários de Revisão completa em 2026-11-03 → 2 (08:00, 13:00) em 7 chamadas
saída: 0
Sete chamadas. Cada linha com → é uma ferramenta chamada pelo cliente MCP; PORTA substitui a porta aleatória do servidor local.
→ browser_navigate {"url":"http://127.0.0.1:PORTA/agendar.html"}
→ browser_snapshot {}
achei: textbox "Seu nome" = e13 · combobox "Serviço" = e15 · button "Ver horários" = e18
→ browser_type {"target":"e13","text":"Ana"}
→ browser_select_option {"target":"e15","values":["Revisão completa"]}
→ browser_click {"target":"e18"}
→ browser_snapshot {}
status na página: Carregando horários…
tarefa: horários de Revisão completa em 2026-11-03 → 0 (nenhum) em 6 chamadas
a lista ainda estava carregando quando o snapshot foi tirado
saída: 1
Sem browser_wait_for, o snapshot pega "Carregando horários…". O script sai com 1, mas um agente apressado diria que não há horário.
04 · O seu site e o seu agente
Primeiro só leitura no seu site; depois o servidor ligado ao Claude Code e ao Codex, com o Chromium do kit.
Terminal · snapshot de um site seu
cd ~/projetos/formacao-webmcp-navegador-v72/kit
node ver-como-agente.mjs https://inema.club/; echo "saída: $?"
Terminal · ligar ao Claude Code e ao Codex
cd ~/projetos/formacao-webmcp-navegador-v72/kit
node configurar.mjs && claude mcp get playwright; echo "saída: $?"
Exemplo do repositório
→ browser_navigate {"url":"https://inema.club/"}
→ browser_snapshot {}
- generic [active] [ref=e1]:
- banner [ref=e2]:
- generic [ref=e3]:
- link "INEMA.VIP Participe da Comunidade" [ref=e4] [cursor=pointer]:
- /url: https://inema.vip
- img "INEMA.VIP" [ref=e5]
- generic [ref=e6]: Participe da Comunidade
- link "INEMA.PRO Assine o INEMA.PRO" [ref=e7] [cursor=pointer]:
- /url: https://inema.pro
- img "INEMA.PRO" [ref=e8]
- generic [ref=e9]: Assine o INEMA.PRO
- generic [ref=e10]:
- heading "INEMA.CLUB Portal INEMA" [level=1] [ref=e11]
- paragraph [ref=e12]: "Aprenda Inteligência Artificial na prática: cursos, agentes, automação e comunidade"
- generic [ref=e13]:
(…)
ferramentas WebMCP vistas: 8 · buscar_conhecimento [readOnly], buscar_cursos [readOnly], comparar_cursos [readOnly], …
snapshot: 1040 linhas · 749 elementos com ref
saída: 0
Aqui o site é o inema.club, do próprio INEMA. Na sua máquina, troque pelo endereço de um site seu: agente de navegador só contra site seu. O resumo traz quantas linhas e refs o agente recebe; o inema.club tem token de origin trial, então o Chromium 156 do kit também viu as 8 ferramentas WebMCP dele, sem flag nenhuma.
Chromium do kit: chromium-1248/chrome-linux-arm64/chrome
escrevi kit/pw-config.json e kit/.mcp.json (servidores: playwright, devtools)
# Codex: cole em ~/.codex/config.toml se quiser os mesmos servidores lá
[mcp_servers.playwright]
command = "~/projetos/formacao-webmcp-navegador-v72/kit/node_modules/.bin/playwright-mcp"
args = ["--config", "~/projetos/formacao-webmcp-navegador-v72/kit/pw-config.json"]
[mcp_servers.devtools]
command = "~/projetos/formacao-webmcp-navegador-v72/kit/node_modules/.bin/chrome-devtools-mcp"
args = ["--headless", "--isolated", "--executablePath", "~/.cache/ms-playwright/chromium-1248/chrome-linux-arm64/chrome", "--no-usage-statistics", "--no-performance-crux", "--chromeArg=--no-sandbox"]
playwright:
Scope: Project config (shared via .mcp.json)
Status: ⏸ Pending approval (run `claude` to approve)
Type: stdio
Command: ~/projetos/formacao-webmcp-navegador-v72/kit/node_modules/.bin/playwright-mcp
Args: --config ~/projetos/formacao-webmcp-navegador-v72/kit/pw-config.json
To remove this server, run: claude mcp remove playwright -s project
saída: 0
O configurar.mjs escreve kit/.mcp.json (Claude Code, escopo de projeto) e imprime o trecho do Codex (na captura, ~ abrevia o caminho; o script imprime o caminho absoluto, que é o que o Codex precisa), que você cola em ~/.codex/config.toml se quiser. Servidor de projeto fica "Pending approval" até você abrir o claude dentro de kit/ e aprovar; depois, o /mcp mostra o servidor conectado (esse passo não foi capturado).
05 · Prática
O ensaio, o seu site e o seu agente. Cada exercício tem um "pronto quando".
E1 · As sete chamadas
10 min
Rode o ensaio e depois a versão sem esperar. Para cada linha com →, diga em uma frase o que o agente sabia naquele momento.
Pronto quando:node ver-como-agente.mjs → 2 (08:00, 13:00) em 7 chamadas e saída: 0; com --sem-esperar → 0 (nenhum) e saída: 1.
E2 · O snapshot do seu site
10 min
Rode o bloco de leitura com o endereço de um site seu. Abra a mesma página no navegador e ache três controles na saída pelo nome.
Pronto quando:node ver-como-agente.mjs com o endereço do seu site → snapshot: N linhas · M elementos com ref e saída: 0.
E3 · O servidor no seu agente
10 min
Rode o configurar.mjs. No Claude Code, abra o claude dentro de kit/ e aprove o servidor do projeto. No Codex, cole o trecho impresso no config.toml.
Pronto quando:claude mcp get playwright → Scope: Project config e, depois de aprovar, Status: ✓ Connected; no Codex, o servidor aparece na lista do /mcp.
06 · Teste da aula
Pergunta 1 de 4
No snapshot aparece textbox "Seu nome" [ref=e13]. Como o agente digita nesse campo?competência
Correto
O Playwright MCP age pela ref do snapshot. Coordenadas são o caminho do computer use; o console é outro servidor (aula 3).
Não é essa
O Playwright MCP age pela ref do snapshot. Coordenadas são o caminho do computer use; o console é outro servidor (aula 3).Rever: Do snapshot ao clique
Pergunta 2 de 4
O agente clicou em "Ver horários", tirou o snapshot na hora e viu "Carregando horários…". O que faltou?
Correto
browser_wait_for com o texto "horários livres para" espera a prova. Recarregar perde o que foi preenchido; clicar de novo dispara outra busca.