Agent-first lightweight browser automation — direct CDP, no Playwright, more accurate and more reliable.
Highlights · Overview · Core Technology · Features · Quick Start · Contents
English · 中文
Harness Browser is a lightweight browser-use style tool that makes an agent's browser usage more accurate and reliable. Unlike typical stacks that route every action through Playwright, it launches a real Chromium and talks to the Chrome DevTools Protocol (CDP) directly — removing the intermediate layer so element targeting is driven by stable, live DOM refs and rarely misses.
Harness Browser's design goal: give an agent a browser it can act on with confidence — accurate clicks, low token cost, and persistent logins — through a small, well-shaped set of tools and a matching CLI.
Note: the install-browser command may bootstrap Playwright once purely to download a Chromium binary. Playwright is not a runtime dependency — the agent always drives the browser over CDP.
✨ Highlights
| Feature | Description | |
|---|---|---|
| ⚡ | Direct CDP | Connects straight to Chrome via CDP — no Playwright / intermediate layer |
| 🎯 | Ref-based targeting | Stable element refs survive layout reflows, so clicks land where intended |
| 🪶 | Lightweight DOM | Token-efficient multi-level DOM keeps prompts small |
| 🔐 | Auth persistence | Profile-based logins persist across sessions — no repeated sign-in |
| 🛠️ | Agent tools | One stateless browser_tool with ~20 actions |
| 💻 | CLI | Every action available as a first-class command |
| 🎬 | Record & replay | Capture a workflow, then replay it as skill-guided agentic execution |
| 🤖 | MCP server | Expose the browser to any MCP-capable agent |
📌 Overview
Most browser automation tools sit on top of Playwright, which adds a layer of abstraction between the model and the page. Harness Browser skips that layer: it starts a Chromium process with a remote-debugging port and speaks CDP itself. Because the element references come straight from the live page, the agent acts on the real nodes — and those refs stay valid through reflows and re-renders. The result is higher action accuracy and lower token usage, with a persistent profile so logins don't expire mid-task.
🧠 Core Technology
| Layer | Technology |
|---|---|
| Language | Python 3.11+ |
| Transport | CDP over websockets (hand-rolled async client) |
| Launcher | subprocess Chromium with --remote-debugging-port |
| DOM | Multi-level builder + stable ref system |
| Tools | Stateless browser_tool action set |
| Recording | Injected JS recorder + semantic collapse + skill generator |
| Interfaces | CLI + MCP server |
| Build / quality | hatchling · ruff · mypy · pytest |
🤔 Features
Browser tools
browser_tool(action=...) exposes the following actions:
| Action | Description | Action | Description |
|---|---|---|---|
navigate |
Open a URL | select |
Pick a <select> option |
dom_tree |
Dump the multi-level DOM | scroll |
Scroll the viewport |
screenshot |
Capture a screenshot | hover |
Hover an element |
click |
Click by ref | eval_js |
Run JavaScript |
type |
Type text by ref | go_back / go_forward |
History nav |
fill |
Fill a field by ref | reload |
Reload the page |
press |
Press a key | new_tab / close_tab |
Tab control |
wait |
Wait for a condition | switch_tab / list_tabs |
Tab management |
close_session |
End the session |
CDP session
BrowserSession.create(profile=...)opens a persistent Chromium session.- Stateless helper:
browser_tool(action="navigate", url=..., profile="work"). - Set
BROWSER_USE_IDLE_TIMEOUT_MINUTESto stop a local Chrome profile after that many minutes without real CDP activity (0, the default, disables it). await session.close(kill=True)orbrowser_tool(action="close_session", profile="work", kill=True)stops the local Chrome process immediately. Profile data and login state stay on disk.
CLI
Every tool is also a CLI command:
harness-browser install-browser # fetch a Chromium binary (one-time)
harness-browser navigate "https://example.com" --profile work
harness-browser dom-tree --profile work
harness-browser click --ref inp_1 --profile work
harness-browser type "harness" --ref inp_1 --profile work
harness-browser screenshot --profile work
# session: open / close-session / new-tab / switch-tab / close-tab / list-tabs
Record & replay
Harness Browser can record a real browsing session and replay it:
harness-browser record daemon-start— launch the long-lived recording daemon.harness-browser record start— begin capturing the active tab.- Browse normally. A small injected script captures clicks, typed text, navigations, and submits, with privacy redaction of sensitive fields.
harness-browser record stop— stop capturing.harness-browser record steps <id>— inspect the semantic steps;record skill <id>emits a draft OpenClaw Skill.harness-browser replay run <id>— re-execute as skill-guided agentic execution (the model replays intent, not brittle coordinates/refs).
Use record list / record show <id> / record status / record doctor to manage recordings.
MCP server
harness-browser ships an MCP server, so any MCP-capable agent can drive the browser through the same tool set.
🚀 Quick Start
Prerequisites
- Python 3.11+
- A Chromium / Chrome binary (auto-downloaded by
install-browser)
1. Install
pip install harness-browser
harness-browser install-browser # fetch a Chromium binary once
2. Use as a library
from harness_browser import BrowserSession
async with await BrowserSession.create(profile="default") as session:
await session.navigate("https://example.com")
dom = await session.dom_tree()
await session.click(ref="btn_1")
Or statelessly:
from harness_browser import browser_tool
await browser_tool(action="navigate", url="https://example.com", profile="work")
3. Use as a CLI
harness-browser navigate "https://example.com" --profile work
harness-browser dom-tree --profile work
4. Record a workflow
harness-browser record daemon-start
harness-browser record start
# ... interact with the page ...
harness-browser record stop
harness-browser record skill <recording_id> # emit an OpenClaw Skill
harness-browser replay run <recording_id> # replay it
📑 Contents
- Highlights
- Overview
- Core Technology
- Features
- Quick Start
- Reference
- Project Info
📖 CLI reference
| Command | Description |
|---|---|
install-browser |
Download a Chromium binary (one-time bootstrap) |
navigate / open |
Open a URL |
dom-tree |
Print the multi-level DOM |
screenshot |
Capture a screenshot |
click / type / fill / press |
Interact by ref |
wait / select / scroll / hover |
Page control |
eval-js |
Run JavaScript |
go-back / go-forward / reload |
History / reload |
new-tab / switch-tab / close-tab / list-tabs |
Tab management |
close-session |
End the session |
record ... |
doctor, daemon-start, daemon-stop, status, start, stop, list, show, steps, skill |
replay run <id> |
Replay a recorded workflow |
🛠️ Development
Prerequisites: Python 3.11+, uv
make install # pip install -e ".[dev]"
make all # lint + typecheck + test
🤝 Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Run
make allbefore submitting - Open a Pull Request
🔗 Related projects
| Project | Description |
|---|---|
| harness-agent | Agent runtime that drives the browser tools |
| harness-memory | Memory system for browser-backed agents |
| harness-gateway | Multi-platform IM channel bridge |
| Octop | The self-hosted assistant that composes the Harness stack |
📄 License
This project is licensed under the MIT License.
Release files for harness-browser 0.7.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| harness_browser-0.7.8.tar.gz | 339.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| harness_browser-0.7.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 441.7 kB
Release files / harness_browser-0.7.8.tar.gz
| Download URL | harness_browser-0.7.8.tar.gz |
|---|---|
| Size | 339.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7ffe4e4af8285df4598341bded14e1cb2769b835df6b1e729b603a8a2cacfc92
|
|
BLAKE2b-256 checksum How to use checksums |
84de482fbf2d10a1e425f14f1a2bde4d36a479c2cb714ffa080cdca1c296aefe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Release files / harness_browser-0.7.8-py3-none-any.whl
| Download URL | harness_browser-0.7.8-py3-none-any.whl |
|---|---|
| Size | 102.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6f95d97109ac23ad389d74f725ce9bb7e34863188e8f1a31569b5f1f9d18f913
|
|
BLAKE2b-256 checksum How to use checksums |
260087f162ed67c17b9dcf0517cfa7c64112616b30a57a7c0165c62f462798db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|