If you are wiring a coding agent to a real browser this year, the CLI vs MCP browser automation question shows up before you write a single line of glue code. Do you stand up a Model Context Protocol server that exposes browser_navigate, browser_click, browser_snapshot and a dozen siblings as tools the model calls one at a time? Or do you hand the model a single shell command it runs like any other binary on the PATH? The two shapes look interchangeable in a demo. They are not interchangeable once you count tokens, and tokens are where the "CLI beats MCP" narrative that took over agent engineering discussions in late 2025 actually comes from.
I have built both. I have watched an agent burn 44,000 tokens to answer a question a CLI answered in 1,365, and I have watched an MCP server make an interactive debugging session feel effortless in a way no shell command could. So this is not a hit piece on MCP. It is an honest accounting of where the token math turns against you, where it does not, and why a plain-English browser CLI like BrowserBash sidesteps the worst of it for the specific job of letting a coding agent verify web flows.
The two architectures, stated plainly
Strip away the branding and there are two ways to give a model a browser.
MCP — tools for an interactive model. You run a server that advertises a set of browser tools over the Model Context Protocol. The host — Claude Code, Cursor, VS Code, Claude Desktop, a custom loop — connects, and every one of those tool definitions gets injected into the model's context window. The agent then drives the browser turn by turn: navigate, read the page back, decide, click, read again. It stays in charge of the whole transcript.
CLI — a browser run as one command. You give the model a binary it invokes through its normal shell tool. It runs browserbash run "log in and confirm the dashboard loads" --agent, the orchestration happens inside that process, and the model gets back a structured result: passed or failed, what happened at each step, any values you asked it to extract. The model consumes a verdict. It does not narrate every click.
Both are legitimate. The difference that drives everything below is when the cost lands. MCP loads its whole toolbox up front, every turn, whether or not the agent touches the browser. A CLI costs nothing until the agent decides to run it, and then it costs exactly the command string plus the JSON it returns. Hold that distinction; the token math falls straight out of it.
Where the token cost actually comes from
MCP's expense is not the work. It is the menu. Before an MCP-connected agent does anything, the model has to be told what every tool is: its name, its description, its full JSON Schema for arguments, the types, the enums, the required fields. That description lives in the context window for the entire session, re-sent on every single completion request, used or not.
Independent measurements put a single MCP tool definition at roughly 550 to 1,400 tokens depending on how richly it is documented. That sounds small until you count the tools. A browser-automation server with twenty-odd primitives is modest by MCP standards — the widely benchmarked GitHub MCP server exposes 93 tools and injects around 55,000 tokens of schema into context before the conversation starts. Anthropic, describing the same problem from the inside, reported seeing tool definitions consume 134,000 tokens before optimization in multi-server setups, and a five-server, 58-tool configuration eating roughly 55K tokens at idle. Stack a few servers — browser, GitHub, Slack, a ticketing system — and independent runs have measured ~143,000 tokens, about 72% of a 200K context window, gone before a useful instruction is typed.
The per-task numbers are starker because they isolate waste. In one benchmark, asking an agent the trivial question "what languages is this repo written in?" cost 44,026 tokens (~$0.13) through an MCP server versus 1,365 tokens (~$0.004) through the equivalent CLI — a 32x difference. Almost none of that gap is the answer. It is the schema for 93 tools the agent will never call on this turn, plus the JSON-RPC envelope, riding along for free-as-in-you-pay.
For browser automation specifically, the schema problem compounds in an ugly way. Browser tools tend to be chatty: a single page snapshot can return a large accessibility tree, and the model re-reads page state between most actions. So you pay the standing schema tax and a per-step state tax, turn after turn, across a multi-step flow. That is the engine behind the "CLI beats MCP" posts that filled feeds through 2026.
One caveat for honesty. Anthropic itself published a pattern — "code execution with MCP" — that reclaims most of this by presenting MCP servers as code APIs the agent imports on demand rather than as a fully-expanded toolbox, cutting one reported workflow from 150,000 tokens to about 2,000. So MCP's overhead is not a law of physics; it is a default. But it is the default most teams run today, and it is the default you are comparing against when you reach for a CLI.
A side-by-side on the thing that matters
| Dimension | MCP browser server | Shell-command CLI (BrowserBash) |
|---|---|---|
| Standing context cost | Every tool's full schema, re-sent each turn | ~0 until invoked; then command string + JSON result |
| Per-task token cost | High — schema + per-step page state | Low — one objective in, one verdict out |
| Who orchestrates | The host model, turn by turn | The CLI process, internally |
| What the agent consumes | A running transcript of clicks and snapshots | A structured pass/fail result |
| Failure signal | Inferred from tool outputs in context | Process exit code (0/1/2/3) + NDJSON |
| Best at | Interactive, exploratory, human-in-the-loop debugging | One-shot verification, CI gates, agent sub-steps |
| Composability | Needs an MCP host to run at all | Pipes, scripts, &&, cron — anything that runs a binary |
| Multi-user auth / governance | Strong — a real MCP strength | Out of scope; it is a local command |
Read that table as a spectrum, not a scoreboard. The right column wins on token economics and CI ergonomics. The left column wins on interactive control and on enterprise concerns MCP was partly designed for. The skill is knowing which job you are doing.
Why a CLI fits coding agents so well
A coding agent already lives in a shell. It runs npm test, git diff, tsc --noEmit, grep. Those are not special integrations; they are commands that return text and an exit code, and the model has been trained on millions of examples of exactly that loop. A browser CLI slots into the same muscle memory. There is nothing new for the agent to learn and, crucially, nothing standing in its context until it chooses to act.
That last point is the whole game. When your agent finishes a change to a checkout page and wants to know whether the fix actually works, it does not need a browser toolbox loaded for the entire session on the off chance it goes near a browser. It needs to run one command at the end, read the verdict, and move on. The CLI's "zero idle cost" maps perfectly onto how coding agents actually touch browsers — rarely, decisively, at the end of a unit of work.
This is the niche BrowserBash was built for. You install it once:
npm install -g browserbash-cli
Then your agent — or your CI, or you — drives a real Chrome browser with a plain-English objective. No selectors, no page objects, no MCP host. The agent writes intent, BrowserBash drives the browser step by step, and you get back a verdict plus any structured values you asked it to pull.
browserbash run "go to staging.example.com, log in with the test account, \
and confirm the orders dashboard shows at least one row" --agent
The --agent flag is the part that makes this safe to hand to another program. Instead of prose, you get NDJSON — one JSON object per line. Progress events look like {"type":"step","step":1,"status":"passed","action":"navigate","remark":"..."}, and the run ends with a terminal object carrying a status of passed, failed, error, or timeout, a summary, and a final_state. The process exits 0, 1, 2, or 3 to match. Your agent parses two or three lines of structured data, not a paragraph of model narration it then has to re-summarize into its own context. The agent-mode NDJSON contract is documented end to end, and there is no prose to misread.
The honest counterpoint: where MCP is the better tool
I would be selling you something if I pretended the CLI wins every round. It does not.
If a human is in the loop and the page is misbehaving — a flaky modal, a race condition on hydration, a form that only fails on the third try — turn-by-turn control is genuinely better. An MCP host lets you and the model poke at the live page together, read the accessibility tree after each action, and form a hypothesis interactively. A one-shot CLI run can tell you "it failed at step 4," but it cannot let you lean in and probe step 4 the way an interactive session can. For exploratory debugging inside an AI IDE, MCP is the right shape, and Playwright MCP in particular is a mature, well-maintained option that leans on the accessibility tree to keep its own token use reasonable.
MCP also owns a set of concerns a local CLI simply does not address. Multi-user authentication, per-user authorization, centralized governance over which tools an org's agents may call, audit trails across a fleet — those are real problems for enterprise agent platforms, and they are exactly what the protocol layer was built to handle. If you are standing up shared agent infrastructure for a company, "it is just a binary on the PATH" is a feature for a developer and a gap for a platform team.
And the token gap is not permanent. Anthropic's code-execution pattern, lazy tool loading, and tool-filtering proxies all chip away at the schema tax. If your MCP host adopts those, the 32x headline shrinks toward something far more reasonable. Bet on the gap narrowing over time, not on it being a fixed law.
So the honest framing is: MCP for interactive, human-supervised, governed, exploratory work; a CLI for one-shot, unattended, token-sensitive verification that a coding agent or a pipeline kicks off and walks away from.
A decision guide you can actually use
Pick based on the job in front of you, not the hype cycle.
Choose a browser CLI when
- A coding agent or CI job needs to confirm a web flow works and then move on. The agent should consume a verdict, not babysit a browser.
- You care about token cost and context budget. Nothing should sit in the model's context until it is needed.
- You want a result you can gate a pipeline on — an exit code, not a transcript you have to parse with regex and hope.
- You want the run to be scriptable and composable:
browserbash run "..." && deploy.sh, or a row in aforloop, or a cron entry. - You want to run against free local models with no keys and nothing leaving the machine (more on that below).
Choose an MCP browser server when
- A human is interactively debugging a page alongside the model and wants turn-by-turn control.
- You are inside an AI IDE and want the assistant to poke at a running app while you both work on it.
- You need enterprise auth, multi-user authorization, or centralized governance over agent tool access.
- The flow is genuinely exploratory — you do not know the steps in advance and want the model to discover them live.
A lot of teams land on both: an MCP server for interactive development, and a CLI for the unattended verification that runs in CI and inside autonomous agent steps. That hybrid is not a cop-out; it is the same instinct as keeping both a REPL and a test runner. If you want to see how the CLI side reads in practice, the BrowserBash tutorials walk through real flows end to end, and the features overview lays out the surface.
The model bill, not just the schema bill
Token cost has a second meaning people forget. The MCP-vs-CLI debate above is about prompt tokens — the schema you re-send every turn. But there is also the inference bill: every step the model takes to drive the browser is a paid call to a hosted LLM, and a chatty turn-by-turn browser loop can rack up a lot of those.
BrowserBash takes a swing at that bill directly by being Ollama-first. Its default model is auto, and the resolution order favors free local inference: if a local Ollama instance is running, it uses ollama/<model> — no keys, nothing leaving your machine, a guaranteed $0 model bill. If not, it falls back to ANTHROPIC_API_KEY (Claude), then OPENAI_API_KEY, and finally errors with guidance rather than guessing. You can pin a backend explicitly:
browserbash run "search for a product and add the first result to the cart" \
--model ollama/qwen3
Here is the caveat I will not hide: very small local models — roughly 8B parameters and under — get flaky on long multi-step objectives. They lose the thread, repeat actions, or declare victory early. The sweet spot is a mid-size local model in the Qwen3 / Llama 3.3 70B class, or a capable hosted model for the genuinely hard flows. Run a 3B model against a five-step checkout and you will be disappointed; run a 70B-class model or Claude and it holds up. That trade-off is real and you should plan around it. What does not change is the architecture: a one-shot CLI call means you pay for one objective's worth of inference, not a context window re-stuffed with tool schema on every turn. The two savings stack.
If you want to keep an eye on runs without sending anything anywhere, browserbash dashboard opens a fully local view at localhost:4477. Every run is also written to disk at ~/.browserbash/runs with secrets masked. Cloud upload exists but is strictly opt-in — you run browserbash connect --key bb_... once and then add --upload per run; without that flag, nothing leaves your machine. The default posture is local, private, and cheap, which is the same instinct that makes the CLI shape win on tokens in the first place.
Putting it together: a realistic agent loop
Picture a coding agent fixing a bug in a signup form. It reads the failing test, edits the component, runs the unit tests — all in the shell it already knows. Now it needs to confirm the actual browser flow works, not just the unit. With an MCP setup, that browser toolbox has been sitting in context the whole session, taxing every reasoning step the agent made about the React code. With a CLI, the browser cost nothing until this moment, and now the agent runs:
browserbash run "open the signup page, register with a fresh email, \
and confirm the welcome screen appears" --agent --record
It reads the terminal NDJSON object, sees "status":"passed", and the loop closes. The --record flag wrote a screenshot and a .webm of the session for the human to review later, and on the builtin engine it also drops a Playwright trace. The agent never narrated a click. It spent tokens on the code, where they belonged, and a fixed small amount on one decisive verification.
That is the entire argument for the CLI shape compressed into one loop. You can read more about how committable markdown tests extend the same idea into living documentation, where each step is a plain-English line and secrets are masked in every log. The pattern scales from a single agent step to a whole suite without ever loading a toolbox into context.
None of this makes MCP wrong. It makes MCP a different tool for a different moment — the interactive, supervised, governed moment. For the unattended, token-sensitive, "did my fix work" moment that dominates a coding agent's day, a plain-English CLI is the cheaper and cleaner fit. Match the shape to the job and you stop paying the schema tax for work that never needed the toolbox.
FAQ
Why does MCP use more tokens than a CLI for browser automation?
An MCP server injects the full JSON Schema for every tool it exposes into the model's context window, and that schema is re-sent on every completion request whether or not the agent uses the browser. Independent benchmarks put each tool definition at roughly 550 to 1,400 tokens, so a server with dozens of browser primitives can cost tens of thousands of tokens at idle. A CLI costs nothing until the agent runs it, then only the command string and the JSON result, which is why measured tasks have shown differences as large as 32x.
Is a CLI always cheaper than MCP for AI agents?
Not always, but usually for unattended verification work. The CLI advantage is largest when the agent touches the browser rarely and decisively, because nothing sits in context until it acts. Anthropic and others have published patterns — code execution with MCP, lazy tool loading — that reclaim much of MCP's overhead, so the gap can shrink if your MCP host adopts them. For long interactive sessions where a human is debugging turn by turn, MCP's shape can be worth its cost.
When should I use MCP instead of a browser CLI?
Reach for MCP when a human is interactively debugging a page with the model, when you are inside an AI IDE and want turn-by-turn control of a live app, or when you need enterprise concerns like multi-user authentication, authorization, and centralized governance over agent tool access. MCP was partly designed for those problems, and a local CLI does not address them. Many teams run both: MCP for interactive development and a CLI for unattended CI and autonomous agent steps.
Does BrowserBash require API keys or send my data anywhere?
No on both counts by default. BrowserBash is Ollama-first, so if a local model is running it uses it with no keys and a guaranteed $0 model bill, and nothing leaves your machine. Runs are stored locally at ~/.browserbash/runs with secrets masked, and the optional dashboard at localhost:4477 is fully local. Cloud upload exists but is opt-in per run via the --upload flag after you connect; without it, nothing is transmitted.
Ready to give your agent a browser without the schema tax? Install it and run your first objective in under a minute:
npm install -g browserbash-cli
Then sign up for the free dashboard when you want it — an account is optional, and the CLI works the moment it is installed.