Costo in token di Playwright MCP contro leggere le pagine in markdown

Abbiamo provato il vero server Playwright MCP e il markdown di FastAF su 11 pagine pubbliche contando i token. Pagina mediana: 9.874 contro 5.083, con eccezioni in entrambi i sensi.

Una lettura di pagina con Playwright MCP costa nel nostro test una mediana di 9.874 token, contro 5.083 per le stesse pagine in markdown da FastAF. È circa il doppio dei token, non cento volte. La forbice però è ampia: da 0,4x su una pagina a 4x su un’altra. Abbiamo misurato 11 pagine pubbliche il 19 ottobre 2026 con @playwright/mcp 0.0.83 e contato i token con tiktoken o200k_base.

Non abbiamo trovato una misura per pagina di Playwright MCP che potessimo riprodurre, quindi ne abbiamo fatta una. Metodo e script sono qui sotto, insieme ai casi in cui il browser è lo strumento giusto.

Quanti token usa Playwright MCP per pagina?

Abbiamo avviato il vero server (@playwright/mcp 0.0.83, l’ultimo su npm a questa data, con Playwright 1.64 alpha) in headless su stdio, con l’SDK Python ufficiale di MCP come client. Per ogni pagina il client ha chiamato browser_navigate e poi browser_snapshot, e abbiamo contato ogni carattere che il modello avrebbe ricevuto. Nella 0.0.83 browser_navigate restituisce solo un link a un file di snapshot (da 78 a 168 token), quindi leggere la pagina richiede la seconda chiamata. L’altro braccio era FastAF /v1/scrape con formats=markdown, prima in modo semplice e con dynamic=true solo se la chiamata semplice falliva o mancavano le frasi di controllo.

“Funzionato” significa che due frasi fissate in anticipo erano presenti in ciò che il modello avrebbe visto. I token sono quelli dell’esecuzione 1 su 3 e comprendono navigate più snapshot.

Pagina HTML grezzo Snapshot Playwright Playwright --mobile Markdown FastAF
MDN, Fetch API (documentazione) 41.439 7.481 6.367 4.110
Documentazione Python, asyncio tasks (documentazione lunga) 50.276 34.405 33.354 15.236
Articolo del Guardian (news) 101.462 6.343 6.129 3.585
Libreria IKEA BILLY (prodotto) 336.714 10.017 7.812 5.092
Wikipedia, Model Context Protocol 79.923 24.931 3.864 (ripiegato) 21.784
GitHub, python-sdk (repository) 135.152 9.874 6.807 5.083
crates.io, serde (app renderizzata via JS) n/d (404) 4.693 4.767 1.408 (5 crediti)
Home di Hacker News (elenco) 11.694 13.649 13.649 3.365
Post del blog di ingegneria di Anthropic 51.697 11.689 11.447 6.115
PyPI, requests (pacchetto) 73.730 7.931 4.840 (scarno) 20.165
GOV.UK aliquote IVA 19.415 3.378 3.337 1.392
Mediana, 11 pagine 51.697 9.874 6.367 5.083
Totale, 11 pagine 901.502 134.391 102.373 87.335

“HTML grezzo” è una semplice GET, per dare la scala. crates.io le ha risposto con un guscio 404. I tempi erano vicini: una pagina Playwright già calda ha impiegato una mediana di 0,5 s (la prima chiamata dopo l’avvio ne ha aggiunti da 0,4 a 0,9), e FastAF una mediana di 0,5 s su tre esecuzioni, con il rendering dinamico a 6-7 s. I conteggi di token di Playwright si sono mossi di meno del 2% fra le esecuzioni, tranne per il Guardian (da 5.671 a 6.343) e la pagina GitHub (da 9.376 a 9.874). L’output di FastAF per Wikipedia è stato 21.784 token in due chiamate e 9.513 in altre due, quindi considera quella riga un intervallo.

Perché uno snapshot è più grande del markdown?

Uno snapshot è un albero di accessibilità in YAML. Ogni nodo porta un ruolo, un livello di annidamento e un id [ref=...] perché l’agente possa cliccarlo, e ogni link spende una riga per la sua destinazione - /url:. Abbiamo contato le sole righe degli URL al 18% dei token dello snapshot sulle varie pagine (9% sulla documentazione Python, 25% su Hacker News). Hacker News è il caso più chiaro: il suo layout a tabella diventa table > rowgroup > row > cell annidato su vari livelli prima della prima notizia, e lo snapshot è 4 volte il markdown.

Il markdown non ha ref e ha pochissima struttura, quindi le pagine ricche di prosa escono circa 2 volte più piccole. Due pagine non hanno seguito questo schema. Il markdown di PyPI (20.165) ha tenuto l’intera pagina compresi elenco dei file e classificatori, mentre lo snapshot (7.931) no. Il markdown di Wikipedia era entro il 13% dello snapshot. La sintesi onesta è che lo snapshot è un po’ più grande sulla maggior parte delle pagine e quello che paghi è la struttura, ma una pagina con molto testo può costare di più in markdown.

Quanto costa in dollari?

