Skip to main content

Stealth-Chromium CDP farm: per-seed browser fingerprints over a patched CDP multiplexer.

Project description

cuttle

A stealth-Chromium CDP farm. cuttle runs a patched Chrome DevTools Protocol (CDP) multiplexer that spawns one stealth Chrome per fingerprint seed, giving each seed its own coherent browser identity - fingerprint, proxy, geoip, locale, and timezone - behind a single CDP endpoint. Point any CDP client (Playwright, Puppeteer, chromium.connectOverCDP) at it and select a seed with a query parameter.

The Chrome engine is a free, redistributable stealth-Chromium fork baked into the image - clark (MIT) by default, clearcote (BSD-3) as a fallback - so there is no proprietary binary and no license to manage. The multiplexer is a patched derivative of CloakHQ's MIT-licensed cloakserve.

Maintained by glim.sh.

Why

The stealth-scraping stack normally reconciles several independently-drifting upstreams by hand: the CDP multiplexer, the base image, and the Chrome fork binary - each of which moves on its own schedule, and Chrome ships a new major roughly every four weeks. cuttle owns the orchestration in one repo and consumes the browser as a pinned prebuilt, turning "always check what still works" into "pick a binary release, run the harness, ship or don't." One decision, one test.

Quickstart

docker run --rm -p 9222:9222 ghcr.io/glim-sh/cuttle:latest

Then connect a CDP client and pass a fingerprint seed:

http://127.0.0.1:9222?fingerprint=12345
http://127.0.0.1:9222?fingerprint=12345&timezone=America/New_York&locale=en-US

Each distinct fingerprint seed gets its own isolated Chrome with a stable, coherent identity. To route a seed through an authenticated residential proxy, pass it on the connect URL; cuttle strips the inline credentials and answers the proxy's 407 over CDP, so fork binaries that reject inline credentials still work.

The image runs headed by default (the default command is cuttleserve --headless=false, on a built-in Xvfb): headed Chrome clears escalated anti-bot challenges that headless cannot. Override the command only to change flags or the port.

CLI (daily driver + login handoff)

For a persistent local browser you can watch and log into via VNC - then drive over CDP - install the host CLI, published on PyPI as cuttle-browser (the command it installs is cuttle):

uv tool install cuttle-browser        # or: pipx install cuttle-browser
uvx --from cuttle-browser cuttle up   # or one-off with no install
cuttle up                             # start the container + VNC viewer
cuttle login https://accounts.google.com   # sign in once via the viewer; the CDP session stays logged in
cuttle down                           # graceful stop, keeps the profile
cuttle skill                          # print the full agent usage guide

cuttle up is idempotent and profile-preserving (logins survive down/up). The CLI shells out to Docker and defaults to image cuttle:local; use the published image with --image ghcr.io/glim-sh/cuttle:latest. See SKILL.md (or cuttle skill) for the full workflow.

Engine swap

Both fork binaries are baked in and selected by CLOAKBROWSER_BINARY_PATH:

  • /opt/clark/chrome - clark, Chrome 148 (default)
  • /opt/clearcote/chrome - clearcote, Chrome 149 (fallback)
docker run --rm -p 9222:9222 \
  -e CLOAKBROWSER_BINARY_PATH=/opt/clearcote/chrome \
  ghcr.io/glim-sh/cuttle:latest

Bumping Chrome

Update the pinned CLARK_* / CLEARCOTE_* build args in the Dockerfile, rebuild, and run the harness. See docs/UPGRADE.md. Building a binary from source is documented as break-glass only in docs/BUILD-FROM-SOURCE.md.

Testing

test/harness.py is a neutral, self-contained smoke (raw CDP over websockets) that drives a running cuttle and checks per-seed fingerprint isolation, stealth coherence, and connection stability under cold-cycle load. Run it before publishing any bump. End-to-end validation against live sites is done separately against a real amd64 deployment. See test/README.md.

To confirm a running seed presents a coherent identity (WebGL GPU string, WebRTC/WebGPU, navigator.webdriver) and to tell benign Chrome log noise from a real problem, see docs/STEALTH-VERIFICATION.md.

Architecture

  • bin/cuttleserve - the patched CDP multiplexer. Per-seed Chrome pool, transparent proxy-auth over CDP, a service_worker browserContextId stamp (so CDP clients do not crash on service workers), and fork launch-parity flags.
  • cuttle/ - a trimmed MIT subset of the cloakbrowser wrapper: the CDP argument-builders plus geoip/config helpers. No license, widevine, or behavioral-automation code.
  • scripts/ - rename-fonts.py (Windows font pack builder: metric-compatible free fonts renamed to Windows family names, so a Windows-claiming fingerprint is coherent) and sync.sh (re-sync helper for the vendored upstream subset).
  • docs/ - the upgrade runbook, build-from-source break-glass, and UPSTREAM.md (provenance of the vendored subset).

Notes and limits

  • The image is linux/amd64 only: the clark/clearcote prebuilts ship linux-x64 binaries. On an Apple Silicon host it runs emulated (fine for local dev and the smoke); production runs it native on an amd64 server. The Python multiplexer itself is arch-agnostic.
  • cuttle does not include a browser-automation client library - use any CDP client. It is the farm, not the scraper.

Licensing

cuttle is MIT (LICENSE). It vendors and redistributes third-party software under their own terms - CloakHQ's cloakserve/cloakbrowser (MIT), clark (MIT), and clearcote (BSD-3). No proprietary CloakBrowser binary is used or redistributed. Full attributions and license texts are in THIRD-PARTY.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cuttle_browser-0.2.0.tar.gz (31.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cuttle_browser-0.2.0-py3-none-any.whl (33.3 kB view details)

Uploaded Python 3

File details

Details for the file cuttle_browser-0.2.0.tar.gz.

File metadata

  • Download URL: cuttle_browser-0.2.0.tar.gz
  • Upload date:
  • Size: 31.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cuttle_browser-0.2.0.tar.gz
Algorithm Hash digest
SHA256 4cd58081862dd2dcd3fb77dcba3ecce60547ebbad9c3e4f1c677d022fb300864
MD5 1621f7d37ff6ed20af0f7f6a3cad637d
BLAKE2b-256 4e3ef17defe13d288507b067c147b01e66246799bb234fa8bd21903e1fbf4326

See more details on using hashes here.

File details

Details for the file cuttle_browser-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: cuttle_browser-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 33.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cuttle_browser-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 271f241990e7f607cae10e169eb3b9c9fc7d44c9e70e04db9a79b86fb3253896
MD5 850d8c62dc538ba0fdf042589d22a9f8
BLAKE2b-256 5c5ca2b16a36c1def507781555035b70bea995e5c6896547f927821996ac5e47

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page