Playwright MCP : coût en tokens face à la lecture en markdown
Nous avons piloté le vrai serveur Playwright MCP et le markdown FastAF sur 11 pages publiques en comptant les tokens. Page médiane : 9 874 contre 5 083, avec des exceptions dans les deux sens.

Une lecture de page via Playwright MCP coûte une médiane de 9 874 tokens dans notre test, contre 5 083 pour les mêmes pages en markdown depuis FastAF. Soit environ deux fois plus de tokens, pas cent fois. L’écart est pourtant large : de 0,4x sur une page à 4x sur une autre. Nous avons mesuré 11 pages publiques le 19 octobre 2026 avec @playwright/mcp 0.0.83 et compté les tokens avec tiktoken o200k_base.
Nous n’avons trouvé aucune mesure par page de Playwright MCP que nous puissions reproduire, alors nous en avons fait une. La méthode et le script sont ci-dessous, avec les cas où le navigateur est le bon outil.
Combien de tokens Playwright MCP utilise-t-il par page ?
Nous avons lancé le vrai serveur (@playwright/mcp 0.0.83, la dernière version sur npm à cette date, avec Playwright 1.64 alpha) en headless via stdio, avec le SDK Python officiel de MCP comme client. Pour chaque page, le client a appelé browser_navigate puis browser_snapshot, et nous avons compté chaque caractère que le modèle aurait reçu. Dans la 0.0.83, browser_navigate ne renvoie qu’un lien vers un fichier de snapshot (78 à 168 tokens), donc lire la page demande le second appel. L’autre bras était FastAF /v1/scrape avec formats=markdown, en mode simple d’abord et dynamic=true seulement quand l’appel simple échouait ou que les phrases de contrôle manquaient.
« A fonctionné » signifie que deux phrases fixées à l’avance étaient présentes dans ce que le modèle verrait. Les tokens sont ceux du run 1 sur 3 et couvrent navigate plus snapshot.
| Page | HTML brut | Snapshot Playwright | Playwright --mobile |
Markdown FastAF |
|---|---|---|---|---|
| MDN, Fetch API (docs) | 41 439 | 7 481 | 6 367 | 4 110 |
| Docs Python, asyncio tasks (docs longues) | 50 276 | 34 405 | 33 354 | 15 236 |
| Article du Guardian (actualité) | 101 462 | 6 343 | 6 129 | 3 585 |
| Bibliothèque IKEA BILLY (produit) | 336 714 | 10 017 | 7 812 | 5 092 |
| Wikipedia, Model Context Protocol | 79 923 | 24 931 | 3 864 (replié) | 21 784 |
| GitHub, python-sdk (dépôt) | 135 152 | 9 874 | 6 807 | 5 083 |
| crates.io, serde (appli rendue en JS) | n/a (404) | 4 693 | 4 767 | 1 408 (5 crédits) |
| Page d’accueil de Hacker News (liste) | 11 694 | 13 649 | 13 649 | 3 365 |
| Article du blog d’ingénierie d’Anthropic | 51 697 | 11 689 | 11 447 | 6 115 |
| PyPI, requests (paquet) | 73 730 | 7 931 | 4 840 (mince) | 20 165 |
| GOV.UK, taux de TVA | 19 415 | 3 378 | 3 337 | 1 392 |
| Médiane, 11 pages | 51 697 | 9 874 | 6 367 | 5 083 |
| Total, 11 pages | 901 502 | 134 391 | 102 373 | 87 335 |
« HTML brut » est un simple GET, pour l’échelle. crates.io lui a renvoyé une coquille 404. Les temps étaient proches : une page Playwright à chaud a pris une médiane de 0,5 s (le premier appel après le lancement ajoutait 0,4 à 0,9 s), et FastAF une médiane de 0,5 s sur trois runs, avec le rendu dynamique à 6 à 7 s. Les comptes de tokens de Playwright ont varié de moins de 2 % entre les runs, sauf pour le Guardian (5 671 à 6 343) et la page GitHub (9 376 à 9 874). La sortie FastAF pour Wikipedia a été de 21 784 tokens dans deux appels et de 9 513 dans deux autres : lisez cette ligne comme une plage.
Pourquoi un snapshot est-il plus gros que du markdown ?
Un snapshot est un arbre d’accessibilité en YAML. Chaque nœud porte un rôle, un niveau d’imbrication et un identifiant [ref=...] pour que l’agent puisse cliquer dessus, et chaque lien dépense une ligne pour sa cible - /url:. Nous avons compté les seules lignes d’URL à 18 % des tokens du snapshot sur l’ensemble des pages (9 % sur les docs Python, 25 % sur Hacker News). Hacker News est le cas le plus net : sa mise en page en tableau devient table > rowgroup > row > cell sur plusieurs niveaux avant la première histoire, et le snapshot fait 4x le markdown.
Le markdown n’a pas de refs et presque pas de structure, donc les pages riches en prose sortent environ 2x plus petites. Deux pages n’ont pas suivi ce schéma. Le markdown de PyPI (20 165) a gardé toute la page, y compris la liste des fichiers et les classifiers, alors que le snapshot (7 931) non. Le markdown de Wikipedia était à 13 % du snapshot. Le résumé honnête : le snapshot est un peu plus gros sur la plupart des pages et c’est la structure que vous payez, mais une page très textuelle peut coûter plus cher en markdown.
Combien cela coûte-t-il en dollars ?
La page de tarifs d’Anthropic indique Claude Sonnet 5.5 à 2 $ le million de tokens d’entrée et Claude Fable 5.1 à 10 $ (les deux au 19 octobre 2026, page de tarifs). Nos comptes utilisent un tokenizer d’OpenAI, donc les comptes propres à Claude différeront un peu ; ce sont les rapports qu’il faut croire. Pour la page médiane :
| Pour 1 000 lectures de page | Tokens | Entrée Sonnet 5.5 | Entrée Fable 5.1 |
|---|---|---|---|
| HTML brut | 51,7 M | 103,39 $ | 516,97 $ |
| Snapshot Playwright MCP | 9,9 M | 19,75 $ | 98,74 $ |
Playwright MCP, --mobile |
6,4 M | 12,73 $ | 63,67 $ |
| Markdown FastAF | 5,1 M | 10,17 $ plus 1 000 crédits | 50,83 $ plus 1 000 crédits |
Avec le pack Starter (10 $ pour 20 000 crédits), 1 000 scrapes simples coûtent 0,50 $, donc FastAF atterrit autour de 10,70 $ sur Sonnet contre 19,75 $ pour le snapshot. C’est environ la moitié, et uniquement pour l’entrée. Une lecture de page reste aussi dans le contexte à chaque tour suivant, sauf si vous la mettez en cache ou la retirez, donc une longue session la paie plus d’une fois. Les définitions d’outils sont un coût fixe par session : Playwright MCP liste 25 outils (5 250 tokens), le serveur MCP FastAF 15 (3 831).
Peut-on rendre Playwright MCP moins cher ?
Oui, et le README du paquet le dit lui-même : il recommande Playwright CLI avec des skills pour les agents de code, parce qu’il garde les arbres d’accessibilité hors du contexte du modèle. Dans MCP, l’option --mobile (documentée comme économisant des tokens) a fait passer la médiane de 9 874 à 6 367 ici. Avec un piège. Sur Wikipedia, elle a fait tomber 24 931 tokens à 3 864 parce que la mise en page mobile replie les sections : 1 paragraphe dans le snapshot au lieu de 22. Sur PyPI, elle a perdu le champ licence et a échoué à notre contrôle. Ne lisez pas un snapshot plus petit comme le même contenu.
D’autres leviers existent dans la liste d’outils et nous ne les avons pas mesurés : browser_find renvoie les nœuds correspondants avec leur contexte au lieu de l’arbre entier, browser_snapshot accepte un depth et un filename, et browser_navigate écrit déjà dans un fichier plutôt que dans le chat. Si vous savez quelle partie de la page vous voulez, ceux-ci battront n’importe quelle lecture de page entière.
Quand le navigateur est-il le bon outil ?
Quand la tâche est de l’interaction : cliquer dans une interface, remplir un formulaire, un parcours derrière une connexion qui vous appartient, une page où l’étape suivante dépend de ce que le dernier clic a fait. Les refs du snapshot existent pour cela, et le markdown n’a rien sur quoi cliquer.
Nous avons aussi essayé une question Stack Overflow et l’avons retirée du tableau : elle a répondu par une page de contrôle anti-bot (HTTP 403), et FastAF a renvoyé 400 et 422 target_unavailable sans facturation. Les contrôles anti-bot d’un site relèvent de la décision de son propriétaire ; FastAF lit les pages publiques et n’essaie pas de les franchir, et nous n’avons pas fait de benchmark d’outils contre eux.
Les applications JavaScript sont le cas intermédiaire. Sur crates.io, le premier snapshot Playwright faisait 35 tokens parce que l’application n’avait pas chargé ; un second après une attente a donné 4 693. L’appel simple de FastAF a renvoyé 422, et le rendu avec dynamic=true a coûté 5 crédits et 1 408 tokens en 6,3 s. Voir pourquoi un fetch revient vide et le rendu JavaScript. Une correction : notre première phrase de contrôle pour crates.io ne correspondait pas à la façon dont la page découpe son texte, nous l’avons donc corrigée et relancé les deux outils sur cette page.
Quand le travail consiste à lire une page publique et à répondre à partir d’elle, lire suffit, et l’API de web scraping ou l’outil scrape_page le fait en un seul appel. Pour le branchement dans Claude Code, Cursor et Codex, voir la recherche web via MCP.
Comment reproduire ce test ?
import asyncio, os, sys, requests, tiktoken
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
enc = tiktoken.get_encoding("o200k_base")
tokens = lambda s: len(enc.encode(s, disallowed_special=()))
def fastaf_markdown(url, dynamic=False):
params = {"url": url, "formats": "markdown"}
if dynamic:
params.update(dynamic="true", wait=3000)
r = requests.get("https://api.fastaf.co/v1/scrape", params=params, timeout=120,
headers={"Authorization": f"Bearer {os.environ['FASTAF_API_KEY']}"})
return r.text if r.status_code == 200 else "", r.headers.get("X-FastAF-Credits-Used")
async def playwright_snapshot(urls):
# npm i @playwright/mcp@0.0.83 (the real server, over stdio, headless)
server = StdioServerParameters(command="node", cwd=os.getcwd(),
args=["node_modules/@playwright/mcp/cli.js", "--headless", "--isolated"])
out = {}
async with stdio_client(server) as (r, w), ClientSession(r, w) as s:
await s.initialize()
for url in urls:
nav = await s.call_tool("browser_navigate", {"url": url})
snap = await s.call_tool("browser_snapshot", {})
text = lambda res: "\n".join(c.text for c in res.content if c.type == "text")
out[url] = tokens(text(nav)) + tokens(text(snap))
return out
urls = sys.argv[1:]
pw = asyncio.run(playwright_snapshot(urls))
for url in urls:
md, credits = fastaf_markdown(url)
print(f"{url}\n playwright {pw[url]:>7,} tokens fastaf {tokens(md):>7,} tokens ({credits} credit)")
Exécuté le 19 octobre 2026 sur deux des pages ci-dessus, il a affiché :
https://www.gov.uk/vat-rates
playwright 3,038 tokens fastaf 1,392 tokens (1 credit)
https://news.ycombinator.com/
playwright 13,647 tokens fastaf 3,323 tokens (1 credit)
Le snapshot de GOV.UK est ressorti à 3 038 ici contre 3 378 dans le tableau, car les pages changent d’un run à l’autre. Notre run complet ajoutait les contrôles par phrases, un nouvel essai après 3 s d’attente pour les snapshots minces, trois répétitions et le bras --mobile. Partout, nous avons fait tourner Chromium sur un portable en Italie, et ce sont les mêmes URL que dans le tableau, vous pouvez donc les relancer.
En bref
Sur 11 pages publiques, une lecture Playwright MCP a pris une médiane de 9 874 tokens et le markdown 5 083 : environ la moitié, pas un centième. Le snapshot dépense des tokens en refs, rôles et URL ; --mobile l’allège mais peut perdre du contenu ; et le snapshot peut encore gagner sur des pages qui sont surtout de la structure. Utilisez le navigateur quand vous devez cliquer, saisir ou vous connecter à quelque chose qui est à vous, et lisez la page en markdown quand vous avez seulement besoin de ce qu’elle dit. Obtenez 500 crédits gratuits et lancez le script sur les pages que votre agent lit le plus. Les prix et limites sont sur la page de tarifs et dans la documentation.