La pagina dei prezzi di Anthropic elenca Claude Sonnet 5.5 a $2 per milione di token di input e Claude Fable 5.1 a $10 (entrambi al 19 ottobre 2026, pagina dei prezzi). I nostri conteggi usano un tokenizer di OpenAI, quindi i conteggi di Claude saranno un po’ diversi; fidati dei rapporti. Sulla pagina mediana:

Ogni 1.000 letture di pagina Token Input Sonnet 5.5 Input Fable 5.1
HTML grezzo 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 più 1.000 crediti $50,83 più 1.000 crediti

Sul pacchetto Starter ($10 per 20.000 crediti) 1.000 scrape semplici costano $0,50, quindi FastAF arriva a circa $10,70 su Sonnet contro $19,75 dello snapshot. È circa la metà, ed è solo l’input. Una pagina letta resta inoltre nel contesto per ogni turno successivo a meno che tu non usi la cache o la scarti, quindi una sessione lunga la paga più di una volta. Le definizioni dei tool sono un costo fisso per sessione: Playwright MCP elenca 25 tool (5.250 token), il server MCP di FastAF 15 (3.831).

Si può rendere Playwright MCP più economico?

Sì, e lo dice lo stesso README del pacchetto: raccomanda Playwright CLI con le skill per gli agenti di coding perché tiene gli alberi di accessibilità fuori dal contesto del modello. All’interno di MCP, il flag --mobile (documentato come risparmio di token) ha portato qui la mediana da 9.874 a 6.367. Ha un tranello. Su Wikipedia ha ridotto 24.931 token a 3.864 perché il layout mobile ripiega le sezioni: 1 paragrafo nello snapshot invece di 22. Su PyPI ha perso il campo della licenza e ha fallito il nostro controllo. Non leggere uno snapshot più piccolo come lo stesso contenuto.

Altre leve esistono nell’elenco dei tool e non le abbiamo misurate: browser_find restituisce i nodi corrispondenti con il loro contesto invece dell’intero albero, browser_snapshot accetta una depth e un filename, e browser_navigate scrive già su file invece che nella chat. Se sai quale parte della pagina ti serve, quelle batteranno qualsiasi lettura dell’intera pagina.

Quando il browser è lo strumento giusto?

Quando il compito è l’interazione: cliccare in un’interfaccia, compilare un modulo, un flusso dietro un login che è tuo, una pagina in cui il passo successivo dipende da cosa ha fatto l’ultimo clic. I ref nello snapshot esistono per questo, e il markdown non ha niente da cliccare.

Abbiamo provato anche una domanda di Stack Overflow e l’abbiamo lasciata fuori dalla tabella: ha risposto con una pagina di verifica anti-bot (HTTP 403), e FastAF ha restituito 400 e 422 target_unavailable senza addebito. I controlli anti-bot di un sito sono una decisione del proprietario; FastAF legge pagine pubbliche e non cerca di superarli, e non abbiamo messo alla prova gli strumenti contro di essi.

Le app JavaScript sono il caso di mezzo. Su crates.io il primo snapshot di Playwright era di 35 token perché l’app non si era caricata; un secondo dopo un’attesa ne ha dati 4.693. La chiamata semplice di FastAF ha restituito 422, e il rendering con dynamic=true è costato 5 crediti e 1.408 token in 6,3 s. Vedi perché un fetch torna vuoto e il rendering JavaScript. Una correzione: la nostra prima frase di controllo per crates.io non corrispondeva a come la pagina spezza il testo, quindi l’abbiamo sistemata e rieseguito entrambi gli strumenti su quella pagina.

Quando il lavoro è leggere una pagina pubblica e rispondere da essa, la lettura basta, e la web scraping API o il tool scrape_page la fanno in una chiamata. Per il collegamento in Claude Code, Cursor e Codex, vedi la ricerca web via MCP.

Come lo riproduco?

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)")

Eseguito il 19 ottobre 2026 su due delle pagine sopra, ha stampato:

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)

Lo snapshot di GOV.UK è risultato di 3.038 qui contro 3.378 in tabella perché le pagine cambiano da un’esecuzione all’altra. La nostra esecuzione completa ha aggiunto i controlli sulle frasi, un nuovo tentativo dopo un’attesa di 3 s per gli snapshot scarni, tre ripetizioni e il braccio --mobile. In tutto abbiamo fatto girare Chromium su un portatile in Italia, e gli URL sono gli stessi della tabella, quindi puoi rieseguirli.

La versione breve

Su 11 pagine pubbliche una lettura con Playwright MCP ha richiesto una mediana di 9.874 token e il markdown 5.083: più o meno la metà, non un centesimo. Lo snapshot spende token su ref, ruoli e URL; --mobile lo riduce ma può far cadere contenuto; e lo snapshot può comunque vincere sulle pagine fatte soprattutto di struttura. Usa il browser quando devi cliccare, digitare o accedere a qualcosa di tuo, e leggi la pagina in markdown quando ti serve solo ciò che dice. Prendi 500 crediti gratuiti e fai girare lo script sulle pagine che il tuo agente legge di più. Prezzi e limiti sono nella pagina dei prezzi e nella documentazione.