Aller au contenu principal

Playwright MCP : le guide pratique approfondi (2026)

Intermédiaire

Le playwright-mcp de Microsoft est à ~35k étoiles GitHub et — selon les registres MCP maintenus par la communauté — est actuellement le serveur MCP le plus installé de la planète, classé devant même les serveurs MCP officiels GitHub et Figma. Si vous utilisez Claude Code, Cursor, Codex, Windsurf ou Claude Desktop et que vous avez déjà demandé à votre agent de « vérifier le site » ou « attraper des données de ce dashboard », c'est cet outil qui fait le vrai travail.

Presque tous les guides s'arrêtent à l'installation en deux lignes. Cette page est la partie qui compte après : ce que l'outil fait vraiment sous le capot, les modes que les gens ne réalisent pas exister, et les bords tranchants — coût en tokens, sécurité, verrouillage de profil de navigateur — qui apparaissent vers la deuxième semaine.

What you'll learn
  • Comprendre pourquoi le mode snapshot d'accessibilité (défaut) n'est pas juste plus rapide que la vision — c'est un paradigme d'automatisation différent que le LLM traite déterministiquement
  • Connaître les trois modes de profil — persistant, isolé, extension navigateur — et quand chacun est le bon choix
  • Activer les packs de capacités opt-in (network, storage, devtools, vision, pdf, testing) avec --caps et comprendre pourquoi ils sont désactivés par défaut
  • Voir le vrai coût en tokens de Playwright MCP dans une session Claude Code et savoir quand Playwright-comme-Skill gagne à la place
  • Déployer Playwright MCP comme serveur HTTP/SSE standalone, en Docker, et en sécurité pour des runs autonomes (le masquage de secrets est une commodité, pas une frontière)

Pourquoi ce serveur a mangé l'écosystème

Playwright MCP est l'implémentation de référence de « donner un navigateur à un LLM », et il a fait deux paris de design qui se sont avérés corrects :

  1. Snapshots d'accessibilité structurés comme interface primaire — pas des captures d'écran. Le modèle obtient un arbre compact et déterministe d'éléments (rôles, noms, refs). Pas de modèle vision requis, pas d'hallucination de coordonnées, tokens dépensés sur la structure plutôt que sur les pixels.
  2. Le vrai moteur d'automatisation de Playwright dessous — mêmes attentes, mêmes vérifications d'auto-actionnabilité, même système de locators qui a durci pendant des années de QA en production. Rien de bespoke.

Résultat : sur une installation fraîche, vous obtenez environ 50+ outils à travers navigation, remplissage de formulaires, onglets, snapshots, captures d'écran, accès console, inspection réseau, et quelques catégories opt-in. C'est beaucoup de surface — ce qui nous amène droit à la première chose qui surprend les gens.

Le mode que vous faites vraiment tourner

Par défaut, le serveur MCP tourne en mode snapshot d'accessibilité. Quand votre agent appelle browser_snapshot, il n'obtient pas une capture d'écran — il obtient un arbre façon YAML :

- Page URL: https://example.com/login
- role: main
- role: form
- role: textbox, name: "Email", ref: e12
- role: textbox, name: "Password", ref: e13
- role: button, name: "Sign in", ref: e14

L'agent appelle ensuite browser_click({ ref: "e14" }) — pas de sélecteurs CSS qu'il aurait inventés, pas de coordonnées qu'il aurait devinées. ref est un handle que le serveur a frappé depuis le locator Playwright sous-jacent, donc le clic est aussi fiable qu'un page.getByRole('button', { name: 'Sign in' }).click() écrit à la main.

C'est pourquoi les gens qui viennent des scripts Selenium/Puppeteer écrits par un LLM pensent « l'usage du navigateur par l'IA est cassé » — ils nourrissaient le modèle avec du HTML brut ou des captures d'écran. Le mode snapshot n'a pas ce mode d'échec, parce que le modèle ne voit jamais un sélecteur qu'il pourrait rater.

Pro tip
  • Si votre agent devine des sélecteurs CSS, vous utilisez presque certainement un MCP navigateur différent — ou vous avez désactivé les snapshots.
  • Les snapshots sont page-scoped. Pour les iframes, utilisez browser_snapshot dans l'iframe explicitement ; l'outil expose la navigation iframe.
  • Les refs sont éphémères. Elles ne sont valides que jusqu'à la prochaine mutation de page — traitez-les comme des IDs fiber React.

Packs de capacités opt-in (--caps)

Seuls les outils ennuyeux et sûrs sont livrés activés. Les puissants vivent derrière le flag --caps et vous les activez par serveur :

