Skip to main content
Glama

chrome-driverless

中文文档

A persistent, headed Chrome driven by Playwright, exposed through an MCP-style HTTP API (POST /mcp) with a built-in web console. Humans and AI agents share one long-lived browser: log in once through the console, then drive it via HTTP, CDP, Node.js scripts — or let an LLM complete tasks for you.

Highlights

  • Persistent context — login state survives restarts in data/profiles/<name>/auth.json (exportable for reuse)

  • MCP-style HTTP API — navigate, screenshot, click, type, keys, hover, evaluate, tabs, profiles, proxy toggle, raw mouse / scroll control

  • Web console — layered live viewport (screenshot / element-highlight / virtual-cursor layers), touchpad-style pointer control, element picker, built-in DevTools

  • Human mode — a bare Chromium with zero Playwright/CDP attachment, purpose-built for Cloudflare / Turnstile challenge pages (open the challenge, wait 5–15 s, it passes)

  • Fingerprint profiles — real / Chrome·Win / Chrome·Mac / Safari·Mac, each self-consistent across HTTP User-Agent, JS platform/vendor/userAgentData, and sec-ch-ua headers

  • Stealth audit — the classic 0–7 anti-detection checklist made runnable in one call (pw/stealth_audit, human/stealth_audit)

  • Humanized input — mouse trajectories and keystroke cadence with reproducible seeds (HUMANIZE_SEED)

  • Clipboard interop — Ctrl+C / Ctrl+V bridged between your machine and the remote page (paste = one-shot insertText, copy reads the remote selection)

  • Network consistency — browser timezone aligned with the proxy's egress timezone; UA / sec-ch-ua coherence

  • Real Google Chrome engine — set BROWSER_ENGINE=chrome for native brands + Widevine (fixes the two biggest Chromium-for-Testing fingerprint tells)

  • GPU passthrough — WebGL renderer probing; real GPU by default when available (no SwiftShader software-rendering tell)

  • Audio streaming — hear the browser at /audio.mp3 (PulseAudio null-sink → parec → ffmpeg)

  • AI tasks — a browser-use-style agent: the DOM is distilled into numbered interactive elements ([3] <button>Sign in</button>), the LLM answers with index-based actions and self-corrects from execution feedback; any OpenAI-compatible endpoint works (DeepSeek preset), and a vision mode attaches screenshots for multimodal models

  • Env-driven auto login — pw/auto_login fills login forms from BROWSER_LOGIN_* env vars, no credentials in code

  • Node.js job scripts — pw/run_script executes scripts that connectOverCDP into the same browser, sharing login state

  • Modular codebase — main.py + cd_*.py modules, each ≤600 lines

Related MCP server: browser-control-mcp-server

Quick start

pip install -r requirements.txt
python main.py        # serves 0.0.0.0:9223

Or with Docker (images built by GitHub Actions):

docker run -d --name chrome-driverless \
  -p 9223:9223 \
  -v chrome-data:/app/data \
  ghcr.io/friddle/chrome-driverless:latest

# real Google Chrome engine instead of Chromium-for-Testing:
docker run -d -p 9223:9223 -v chrome-data:/app/data \
  -e BROWSER_ENGINE=chrome \
  ghcr.io/friddle/chrome-driverless:latest

Open http://localhost:9223/ for the console.

Environment variables

Variable

Description

Default

BROWSER_DATA_DIR

Persistent data dir (profiles / auth.json / browser profile)

./data

PROFILE_NAME

Profile activated at startup

debug

BROWSER_ENGINE

chromium (Playwright CfT) or chrome (real Google Chrome)

chromium

HTTP_PROXY / HTTPS_PROXY

Browser proxy (empty = no proxy)

empty

NO_PROXY

Comma-separated no-proxy list

localhost,127.0.0.1

REMOTE_DEBUG_PORT

Chrome CDP port for external connectOverCDP scripts

9222

EXTERNAL_URL

External access URL (shown in logs / /debug/url)

empty

AI_MODEL / AI_BASE_URL

Default model + endpoint for AI tasks

empty

BROWSER_LOGIN_URL / BROWSER_LOGIN_USERNAME / BROWSER_LOGIN_PASSWORD

Credentials for pw/auto_login

empty

HUMANIZE_SEED

Fix the humanized-input RNG seed for reproducibility

random

Proxies are intentionally empty by default — inject them via env vars instead of hardcoding addresses.

HTTP endpoints

  • GET / — web console

  • GET /health

  • POST /mcp — MCP method call: {"method": "pw/...", "params": {...}}

  • GET /debug/status · /debug/logs · /debug/files · /debug/url

  • GET /audio.mp3 — live browser audio stream

  • GET /devtools/targets, GET /devtools/{rest} (+ WS bridges) — Chrome DevTools

MCP methods

Method

