EP18 intermediate

Browser Harness in 2026: Still the Most Token-Efficient Browser Tool

Five browser control approaches ranked by cost, why 592 lines of Python still beats everything else for daily automation, and a decision framework for picking the right tool.

I wrote about Browser Harness in EP06. That was the deep dive into architecture and API. This is the 2026 update: what changed, how it stacks up against newer alternatives, and the decision framework I use every day to pick the right browser tool for each job.

Short version: Browser Harness is still my default. Here’s why.

Five Approaches Ranked by Token Cost

I’ve measured token consumption across hundreds of real tasks — form fills, dashboard checks, screenshot captures, multi-step workflows. Here’s where things stand:

ApproachTokens per taskLogin sessionSetup effortFlexibility
Browser Harness2K-2.5KYesMediumHigh
Playwright MCP3-5KNoLowMedium
Claude in Chrome5-8KYesLowMedium
Traditional (Selenium/Playwright)N/ANoHighHighest
Computer Use15-20KNoNoneHighest

The gap between Browser Harness and Computer Use is 8x. On a daily automation that runs 10 times, that’s the difference between $0.30 and $2.40 in API costs. Over a month, it adds up.

Computer Use takes screenshots of the entire screen, sends them as images to the model, and asks “what do you see?” every single step. That’s expensive. Browser Harness sends a targeted screenshot only when needed, and most interactions happen through js() calls that cost almost nothing.

What Makes Browser Harness Different

The entire tool is 592 lines of Python. Under 900 lines total if you count the shell wrapper and config. It does one thing: connects to your running Chrome browser via CDP (Chrome DevTools Protocol) over a WebSocket.

That single design choice — connecting to your existing browser — gives it three advantages no other tool has:

Your cookies, your logins, your sessions. When Browser Harness opens a tab, it opens it in the same browser where you’re logged into Gmail, GitHub, Notion, and everything else. No re-authentication. No cookie imports. No headless browser trying to pretend it’s human. You are human, and Browser Harness rides on your session.

Your extensions work. Ad blockers, password managers, dark mode extensions — they all run normally because it’s your real browser. Headless Playwright doesn’t load extensions. Computer Use sees them on screen but can’t interact with them efficiently.

Zero infrastructure. No Docker containers, no Playwright binary downloads, no browser version management. You have Chrome installed already. Enable remote debugging, and you’re done.

The Self-Healing Architecture

This is the part that aged best since EP06. Browser Harness has two files that grow smarter over time:

agent_helpers.py starts empty. As the agent runs tasks, it writes helper functions it needs — scroll_to_bottom(), wait_for_element(), extract_table_data(). Next time it needs the same capability, it imports the existing function instead of re-inventing it. I checked mine recently: 47 helper functions, accumulated over three months of daily use. That’s 47 functions I never wrote by hand.

domain-skills/ is a directory of per-website experience files. After Browser Harness automates a new site for the first time, it records what worked: DOM selectors, interaction sequences, edge cases, wait times. Second visit reads the skill file and executes with near-zero exploration.

I have 30+ domain skill files now. GitHub, TikTok analytics, Google Search Console, Cloudflare dashboard, various internal tools. Each one represents hours of exploration that only happened once.

Setup

Two steps.

Step 1: Enable Chrome remote debugging.

On Mac, quit Chrome completely, then relaunch with:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222

Or set it permanently by creating a wrapper script. I keep mine in ~/.local/bin/chrome-debug:

#!/bin/bash
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 "$@"

Verify it works by visiting http://localhost:9222/json — you should see a JSON list of your open tabs.

Step 2: Install Browser Harness.

uv tool install browser-harness

That’s it. No API keys, no OAuth setup, no configuration files.

Core API in Practice

The API is minimal by design. Six functions handle 90% of tasks:

# Open a page
new_tab("https://analytics.google.com")
wait_for_load()
wait(3)  # Extra wait for JS-heavy dashboards