{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--caps=network,storage,pdf"]
}
}
}
CapCe que ça débloquePourquoi c'est désactivé par défaut
networkMock des requêtes, mode offline, interception de routePeut réécrire silencieusement le trafic ; a besoin d'intention
storageLecture/écriture cookies, localStorage, sessionStorageLe vol de données same-origin est trivial une fois activé
devtoolsTracing, enregistrement vidéo, mise en surbrillance d'élémentArtefacts très grands, coût disque
visionActions souris à coordonnées pixelContourne le modèle déterministe — voir plus bas
pdfSauver la page courante en PDFOK, juste du bruit pour la plupart des sessions
testingVérification élément/texte/valeur, génération de locatorNiche de test-authoring, ajoute ~une douzaine d'outils
configRelire la config serveur résolueDebug-only

Le non évident est vision. L'activer donne au modèle browser_mouse_move_at_coordinates et amis. Ça change aussi silencieusement le profil d'échec de toute la session, parce que l'agent basculera sur le clic par coordonnées quand les snapshots sont inconvénients — et maintenant vous avez un navigateur conduit par un modèle de langue qui fait des maths de pixels. Activez-le seulement quand un élément canvas ou un widget cassé côté a11y vous force la main.

Les trois modes de profil

C'est là où vit le design intéressant.

