Skip to content

Playwright MCP vs Playwright CLI: Which is More Token-Efficient for Claude?

Problem

When I use Claude Code for browser automation, I burn through tokens quickly. The browser state (DOM, screenshots, accessibility trees) gets sent back to Claude on every action. With a 1M context window, I still hit token limits on complex applications.

I wanted to know: which approach is more token-efficient - Playwright MCP or Playwright CLI?

Environment

  • Claude Code
  • Playwright MCP or Playwright CLI
  • Python/Node.js project

What happened?

I started using Playwright MCP for browser automation. It worked, but I noticed my token consumption was high. Every browser action sent a full accessibility snapshot back to Claude:

MCP approach - sends full browser state
const snapshot = await page.accessibility.snapshot();
// This snapshot data is transmitted to Claude, consuming tokens
// For a complex page, this can be thousands of tokens

Then I saw a Reddit comment that changed my approach:

“Playwright MCP is now surpassed with the Playwright CLI btw - it’s way more token efficient.”

So I tried the CLI approach instead.

How to solve it?

The solution was to switch from MCP to CLI. Here’s the difference:

MCP Approach (higher token consumption)

MCP sends full browser state to Claude:

MCP data flow
Browser Action → MCP Server → Serialize DOM/Accessibility Tree → Send to Claude (many tokens)

For a typical page, the accessibility tree alone can be 10,000+ tokens. Every interaction multiplies this.

CLI Approach (more token-efficient)

CLI sends only the command and minimal output:

CLI approach - minimal token overhead
await page.click('#submit-button');
await page.fill('#email', '[email protected]');
await page.screenshot({ path: 'result.png' });
CLI data flow
Command → Execute in Browser → Return success/failure + minimal output (few tokens)

The CLI sends structured commands, not state dumps. This dramatically reduces token consumption.

Scope your tests properly

Another key insight from the Reddit discussion:

“The one thing to guard against: no explicit scope means it’ll try to verify every possible state and torch your token budget on a big app.”

Bad approach - no scope:

Bad: No scope, explores everything
test('verify app works', async () => {
// Claude may try to click every button, fill every form...
// Token usage explodes exponentially
});

Good approach - explicit boundaries:

Good: Explicit scope and boundaries
test('login flow works correctly', async ({ page }) => {
await page.goto('/login');
await page.fill('#email', '[email protected]');
await page.fill('#password', 'password123');
await page.click('#submit');
await expect(page).toHaveURL('/dashboard');
});

You can see that I succeeded in reducing token consumption by switching to CLI and scoping tests properly.

The reason

I think the key reasons CLI is more efficient:

FactorMCPCLI
Data sentFull browser stateCommands only
Token cost per actionHigh (DOM snapshot)Low (command string)
Context pollutionBrowser state mixed with codeClean separation
Best forRich state analysisScripted test flows

MCP transmits the accessibility tree, DOM structure, and element states - useful for complex analysis but expensive.

CLI executes commands and returns minimal output - efficient for deterministic test flows.

Summary

In this post, I compared Playwright MCP vs CLI for token efficiency. The key point is CLI sends action commands rather than full browser state dumps, significantly reducing token consumption. Always define explicit test scope to prevent Claude from over-exploring application states.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments