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.
Metadata
Release files for harness-browser 0.7.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| harness_browser-0.7.9.tar.gz | 341.3 kB | Without provenance | Details for harness_browser-0.7.9.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| harness_browser-0.7.9-py3-none-any.whl | Python 3 | none | any | Details for harness_browser-0.7.9-py3-none-any.whl |
Total release size: 444.0 kB
Release files / harness_browser-0.7.9.tar.gz
| Download URL | harness_browser-0.7.9.tar.gz |
|---|---|
| Size | 341.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a88a7a9d55649c628ff41b073be749885d16d95925521ab8a3e2e4e11c3f37f8
|
|
BLAKE2b-256 checksum How to use checksums |
a4088dfe724dc05de9ab8c903f64482dbe54f67a9323995867ebbd4094c52fe2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.2
|
Release files / harness_browser-0.7.9-py3-none-any.whl
| Download URL | harness_browser-0.7.9-py3-none-any.whl |
|---|---|
| Size | 102.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4c1afc19e225105cbc6f2804a1ae56fd32555b1e32cf8a215752823f79a69023
|
|
BLAKE2b-256 checksum How to use checksums |
fb29b652bc07e2bf4b1c012469f512cca9bab01c1958842129304996811e80a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.2
|
Security for harness-browser 0.7.9
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.