Imported from JZKK720/agent-meow (
examples/browser-agent/skills/browser-harness/SKILL.md). Install upstream withnpx skills add JZKK720/agent-meow --skill browser-harness. Copyright stays with the author.
browser-harness — live CDP browser control via CLI
browser-harness is a CLI + skill (not an MCP server). You (the agent) drive
the user's real Chrome by shelling out to the browser-harness command with
inline Python heredocs. The CLI auto-starts a daemon that connects to Chrome's
remote-debugging CDP endpoint and relays your commands.
When to use
- Fill forms, click buttons, navigate apps the user is signed into (stateful, needs their cookies/login).
- Take screenshots of a logged-in page.
- Record a browser-action video (
browser-harness video init/review/export). - Run parallel isolated browsers via Browser Use Cloud (one per task).
- Scrape a page that needs JS + login that Scrapling's stateless fetch can't reach.
When NOT to use
- Stateless scrape of a public URL with anti-bot bypass → use Scrapling
(
get/fetch/stealthy_fetch). - Research a named social platform (Twitter, Reddit, XiaoHongShu, YouTube, etc.) → use agent-reach (knows the right CLI per platform).
- Simple read of any URL to markdown → Scrapling
getor agent-reach'sjina.
Setup (one-time)
uv tool install --python 3.12 --upgrade --force browser-harness
command -v browser-harness # should print a path
Then connect it to Chrome:
- Open
chrome://inspect/#remote-debuggingin Chrome. - Tick the checkbox so agents can connect to your browser.
- Click Allow when the per-attach popup appears (Chrome 144+).
Verify:
browser-harness --doctor
If page_info() prints, you're connected:
browser-harness <<'PY'
print(page_info())
PY
How to call it
Use agent-meow's shell/terminal tools to run browser-harness with a heredoc.
Helpers (page_info, goto_url, click_at_xy, type_text, fill_input,
js, wait_for_load, wait_for_element, cdp, new_tab, switch_tab,
screenshot, etc.) are pre-imported in the heredoc scope.
Read the current page
browser-harness <<'PY'
print(page_info())
PY
Navigate
browser-harness <<'PY'
goto_url("https://example.com")
wait_for_load()
print(page_info())
PY
Click at coordinates and type
browser-harness <<'PY'
goto_url("https://example.com/login")
wait_for_load()
click_at_xy(420, 310)
type_text("my_username")
click_at_xy(420, 360)
type_text("my_password")
click_at_xy(420, 410)
wait_for_load()
print(page_info())
PY
Fill a form field by CSS selector
browser-harness <<'PY'
fill_input("#email", "user@example.com", clear_first=True)
fill_input("#password", "hunter2", clear_first=True)
js("document.querySelector('button[type=submit]').click()")
wait_for_load()
print(page_info())
PY
Run raw CDP
browser-harness <<'PY'
cdp('Page.navigate', url='https://example.com')
PY
Take a screenshot
browser-harness <<'PY'
from browser_harness.helpers import screenshot
screenshot("/tmp/page.png")
PY
Cloud browsers (isolated / headless / parallel)
Local Chrome is one shared browser; parallel tasks fight over tabs and focus. For isolated work, captchas, or bot-sensitive sites, use Browser Use Cloud:
# Authenticate once
browser-harness auth login
# Start a cloud browser named "r7k2"
browser-harness <<'PY'
start_remote_daemon("r7k2")
PY
# Use it by name
BU_NAME=r7k2 browser-harness <<'PY'
print(page_info())
PY
Cloud browsers run with clean managed IPs + stealth settings — your own IP and local browser stay out of it. Free tier: 3 concurrent browsers, proxies, captcha solving. No card required. Grab a key at cloud.browser-use.com/new-api-key.
Recordings and videos
browser-harness can record browser actions and produce explanatory MP4s with privacy review:
browser-harness recordings enable # save actions locally by default
# ... do the browser actions ...
browser-harness recordings --latest # print the newest recording directory
browser-harness video init <recording> # prepare for editing
browser-harness video review <recording> # compile + review
browser-harness video export <recording> --reviewed # export verified MP4
Requires ffmpeg and ffprobe for export.
Domain skills (optional, advanced)
browser-harness ships site-specific domain skills (Framer editor, Wayback
Machine, package registries, etc.) under
${XDG_CONFIG_HOME:-~/.config}/browser-harness/agent-workspace/domain-skills/.
Enable with BH_DOMAIN_SKILLS=1. If the task is site-specific, read every file
in the matching domain-skills/<site>/ directory before inventing an approach.
Design constraints
- Helpers attach to the running Chrome/Chromium CDP endpoint. For isolated
automation, launch Chrome yourself with
--remote-debugging-portand passBU_CDP_URL, or use a Browser Use cloud browser. - The daemon auto-starts and connects. If
--doctorfails, inspectsrc/browser_harness/admin.py,daemon.py,_ipc.py. - State lives under
${XDG_CONFIG_HOME:-~/.config}/browser-harness(auth, telemetry id, agent workspace, sockets, logs, screenshots, temp files). Override withBH_HOMEorBROWSER_HARNESS_HOME.
Gotchas
- Keep the browser-harness tab focused during video export — rAF throttles in background tabs and stalls MediaRecorder capture.
- Snap Chromium on Linux blocks CDP;
browser-harness doctor --fix-snapprints the workaround. - If an old
browserorbrowser-useskill is being picked instead of this one, remove that stale skill directory manually.