Description

pw/init_browser

Init / reuse the persistent browser

pw/navigate, pw/back, pw/reload

Navigation (returns screenshot)

pw/screenshot

Screenshot of the current page (base64)

pw/click, pw/hover, pw/type, pw/key, pw/clear

Humanized click / hover / typing (instant = paste semantics) / key / clear

pw/clip_read, human/clip_read

Read the remote page's selected text (clipboard-interop copy side)

pw/evaluate

Run JS in the current page

pw/elements

List interactive elements (id / selector / coordinates)

pw/auto_login

Env-driven form login (QR → password tab switch included)

pw/tabs, pw/tab_select, pw/tab_close, pw/tab_close_all, pw/tab_tag, pw/new_tab

Multi-tab management (pw/new_tab {tab: name} named create, idempotent reuse, returns tab name)

pw/profile_list, pw/profile_set

Profile-isolated login states

pw/save_auth

Export current login state to auth.json

pw/set_proxy

Toggle browser proxy (aligns timezone to egress)

pw/mouse_move, pw/mouse_down, pw/mouse_up, pw/scroll_at

Raw pointer / scroll control

pw/run_script, pw/run_script_content

Run Node.js scripts via connectOverCDP (same browser, shared auth)

pw/ai_task, pw/ask_deepseek

LLM-driven task execution

pw/stealth_audit

Stealth audit on the Playwright-driven page

human/status, human/set_mode, human/gpu_set

Human mode / GPU passthrough switching

human/screenshot, human/navigate, human/reload, human/tabs, human/new_tab, human/tab_select, human/tab_close, human/back

Human-mode page ops

human/click, human/hover, human/type, human/key, human/clear

Human-mode input

human/mouse_move, human/mouse_down, human/mouse_up, human/scroll_at

Human-mode pointer control

human/stealth_audit

Stealth audit inside human mode

fp/set

Fingerprint profile: real | chrome_win | chrome_mac | safari_mac

ai/config_get, ai/config_set, ai/test, ai/cancel

AI task configuration

Multi-tab concurrency & per-tab lock

One profile supports operating multiple tabs at the same time. Convention:

  1. pw/new_tab {tab: "my-task", url: ...} creates (or reuses) a named tab; the response carries the tab name;

  2. Any later pw/* call with {tab: "my-task"} runs on that tab (resolved by name; unknown names fail with tab not found);

  3. Lock granularity is per tab: requests on the same tab are serialized — the next request starts only after the previous one finishes (locked automatically before execution); different tabs run concurrently;

  4. Calls without tab take the global lock (single-browser serial semantics unchanged); ai/cancel bypasses locks so long tasks can always be interrupted;

  5. /debug/status exposes tab_busy showing which named tabs currently have a task running.

Module map

File

Responsibility

main.py

MCP dispatch + startup events

cd_app.py / cd_config.py / cd_state.py

FastAPI app · env config & fingerprint profiles · global state & persistence

cd_routes.py

HTTP/WS routes, debug endpoints, DevTools proxy

cd_browser.py

Persistent Playwright context, tabs, profiles

cd_actions.py

Page actions, humanized input, auto login

cd_human.py / cd_human_ops.py

Human-mode lifecycle · human-mode page operations

cd_audit.py / cd_stealth.py

Stealth audit checklist · stealth JS injection

cd_cdp.py

Raw CDP helpers, GPU / WebGL probing

cd_agent.py

browser-use-style task agent: element-indexed action space, same-origin iframe recursion, step-by-step logging

cd_ai.py

LLM client (messages + vision shards), AI config, Node script runner

cd_audio.py

PulseAudio → parec → ffmpeg → /audio.mp3

Embedding into your app

  1. Run the service (docker or bare) and expose port 9223.

  2. Open the console URL in an in-app tab / iframe.

  3. Log in to target sites in the console — state persists in auth.json for later scripts / CDP connections.

The service itself has no built-in auth — it is meant as an internal / embedded tool. Put an authenticating reverse proxy in front if you need access control.

Disclaimer

For personal learning and self-hosted automation only. Respect the terms of service of the websites you visit.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables AI coding assistants to control a persistent Chrome browser through DevTools Protocol. Supports web navigation, screenshots, element interaction, mobile testing, console logs, and network debugging in a stable Docker environment.
    10
    8
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents and clients to control a real Chromium browser through MCP tool calls, including navigation, clicking, typing, JavaScript evaluation, screenshots, and DOM snapshots. Supports multiple isolated sessions over authenticated HTTP with no disk writes.
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to run Playwright-compatible browser automation with persistent profiles, proxies, Chrome extensions, and humanized mouse, keyboard, and scroll interactions over stdio or Streamable HTTP. Supports web research, daily automation, testing workflows, and optional session-scoped CDP access.
    541 npm
    MIT