{"id":35835865,"url":"https://github.com/psyb0t/docker-stealthy-auto-browse","last_synced_at":"2026-04-16T01:03:58.265Z","repository":{"id":331883276,"uuid":"1129990129","full_name":"psyb0t/docker-stealthy-auto-browse","owner":"psyb0t","description":"Stealth browser automation that actually works. A Docker container running Camoufox (custom Firefox) with zero Chrome DevTools Protocol exposure, real OS-level mouse and keyboard input, and a dead-simple HTTP API to control it all.","archived":false,"fork":false,"pushed_at":"2026-04-04T20:12:22.000Z","size":180,"stargazers_count":34,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-04T22:35:45.922Z","etag":null,"topics":["automated","automation","browser","camoufox","container","docker","http-api","playwright","pyautogui","python","stealth","system-automation"],"latest_commit_sha":null,"homepage":"https://ciprian.51k.eu/docker-stealthy-auto-browse-the-browser-that-doesnt-know-its-being-automated/","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/psyb0t.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-07T21:50:57.000Z","updated_at":"2026-04-04T20:12:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/psyb0t/docker-stealthy-auto-browse","commit_stats":null,"previous_names":["psyb0t/docker-stealthy-auto-browse"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/psyb0t/docker-stealthy-auto-browse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-stealthy-auto-browse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-stealthy-auto-browse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-stealthy-auto-browse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-stealthy-auto-browse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/psyb0t","download_url":"https://codeload.github.com/psyb0t/docker-stealthy-auto-browse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-stealthy-auto-browse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31492751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automated","automation","browser","camoufox","container","docker","http-api","playwright","pyautogui","python","stealth","system-automation"],"created_at":"2026-01-08T00:14:02.269Z","updated_at":"2026-04-16T01:03:58.251Z","avatar_url":"https://github.com/psyb0t.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# docker-stealthy-auto-browse\n\nStealth browser automation that actually works. Runs Camoufox (custom Firefox) in Docker with zero Chrome DevTools Protocol exposure, real OS-level mouse and keyboard input via PyAutoGUI, and a JSON HTTP API + MCP server to control it all remotely. Watch it live via noVNC. Run a single instance or spin up a cluster behind HAProxy with Redis cookie sync, request queuing, and sticky sessions. Drive it with curl, pipe YAML scripts through stdin, send multi-step scripts via the API, use page loaders to auto-handle popups and paywalls, or connect AI agents directly via MCP. Optional Bearer token auth via `AUTH_TOKEN`.\n\nPasses Cloudflare, CreepJS, BrowserScan, Pixelscan, and every other bot detector we've thrown at it. While Chromium-based tools are getting caught by the first line of defense, this thing walks through the front door unnoticed.\n\n## Table of Contents\n\n- [What's Inside](#whats-inside)\n- [Quick Start](#quick-start)\n- [Two Input Modes](#two-input-modes)\n- [MCP Server](#mcp-server)\n- [Script Mode](#script-mode)\n- [Page Loaders](#page-loaders)\n- [Cluster Mode](#cluster-mode)\n- [Authentication](#authentication)\n- [Configuration](#configuration)\n- [Bot Detection Results](#bot-detection-results)\n- [License](#license)\n\n## What's Inside\n\n| Component      | What It Does                                                                                                                                                                                |\n| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Camoufox**   | A custom build of Firefox with zero Chrome DevTools Protocol exposure. Bot detectors look for CDP signals — this browser simply doesn't have any.                                           |\n| **Xvfb**       | Virtual framebuffer that lets the browser run with a full graphical display inside a container, no physical monitor needed. This matters because headless mode is another detection signal. |\n| **PyAutoGUI**  | Generates real OS-level mouse movements and keystrokes. The browser receives these as genuine user input — it has no idea it's being automated.                                             |\n| **noVNC**      | Web-based VNC client so you can watch the browser in real time from your own browser. Great for debugging and seeing exactly what's happening.                                              |\n| **HTTP API**   | A JSON API on port 8080 that lets you control everything — navigate pages, click elements, type text, take screenshots, manage tabs, handle cookies, and more.                              |\n| **MCP Server** | [Model Context Protocol](https://modelcontextprotocol.io/) server at `/mcp` on the same port. AI agents (Claude, etc.) can drive the browser directly over MCP using Streamable HTTP.       |\n\nPre-installed extensions: **uBlock Origin** (ads/trackers), **LocalCDN** (prevents CDN tracking), **ClearURLs** (strips tracking params), **Consent-O-Matic** (auto-handles cookie popups).\n\n## Quick Start\n\n```bash\ndocker run -d --name browser \\\n  -p 8080:8080 \\\n  -p 5900:5900 \\\n  psyb0t/stealthy-auto-browse\n```\n\nPort **8080** is the HTTP API, port **5900** is the VNC viewer (`http://localhost:5900/`).\n\n```bash\n# Navigate\ncurl -X POST http://localhost:8080 \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"action\": \"goto\", \"url\": \"https://example.com\"}'\n\n# Get page text\ncurl -X POST http://localhost:8080 \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"action\": \"get_text\"}'\n\n# Click by CSS selector (preferred — fast and reliable)\ncurl -X POST http://localhost:8080 \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"action\": \"click\", \"selector\": \"button#submit\"}'\n\n# Screenshot (last resort — prefer get_text; always resize to save tokens)\ncurl \"http://localhost:8080/screenshot/browser?whLargest=512\" -o screenshot.png\n```\n\n**Run multi-step scripts in one request:**\n\n```bash\ncurl -X POST http://localhost:8080 \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"action\": \"run_script\",\n    \"steps\": [\n      {\"action\": \"goto\", \"url\": \"https://example.com\", \"wait_until\": \"domcontentloaded\"},\n      {\"action\": \"sleep\", \"duration\": 2},\n      {\"action\": \"get_text\", \"output_id\": \"text\"},\n      {\"action\": \"eval\", \"expression\": \"document.title\", \"output_id\": \"title\"}\n    ]\n  }'\n```\n\nAlso accepts `\"yaml\": \"...\"` with the same YAML format used in script mode. In single-instance mode, requests are serialized automatically — send multiple scripts in parallel and they queue up.\n\nSee [docs/api.md](docs/api.md) for all actions and the full API reference.\n\n## Two Input Modes\n\nThere are two ways to interact with pages. **System input** uses PyAutoGUI to generate real OS-level mouse and keyboard events — the browser cannot tell these apart from a real human. **Playwright input** uses CSS selectors and DOM event injection — easier, but theoretically detectable by behavioral analysis. Use system input on any site with bot protection.\n\nFull breakdown and usage guide: [docs/stealth.md](docs/stealth.md)\n\n## MCP Server\n\nAI agents can control the browser over the [Model Context Protocol](https://modelcontextprotocol.io/) via Streamable HTTP at `/mcp` on the same port 8080. All browser actions are exposed as MCP tools — navigation, screenshots, clicking, typing, JavaScript evaluation, cookies, and more.\n\nConnect any MCP-compatible client (Claude Desktop, Claude Code, custom agents) to `http://localhost:8080/mcp/` and start browsing.\n\nWorks in both standalone and [cluster mode](#cluster-mode) — HAProxy routes MCP traffic with the same sticky sessions as the HTTP API.\n\n## Script Mode\n\nPipe a YAML script into the container, get JSON results on stdout, container exits. No HTTP server. Good for CI, cron jobs, one-shot scraping.\n\n```bash\ncat my-script.yaml | docker run --rm -i \\\n  -e TARGET_URL=https://example.com \\\n  psyb0t/stealthy-auto-browse --script \u003e results.json\n```\n\nFull docs: [docs/script-mode.md](docs/script-mode.md)\n\n## Page Loaders\n\nDefine URL patterns + action sequences in YAML files. Mount them at `/loaders`. Whenever `goto` matches a pattern, the loader runs automatically — removes popups, waits for content, cleans up the page. Greasemonkey for the HTTP API.\n\nFull docs: [docs/page-loaders.md](docs/page-loaders.md)\n\n## Cluster Mode\n\nRun multiple browser instances behind HAProxy with a request queue, sticky sessions, and Redis cookie sync (default 10, configurable via `NUM_REPLICAS`). Download the compose file and HAProxy config, then start:\n\n```bash\ncurl -LO https://raw.githubusercontent.com/psyb0t/docker-stealthy-auto-browse/main/docker-compose.cluster.yml\ndocker compose -f docker-compose.cluster.yml up -d\n```\n\nCookies set on any instance propagate to all others instantly via Redis PubSub. Log in once, the whole fleet is authenticated.\n\nFull docs: [docs/cluster-mode.md](docs/cluster-mode.md)\n\n## Authentication\n\nSet `AUTH_TOKEN` to require a Bearer token on all requests (except `/health`):\n\n```bash\ndocker run -d -p 8080:8080 -e AUTH_TOKEN=mysecretkey psyb0t/stealthy-auto-browse\n```\n\nPass the token via header or query param:\n\n```bash\n# Header\ncurl -H \"Authorization: Bearer mysecretkey\" http://localhost:8080 ...\n\n# Query param (useful for MCP clients that can't set headers)\n# MCP endpoint: http://localhost:8080/mcp/?auth_token=mysecretkey\n```\n\n## Examples\n\nSee [`.agents/.skills/stealthy-auto-browse/scripts/`](.agents/.skills/stealthy-auto-browse/scripts/) for ready-to-use scripts:\n\n- **[`websearch.py`](.agents/.skills/stealthy-auto-browse/scripts/websearch.py)** — Multi-engine parallel web search (Brave, Google, Bing) with structured results and AI overview extraction. Outputs JSON with title, URL, and snippet for each result.\n\n## Configuration\n\nFull environment variables table, proxy setup, persistent profiles, browser extensions, and VNC access: [docs/configuration.md](docs/configuration.md)\n\n## Bot Detection Results\n\n| Service                                                                | Result   | What They Check                                                         |\n| ---------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------- |\n| [CreepJS](https://abrahamjuliot.github.io/creepjs/)                    | **Pass** | Canvas/WebGL fingerprint consistency, lies detection, worker comparison |\n| [BrowserScan](https://www.browserscan.net/bot-detection)               | **Pass** | WebDriver flag, CDP signals, navigator properties                       |\n| [Pixelscan](https://pixelscan.net/)                                    | **Pass** | Fingerprint coherence, timezone/IP match, WebRTC leaks                  |\n| [Cloudflare](https://cloudflare.com)                                   | **Pass** | Challenge pages, Turnstile, bot management                              |\n| [SannySoft](https://bot.sannysoft.com/)                                | **Pass** | Intoli + fingerprint scanner tests                                      |\n| [Incolumitas](https://bot.incolumitas.com/)                            | **Pass** | Modern detection techniques                                             |\n| [Rebrowser](https://bot-detector.rebrowser.net/)                       | **Pass** | CDP leak detection, webdriver, viewport analysis                        |\n| [BrowserLeaks WebRTC](https://browserleaks.com/webrtc)                 | **Pass** | WebRTC IP leak detection                                                |\n| [DeviceAndBrowserInfo](https://deviceandbrowserinfo.com/are_you_a_bot) | **Pass** | 19 checks, all green, \"You are human!\"                                  |\n| [IpHey](https://iphey.com/)                                            | **Pass** | \"Trustworthy\" rating                                                    |\n| [Fingerprint.com](https://fingerprint.com/demo/)                       | **Pass** | Identified as normal Firefox, no bot flags                              |\n\nWhy it works: [docs/stealth.md](docs/stealth.md)\n\n## Known Issues / TODO\n\n- **`system_click` reliability** — OS-level mouse clicks can land in the wrong place if the window offset is stale. Needs a more robust coordinate mapping solution so it works reliably without manual `calibrate` calls.\n\n## License\n\n**WTFPL** — Do What The Fuck You Want To Public License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsyb0t%2Fdocker-stealthy-auto-browse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpsyb0t%2Fdocker-stealthy-auto-browse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsyb0t%2Fdocker-stealthy-auto-browse/lists"}