Guided walkthrough1 of 3
  1. Le serveur lance Chromium contre un répertoire user-data par workspace (chemin dérivé d'un hash de votre dossier de travail). Cookies, localStorage, mots de passe sauvegardés, historique persistent à travers les sessions. Super pour les dashboards authentifiés. Bord tranchant : une seule instance peut tenir le profil à la fois — une seconde fenêtre Claude Code contre le même dossier échouera. Pointez --user-data-dir sur un emplacement partagé et vous pouvez partager l'état à travers les projets.

Installation : les quatre configs que vous voulez vraiment

Standard local (Claude Desktop / Claude Code / Cursor)

{
"mcpServers": {
  "playwright": {
    "command": "npx",
    "args": ["@playwright/mcp@latest"]
  }
}
}

Isolé + auth préchargée (CI-ish, reproductible)

{
"mcpServers": {
  "playwright": {
    "command": "npx",
    "args": [
      "@playwright/mcp@latest",
      "--isolated",
      "--storage-state", "/Users/me/.auth/github.json",
      "--caps=network"
    ]
  }
}
}

S'attacher à mon vrai onglet Chrome (extension navigateur)

{
"mcpServers": {
  "playwright": {
    "command": "npx",
    "args": ["@playwright/mcp@latest", "--extension"]
  }
}
}

Serveur HTTP standalone (partager un navigateur entre plusieurs agents)

# One-time on your workstation:
npx @playwright/mcp@latest --port 8931

# Then every client points at it:
{
"mcpServers": {
  "playwright": { "url": "http://localhost:8931/mcp" }
}
}

Le mode HTTP est celui que les gens ratent. Si vous faites tourner quatre agents de code sur la même machine, quatre installations npx séparées de Playwright MCP lancent chacune leur propre Chromium. Un serveur HTTP partagé garde une seule pool de navigateurs, ce qui est à la fois moins cher et plus facile à observer.

Docker : la seule recette « serveur headless » supportée

# One-shot (stdio):
docker run -i --rm --init --pull=always mcr.microsoft.com/playwright/mcp

# Long-lived HTTP server on port 8931:
docker run -d -i --rm --init --pull=always \
--entrypoint node \
-p 8931:8931 \
mcr.microsoft.com/playwright/mcp \
/app/cli.js --headless --browser chromium --no-sandbox --port 8931 --host 0.0.0.0

Deux choses que les docs enterrent : l'image Docker est Chromium headless seulement (pas de Firefox, pas de WebKit, pas de mode headed), et --no-sandbox est requis dans le conteneur. Si vous avez besoin de Firefox ou d'un vrai GPU, faites tourner le serveur sur l'hôte.

La bataille du coût en tokens : MCP vs Skill vs CLI brut

L'autre chose dont personne ne vous prévient : Playwright MCP est le serveur unique le plus lourd que vous puissiez attacher à Claude Code, à environ 3 500 tokens d'overhead de schéma d'outil par session — avant d'avoir fait un seul appel. Ce chiffre vit dans votre fenêtre de contexte pour toute la conversation.

Les mesures rapportées par la communauté (lien plus bas) placent une tâche typique « teste ce site » à :

ApprocheTokens pour la tâcheCoût Sonnet (approx)
Playwright MCP (caps défaut)~114k~0,34 $
Playwright CLI + un fichier Skill~27k~0,08 $

L'approche Skill livre un petit SKILL.md qui documente le CLI de Playwright et laisse l'agent shell-out avec bash. Le schéma d'outil reste hors du contexte du modèle jusqu'à ce qu'il soit nécessaire, et le fichier skill lui-même est lu une fois. Les versions récentes de Playwright MCP ont réduit cet écart en ne streamant plus l'état complet de la page à chaque appel, mais l'overhead de schéma reste l'overhead de schéma.

Règle du pouce : MCP pour du travail interactif/exploratoire où le modèle a besoin d'un aller-retour conversationnel avec le DOM. Skill/CLI pour des jobs répétables — capturer une liste d'URLs, faire tourner une suite de tests, ou tout ce que vous mettriez dans un cron.

Voir la page Claude Code sur coût en tokens MCP pour comment mesurer ça dans votre propre session.

Le masquage de secrets est une commodité, pas une frontière

Playwright MCP supporte une map secrets dans sa config :

{
"secrets": {
"OPENAI_API_KEY": "sk-real-key-here",
"GITHUB_TOKEN": "ghp_real"
}
}

Quand le serveur voit ces chaînes exactes dans une réponse d'outil, il substitue le nom de la clé avant de forwarder le résultat au modèle. C'est vraiment utile — le contenu de page qui echo votre clé API ne le fuitera plus dans la transcription LLM.

Mais le README du projet est explicite et le répète plusieurs fois : « Playwright MCP n'est pas une frontière de sécurité. » Concrètement :

  • Une page peut rendre votre secret dans un attribut title ou en base64 et le masker ne l'attrapera pas.
  • Tout ce que le modèle demande au navigateur de faire — y compris des lectures document.cookie via un truc de champ de formulaire — s'exécute toujours avec l'autorité de votre vrai profil.
  • Le mode extension s'attache à votre Chrome de tous les jours. Chaque onglet connecté devient joignable en principe.

Traitez un agent avec Playwright MCP + profil persistant comme vous traiteriez un nouvel employé avec vos cookies admin : bien pour des tâches étroites et supervisées, catastrophique en --dangerously-skip-permissions. Voir Navigateurs agentiques & confiance same-origin et Ce que votre agent upload pour le modèle de menace plus large.

Ce qui a changé récemment

Les releases récentes (ligne v0.0.79) valent la peine d'être connues parce qu'elles changent les défauts :

  • --timeout-settle — le serveur attend maintenant un nombre configurable de ms (défaut 500) après chaque action pour que le travail déclenché se stabilise avant de retourner. Élevez pour les SPAs lentes, baissez pour les tests de perf.
  • Captures d'écran WebPbrowser_take_screenshot accepte type: "png" | "jpeg" | "webp" et infère depuis le nom de fichier. WebP est environ 30–50 % plus petit que PNG pour la même qualité, ça vaut le coup de changer si vous capturez beaucoup.
  • Sortie codegen pour Python / Java / C# — la cap testing peut maintenant émettre des squelettes de test dans plus que TypeScript.
  • Détection d'événement de téléchargement — remplace l'inférence basée sur erreur précédente ; les téléchargements déclenchent maintenant un vrai événement pour que les agents puissent les attendre.
  • Relais CDP extension navigateur — durci avec validation d'en-tête sur l'upgrade WebSocket.

Playbook de débogage

Guided walkthrough1 of 5
  1. Le snapshot est périmé. Faites appeler l'agent browser_snapshot à nouveau après chaque navigation ou soumission de formulaire — les refs du snapshot précédent sont mortes. S'il ne peut toujours pas trouver l'élément, le bouton peut être dans une iframe ou un Shadow DOM ; élargissez le scope du snapshot.

Concepts liés à garder droits

Aucune carte pour l'instant — ajoutez-en pour commencer à réviser. 🃏

Vérification rapide

Check yourself

0/5
  1. Par défaut, quand votre agent appelle browser_click, qu'est-ce qui identifie l'élément cible ?
  2. Vous voulez deux fenêtres Claude Code contre le même repo, les deux utilisant Playwright MCP avec votre profil connecté. Quel est le bon geste ?
  3. Quelle valeur --caps change le plus le profil de sécurité de votre session ?
  4. Pour un job batch répétable (capturer 200 URLs chaque nuit), quel est habituellement le bon outil ?
  5. Vous configurez la map secrets avec GITHUB_TOKEN=ghp_xxx. Une page inclut le token encodé en base64 dans un champ caché. Que se passe-t-il ?

Quand Playwright MCP est le mauvais outil

  • Vous avez besoin de login partagé avec une session de navigation humaine en cours. Envisagez un navigateur agent à login partagé comme celui couvert dans Agents navigateurs qui héritent de vos logins — le mode extension de Playwright MCP s'en approche, mais l'UX autour des approbations et des Spaces est différente.
  • Vous testez des chemins de code de production et voulez le vrai test runner Playwright. Utilisez @playwright/test directement ; le MCP est optimisé pour l'exploration agentique, pas pour l'authoring de tests CI.
  • La charge est 100 % scraping headless de HTML statique. Un simple fetch + parser est des ordres de grandeur moins cher. Gardez le navigateur pour les pages qui ont vraiment besoin d'exécution JavaScript.
  • Vous ne pouvez risquer aucune fuite d'état navigateur. Utilisez --isolated avec un snapshot --storage-state frais par run. N'utilisez pas le mode extension contre votre Chrome de tous les jours.

Sources et lectures complémentaires