Skip to content

LocalHarness — the browser plugin

Browser

← the plugins /browser

Off by default — turn it on and the web researcher can read a page that web_fetch finds empty.

  1. 1
    the root delegates it never holds browser_fetch — it reads untrusted pages
  2. 2
    the web researcher calls browser_fetch after web_fetch answered “low extractable text”
  3. 3
    a sandboxed headless Chromium opens it https only · a new context per call · no images, media or fonts
  4. 4
    every request goes to the proxy loopback · CONNECT only · credentials new at every launch
  5. 5
    public addresses only checked, then dialled at the address it checked
  6. 6
    the text comes back a window, the way web_fetch returns a page
  7. ↺
    every launch is checked a loopback probe must be refused before any page
  8. ✕
    private services refused — the private allowlist is web_fetch’s alone

browser.executable_path and browser.sandbox are machine-level only — a project cannot choose the program or unsandbox it.

fig. 01 — PLATE BROWSER — a sandboxed page reader behind a checking proxy: one page

how it works

  • one tool browser_fetch opens an https page in a real headless Chromium, runs its JavaScript and returns its text the way web_fetch does.
  • who holds it the web researcher and the search verifier, after web_fetch answers “low extractable text”; the root agent never does.
  • sandboxed Chromium runs sandboxed and refuses to run otherwise, unless your machine-level config accepts an unsandboxed browser.
  • nothing kept each call gets a new browser context, closed after it: no cookies, profile or storage between calls.
  • started on demand the browser starts at the first call and closes when idle and when the session ends.
  • doctor checks the package, the downloaded Chromium, a launch and the sandbox.

what it reaches

  • public addresses only the rule web_fetch uses, applied to every request the page makes — the page, each redirect, every script, fetch and WebSocket.
  • one way out everything leaves through a loopback proxy that accepts only CONNECT, with credentials new at every launch, and dials the address it checked.
  • each launch checked a navigation to a loopback port must be refused before any page loads, or browser_fetch stays off and doctor says why.
  • no side doors QUIC is off, WebRTC sends no UDP outside the proxy, and Chromium writes no crash dumps.

what it does not do

  • no signed-in browsing no cookies, profile or storage between calls.
  • no clicking or typing no forms, downloads, uploads or screenshots.
  • https only web_fetch reads plain-http pages.
  • no browser-backed search and no anti-bot stealth: it says HeadlessChrome, so a site that refuses headless browsers refuses it.
  • not for your own app driving an app under test is a job for a config child with bash_exec.
  • no private services the private allowlist is web_fetch’s alone — a page has an origin and runs code, so reading a private service stays web_fetch’s job.

Setup

Turn it on from the session, fill in its settings, and it checks they work; your coding agent can do the hardware part.

~/project — localharness start shipped
qwen3.6-27b ~/project
Plugins: memory, autoresearch, browser
❯ /plugins enable browser
Restarting with browser on — your conversation is kept.
✓ browser enabled in ~/.localharness/overrides.yaml
Download Playwright's headless Chromium now? About 100 MB from Playwright's CDN; it runs as a program on this machine (sandboxed by default). [Y/n]: y
✓ browser-binary: chromium_headless_shell-1248 installed
Checking it now:
✓ browser-package: playwright 1.64.0
✓ browser-binary: chromium_headless_shell-1248
✓ browser-launch: reach check ok
✓ browser-sandbox
browser_fetch (pages that need JavaScript) works once Chromium is downloaded and `localharness doctor` shows every browser row passing; `localharness plugins enable browser` does the download.
Restarted with browser on. Your conversation continues.
browser: on in this session

in a session: /plugins enable browser · from a shell: localharness plugins enable browser

paste into your coding agent to set it up for your hardware
Set up LocalHarness browser_fetch on this machine. Install LocalHarness with its browser extra, keeping the extras I already use (a reinstall keeps only the extras it names). Then run `localharness plugins enable browser` and answer yes to downloading Playwright's headless Chromium (about 100 MB). On Linux, if `localharness doctor` says system libraries are missing, run the deps install it names (apt only; otherwise set browser.executable_path to a system Chromium). If doctor says the sandbox is unavailable, add an AppArmor profile for the downloaded headless shell or, accepting the residual, set browser.sandbox: false in the machine-level config. You are done when `localharness doctor` shows browser-package, browser-binary, browser-launch and browser-sandbox all passing.

Surfaces

where you reach it

  • browser_fetch the tool the web researcher and the search verifier call; an agent you define gets it with tools.add.
  • browser.idle_close_s · browser.executable_path · browser.sandbox when the browser closes, your own Chromium, and the sandbox — the last two machine-level only.
  • slash commands none.
  • uv tool install 'localharness[browser]' the extra first; name the other extras you use too, since a reinstall keeps only the ones it names.
  • /plugins enable browser inside a running session: asks before downloading Playwright’s headless Chromium, checks it, then restarts with your conversation kept.
  • localharness plugins enable browser off by default; disable removes the tool, and the download stays in Playwright’s cache.

Get Involved