v1.8.1
A reliability, speed, polish and security pass over 1.8.0.
If you use the stdio MCP bridge (uvx auto-browser-mcp, Claude Desktop, Cursor), upgrade.
It now survives a controller restart, reports auth and rate-limit errors instead of hanging,
and can send an operator id (--operator-id / AUTO_BROWSER_OPERATOR_ID) to controllers
that set REQUIRE_OPERATOR_ID=true.
Upgrade notes:
browser.create_sessionwithtotp_secretnow needstotp_hostsunless it also sets
start_url, whose host becomes the default.- noVNC takeover now accepts only its own page on a loopback host name. If your takeover URL
uses another name (a LAN IP, a bastion, a domain), setNOVNC_ALLOWED_HOSTS. POST /workflows/runvalidates its steps up front. Unknown keys, duplicate ids, unknown
dependencies and unbounded retries now get a 422 before the run starts.GET /sessions/{id}/tracereturns aviewer_urlthat opens the Playwright trace viewer
without a trace preloaded, plus a newviewer_command. The old?trace=link never loaded.GET /audit/eventswithlimit <= 0returns an empty list.- The controller image no longer includes the test tooling. Build with
INSTALL_DEV_DEPS=true
to run pytest inside it (make testand CI already do).
Security
- Hardened session creation, the TOTP autofill, approvals, the noVNC takeover
socket and witness receipts. Advisories will follow with details. - New:
totp_hostsonbrowser.create_sessionnames the hosts where
one-time codes may be typed; it defaults to thestart_urlhost, and a
totp_secretwith neither is now refused. - New: noVNC takeover accepts only its own page on a loopback host name.
If your takeover URL uses another name (a LAN IP, a bastion, a domain), set
NOVNC_ALLOWED_HOSTS; if a proxy in front of the noVNC port rewrites the
Hostheader, setNOVNC_ALLOWED_ORIGINS. Isolated session containers get
ISOLATED_TAKEOVER_HOSTautomatically. - An approval for text typed with
sensitive: truecan be executed only by the
controller process that created it (not after a restart, by another uvicorn
worker or replica, or after 24 hours); the action then asks for a new one.
Fixed
- Actions that ran are no longer reported as failed. A page that navigated just after a
successful action (a click whose handler redirects) used to turn the result into a failure,
so callers retried and submitted forms twice. The result now comes back with an
observation_errortelling the caller to observe again. When a failed page can't be
snapshotted, the normalized error is kept. - An approved action runs at most once, even when two requests carry the same approval.
- MAX_SESSIONS counts sessions still being created, so concurrent creates can't exceed it.
- Sessions tear down cleanly. A failing teardown step no longer strands the session and its
slot. A cancelled create rolls back the way a failed one does. - Tabs: a session whose active tab closes itself moves to another tab. A tab that fails to
open is closed. The CDP routes and the network inspector follow every tab, not only the first. - Stores: every atomic JSON write gets its own temp file. Before, 16 parallel upserts lost
177 of 320 writes. An audit trim no longer drops events appended while it runs. Damaged
auth-profile metadata refuses access instead of reading as unowned. Encrypted storage state
never leaves a plaintext temp file behind. - MCP: sessions are evicted by last use, not creation time. The stdio bridge re-initializes
when the controller forgets its session, and answers HTTP-layer errors (401, 400, 429) as
JSON-RPC errors. - Cron: jobs no longer leak sessions or silently stop firing. An invalid schedule is
refused, and a webhook and a scheduled fire can't both start a run. - Agent jobs: jobs caught mid-cancellation by a restart are settled. Resumed jobs stay
within the context-hint limit. The orchestrator ends a run with its history when the page
can't be observed, instead of returning a 500. - Providers: rate-limited retries honor
Retry-After, and a cancelled job kills its CLI
subprocess. - Also: session event streams end when the session closes. The network inspector bounds
in-flight requests. A cancelled tunnel provision stops its autossh. The cleanup sweep no
longer removes a new session's empty directories. Two downloads with the same name keep both
files.
Changed
- Actions and observations are faster (#161). A selector click on a
300-row page went from about 1,440 ms to 1,250 ms against local Chromium.
An observation's page summary now makes two concurrent browser calls instead
of four in a row. The screenshot is taken while the DOM is read. The
post-action bot-challenge probe makes one call instead of three. Tab titles
are fetched together. The accessibility outline no longer builds nodes past
its 30-node cap, which halves its parse time on large pages (85 ms to 47 ms
on a 3,000-row page). Observation payloads keep the same shape. - Human-like mouse moves keep their intended 4–18 ms pacing (#161). Each
step used to sleep its full gap on top of the ~17 ms Chromium takes to
dispatch a move. Moves now arrive at about the browser's dispatch rate, and
the path keeps its shape and step count. - Listing audit events stops at the limit (#161). The file-backed store
read and validated every stored event (up to 10,000) to return the newest
100. It now reads newest first and stops once it has enough: 67 ms to 6 ms.
Alimitof zero or less now returns nothing. - The controller image leaves out the test tooling (#161). pytest, ruff,
pip-audit and the rest ofrequirements-dev.txt(about 58 MB) install only
when the image is built withINSTALL_DEV_DEPS=true, whichmake testand
CI set. Anything else that runs pytest inside the image needs that build arg. - Clearer MCP tools. Every argument of the curated tools is described. An
unknown tool name points at the tool the caller meant. Validation errors drop
pydantic's "Value error" prefix. - The OpenAPI docs are grouped by area instead of one flat list.
Added
auto-browser-client:operator_idandheadersarguments, andAutoBrowserErrorexported
from the package.auto-browser-langchain:operator_idonAutoBrowserTool,list_toolsand
AutoBrowserNode. The tool description no longer names tools that don't exist.- Stdio bridge:
--operator-id/AUTO_BROWSER_OPERATOR_ID, and--helpnames each flag's
environment variable.
Documentation
- The README's production settings now let the controller start. They were missing
SHARE_TOKEN_SECRETand
CONTROLLER_ALLOWED_HOSTS, and a test runs the startup policy over them. .env.examplelists every setting and the current default models, and a test keeps it that
way.- Doc examples that called removed tools are fixed, and a test validates every curl MCP call in
the docs. - The README says when to choose per-session isolation, and the architecture doc marks the
shipped roadmap phases.