# Get page context
info = page_info()  # Returns URL, title, status
print(info["title"])

# Interact via JavaScript
js('document.querySelector("#date-range").click()')
js('document.querySelector("input[type=text]").value = "2026-01-01"')
js('document.querySelector(".apply-btn").click()')

# Take a screenshot for verification
capture_screenshot("/tmp/analytics-dashboard.png", max_dim=1800)

# Clean up
js("window.close()")

Everything funnels through js(). There’s no click_element() or fill_form() wrapper that tries to be smarter than the AI. The AI writes the JavaScript it needs. If a site uses React and the standard .value = "..." setter doesn’t trigger the change handler, the AI figures that out and dispatches an input event. That flexibility is why 592 lines beats 15,000 lines of framework code.

When NOT to Use Browser Harness

Browser Harness isn’t always the right call. I use a simple decision tree:

Does a dedicated MCP server exist? GitHub has one. Notion has one. Slack has one. Google Drive has one. If the service you need has a proper MCP server, use it. MCPs give you structured data and typed operations. Browser automation gives you pixels and DOM. Structured data wins every time.

Task: "Create a GitHub issue with labels"
→ GitHub MCP: 1 tool call, 500 tokens, guaranteed correct
→ Browser Harness: 5+ steps, 2.5K tokens, fragile selectors

Do you need structured automation with CI/CD? Playwright MCP gives you 40+ predefined operations with clean error handling. If you’re building a test suite or a production scraping pipeline that runs in a container, Playwright MCP is more reliable. Browser Harness needs a running Chrome with your session — that’s not containerizable.

Do you need desktop control beyond the browser? Computer Use can move windows, interact with native applications, and control things outside Chrome. Browser Harness literally cannot see anything outside the browser tab. If the task involves copying data from a spreadsheet app into a browser form, Computer Use is your only option.

Everything else? Browser Harness. Dashboard monitoring where no API exists. Filling out web forms that don’t have APIs. Grabbing screenshots of competitor pages. Checking deployment status on hosting dashboards. Logging into admin panels to toggle settings. These are all real tasks I run daily.

The Decision Framework

Does a dedicated MCP exist for this service?
├── Yes → Use the MCP
└── No
    ├── Need containerized/CI automation?
    │   └── Yes → Playwright MCP
    └── No
        ├── Need desktop control beyond browser?
        │   └── Yes → Computer Use
        └── No → Browser Harness

Real Usage Numbers

I run 10+ browser automations through Browser Harness on a typical day. Here’s a sample:

  • Morning: screenshot three analytics dashboards, save to a dated folder
  • Midday: check Cloudflare Pages deploy status after a git push
  • Afternoon: fill a shipping form on a supplier portal (no API, just a web form)
  • Evening: grab competitor product screenshots from Etsy search results

Each task takes 2-4 seconds of wall time and 2K-2.5K tokens. The daily total is around 25K-30K tokens for browser automation. Compare that to Computer Use at 150K-200K tokens for the same tasks, and the savings are obvious.

What Changed Since EP06

The core hasn’t changed. Still 4 files, still CDP, still under 900 LOC. What grew was the ecosystem around it:

Domain skills doubled. The community has contributed skill files for more sites. When you install Browser Harness, you get a starter set. Your own skills accumulate on top.

Error recovery improved. The agent_helpers.py approach means common failure modes (element not found, page still loading, modal dialog blocking interaction) get solved once and reused forever.

Integration with Claude Code’s config system. You can now define Browser Harness as a preferred tool in CLAUDE.md, and Claude Code will reach for it automatically when browser tasks come up. No need to say “use Browser Harness” in every prompt.

The philosophy hasn’t changed either: minimal framework, maximum AI autonomy, token efficiency above all. A year from now, the core will probably still be under 1,000 lines. The domain skills directory might have 100+ files. That’s the growth vector — accumulated experience, not accumulated code.