{"repo":"jo-inc/camofox-browser","free":true,"listed":false,"github":"https://github.com/jo-inc/camofox-browser","clone":"git clone https://github.com/jo-inc/camofox-browser.git","description":"Stealth headless browser for AI agents — bypass Cloudflare, bot detection, and anti-scraping. Drop-in Puppeteer/Playwright replacement.","language":"JavaScript","stars":8634,"topics":["ai-agent","anti-bot","antidetect-browser","automation","bot-detection","browser-automation","cloudflare-bypass","headless-browser","javascript","nodejs","playwright","puppeteer","scraping","stealth-browser","web-scraping"],"license":"MIT","category":"anti_bot_api","readme_excerpt":"<div align=\"center\">\n  <img src=\"fox.png\" alt=\"camofox-browser\" width=\"200\" />\n  <h1>camofox-browser</h1>\n  <p><strong>Anti-detection browser server for AI agents, powered by Camoufox</strong></p>\n  <p>\n    <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\" /></a>\n    <a href=\"https://github.com/jo-inc/camofox-browser/stargazers\"><img src=\"https://img.shields.io/github/stars/jo-inc/camofox-browser\" alt=\"GitHub stars\" /></a>\n    <a href=\"https://www.npmjs.com/package/camofox-browser\"><img src=\"https://img.shields.io/npm/v/camofox-browser\" alt=\"npm version\" /></a>\n    <a href=\"https://github.com/jo-inc/camofox-browser/commits\"><img src=\"https://img.shields.io/github/last-commit/jo-inc/camofox-browser\" alt=\"GitHub last commit\" /></a>\n  </p>\n  <p>\n    Standing on the mighty shoulders of <a href=\"https://camoufox.com\">Camoufox</a> - a Firefox fork with fingerprint spoofing at the C++ level.\n  </p>\n</div>\n\n<br/>\n\n> <a href=\"https://askjo.ai?ref=camofox\"><img src=\"jo-logo.png\" alt=\"Jo\" width=\"80\" height=\"80\" align=\"left\" /></a>\n>\n> Built by the team behind <a href=\"https://askjo.ai?ref=camofox\"><strong>jo, a personal AI agent</strong></a> that runs half on your Mac, half on a dedicated cloud machine just for you -- with zero maintenance needed. Available on macOS, Telegram, WhatsApp, and email. <a href=\"https://askjo.ai?ref=camofox\">Try the beta free -></a>\n\n<br/>\n\n```bash\ngit clone https://github.com/jo-inc/camofox-browser && cd camofox-browser\nnpm install && npm start\n# -> http://localhost:9377\n```\n\n---\n\n## Why\n\nAI agents need to browse the real web. Playwright gets blocked. Headless Chrome gets fingerprinted. Stealth plugins become the fingerprint.\n\nCamoufox patches Firefox at the **C++ implementation level** - `navigator.hardwareConcurrency`, WebGL renderers, AudioContext, screen geometry, WebRTC - all spoofed before JavaScript ever sees them. No shims, no wrappers, no tells.\n\nThis project wraps that engine in a REST API built for agents: accessibility snapshots instead of bloated HTML, stable element refs for clicking, and search macros for common sites.\n\n## Features\n\n- **C++ Anti-Detection** - bypasses Google, Cloudflare, and most bot detection\n- **Element Refs** - stable `e1`, `e2`, `e3` identifiers for reliable interaction\n- **Token-Efficient** - accessibility snapshots are ~90% smaller than raw HTML\n- **Runs on Anything** - lazy browser launch + idle shutdown keeps memory at ~40MB when idle. Designed to share a box with the rest of your stack -- Raspberry Pi, $5 VPS, shared infra.\n- **Session Isolation** - separate cookies/storage per user\n- **Cookie Import** - inject Netscape-format cookie files for authenticated browsing\n- **File Upload** - attach files from a configured upload directory without a native OS dialog\n- **Proxy + GeoIP** - route traffic through residential proxies with automatic locale/timezone\n- **Structured Logging** - JSON log lines with request IDs for production observability\n- **YouTube Transcripts** - extract captions from any YouTube video via yt-dlp, no API key needed\n- **Search Macros** - `@google_search`, `@youtube_search`, `@amazon_search`, `@reddit_subreddit`, and 10 more\n- **Snapshot Screenshots** - include a base64 PNG screenshot alongside the accessibility snapshot\n- **Large Page Handling** - automatic snapshot truncation with offset-based pagination\n- **Download Capture** - capture browser downloads and fetch them via API (optional inline base64)\n- **DOM Image Extraction** - list `<img>` src/alt and optionally return inline data URLs\n- **Deploy Anywhere** - Docker, Fly.io, Railway\n- **VNC Interactive Login** - log into sites visually via noVNC, export storage state for agent reuse\n- **OpenAPI Docs** - auto-generated spec at [`/openapi.json`](http://localhost:9377/openapi.json) and interactive docs at [`/docs`](http://localhost:9377/docs)\n- **Structured Extract** - `POST /tabs/:tabId/extract` with a JSON Schema that maps properties to snapshot refs via `x-ref`\n- **Session Tracing** - opt-in per-session Playwright trace capture (screenshots + DOM snapshots + network) with API endpoints to list, fetch, and delete trace zips\n- **Telemetry** - automatic [anonymized crash/hang telemetry](lib/reporter.js#L28-L290) via GitHub Issues. Identifies which sites cause failures and common failure patterns. Private domains are HMAC-hashed, paths/params stripped, tokens/IPs redacted. Opt-out with `CAMOFOX_CRASH_REPORT_ENABLED=false`.\n\n## Optional Dependencies\n\n| Dependency | Purpose | Install |\n|-----------|---------|---------|\n| [yt-dlp](https://github.com/yt-dlp/yt-dlp) | YouTube transcript extraction (fast path) | `pip install yt-dlp` or `brew install yt-dlp` |\n\nThe Docker image includes yt-dlp. For local dev, install it for the `/youtube/transcript` endpoint. Without it, the endpoint falls back to a slower browser-based method.\n\n## Quick Start\n\n### OpenClaw Plugin\n\n```bash\nopenclaw plugins install @askjo/camofox-browser\n```\n\n**Tools:** `camofox_create_tab`  |  `camofox_snapshot`  |  `camofox_click`  |  `camofox_type`  |  `camofox_navigate`  |  `camofox_scroll`  |  `camofox_screenshot`  |  `camofox_close_tab`  |  `camofox_list_tabs`  |  `camofox_import_cookies`\n\n### Standalone\n\nRun from npm:\n\n```bash\nnpx @askjo/camofox-browser\n```\n\nOr from source:\n\n```bash\ngit clone https://github.com/jo-inc/camofox-browser\ncd camofox-browser\nnpm install\nnpm start  # downloads Camoufox on first run (~300MB)\n```\n\nDefault port is `9377`. See [Environment Variables](#environment-variables) for all options.\n\n> **Note:** the postinstall script unsets `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` for itself before fetching the Camoufox binary. Without that override, an exported `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1` (common when Playwright is configured to use system Chrome) would silently skip the binary download and crash the server at runtime.\n>\n> **External Camoufox executable:** set `CAMOUFOX_EXECUTABLE=/path/to/camoufox-bin` before `npm install` and when starting the server to skip the bundled download and launch that executable. Compatibility aliases are `CAMOUFOX_EXECUTABLE_PATH` and `CAMOFOX_EXECUTABLE_PATH`. This is useful for NixOS paths such as `/nix/store/.../camoufox-bin`; the executable must come from a Camoufox bundle that includes `properties.json`, `version.json`, and `fontconfig/`.\n>\n> **Air-gapped or custom binary management:** prefer `CAMOUFOX_EXECUTABLE` when you already have a Camoufox bundle. Otherwise disable the auto-fetch with `npm install --ignore-scripts` (skips lifecycle scripts for *every* dependency -- bluntest option) or, more surgically, `npm install --omit=optional` plus a manual `npx camoufox-js fetch` step against your mirror. Note that `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install` no longer skips the Camoufox download (the postinstall sanitizes the env locally); use `--ignore-scripts` or `CAMOUFOX_EXECUTABLE` for that.\n\n### Docker\n\nThe included `Makefile` auto-detects your CPU architecture and pre-downloads Camoufox + yt-dlp binaries outside the Docker build, so rebuilds are fast (~30s vs ~3min).\n\n```bash\n# Build and start (auto-detects arch: aarch64 on M1/M2, x86_64 on Intel)\nmake up\n\n# Stop and remove the container\nmake down\n\n# Force a clean rebuild (e.g. after upgrading VERSION/RELEASE)\nmake reset\n\n# Just download binaries (without building)\nmake fetch\n\n# Override arch or version explicitly\nmake up ARCH=x86_64\nmake up VERSION=135.0.1 RELEASE=beta.24\n```\n\n#### Windows\n\nOn Windows, `make` is not available. Use the included `build.ps1` PowerShell script instead:\n\n```powershell\n# Build and start\n.\\build.ps1 up\n\n# Stop and remove the container\n.\\build.ps1 down\n\n# Build image only\n.\\build.ps1 build\n\n# Force a clean rebuild\n.\\build.ps1 reset\n\n# Download binaries only (without building)\n.\\build.ps1 fetch\n\n# Override architecture\n.\\build.ps1 up -Arch x86_64\n.\\build.ps1 up -Arch aarch64\n```\n\n> **Note:** PowerShell 7+ (`pwsh`) is recommended but `powershell.exe` (Windows PowerShell 5.1) also works. The script requires Docker Desktop for Windows with the WSL2 backend.\n>\n> **Line endings:** This project includes a `.gitattributes` file that forces Unix (`LF`) line endings for `.sh` files. If you've already cloned the repo and get `sh: not found` or `set: Illegal option -` errors during `docker build`, run:\n> ```powershell\n> Get-ChildItem -Recurse *.sh | ForEach-Object { (Get-Content $_) -join \"`n\" + \"`n\" | Set-Content $_ -NoNewline }\n> ```\n> This converts shell scripts to LF line endings. Future clones will handle this automatically thanks to `.gitattributes`.\n\n> **WARNING: Do not run `docker build` directly.** The Dockerfile uses bind mounts to pull pre-downloaded binaries from `dist/`. Always use `make up` (or `make fetch` then `make build`) -- it downloads the binaries first.\n\n### Fly.io\n\nFor Fly.io or other remote CI, you'll need a Dockerfile that downloads binaries at build time instead of using bind mounts.\n\n### Railway\n\nA `railway.toml` is included. It uses `Dockerfile.ci` (which downloads binaries at build time) and maps Railway's `PORT` env var to `CAMOFOX_PORT` automatically.\n\n```bash\n# Install Railway CLI, then:\nrailway link\nrailway up\n```\n\nSet secrets via the Railway dashboard or CLI:\n```bash\nrailway variables set CAMOFOX_API_KEY=\"your-generated-key\"\n```\n\n## Usage\n\n### Cookie Import\n\nImport cookies from your browser into Camoufox to skip interactive login on sites like LinkedIn, Amazon, etc.\n\n#### Setup\n\n**1. Generate a secret key:**\n\n```bash\n# macOS / Linux\nopenssl rand -hex 32\n```\n\n**2. Set the environment variable before starting OpenClaw:**\n\n```bash\nexport CAMOFOX_API_KEY=\"your-generated-key\"\nopenclaw start\n```\n\nThe same key is used by both the plugin (to authenticate requests) and the server (to verify them). Both run from the same environment -- set it once.\n\n> **Why an env var?** The key is a secret. Plugin config in `openclaw.json` is stored in plaintext, so secrets don't belong there. Set `CAMOFOX_API_KEY` in your shell profi","default_branch":"master","files":196,"tree":[".gitattributes",".github/CODEOWNERS",".github/FUNDING.yml",".github/workflows/auto-close-old-reports.yml",".github/workflows/ci.yml",".github/workflows/clawhub-publish.yml",".github/workflows/docker.yml",".github/workflows/mirror-camoufox.yml",".github/workflows/publish.yml",".github/workflows/telemetry-deploy.yml",".gitignore","AGENTS.md","CONTRIBUTING.md","Dockerfile","Dockerfile.ci","LICENSE","Makefile","README.md","bin/camofox-browser.js","build.ps1","camofox-og.png","camofox.config.json","changelog/1.4.0.md","docs/api.html","docs/fox.png","docs/openapi.json","fox.png","jest.config.cjs","jest.config.e2e.cjs","jo-logo.png","lib/auth.js","lib/browser-errors.js","lib/browser-processes.js","lib/camoufox-executable.js","lib/config.js","lib/cookies.js","lib/downloads.js","lib/extract.js","lib/fly.js","lib/images.js","lib/inflight.js","lib/launcher.js","lib/macros.js","lib/mcp-tool-contracts.mjs","lib/metrics.js","lib/new-page-recovery.js","lib/openapi.js","lib/page-lease.js","lib/persistence.js","lib/plugins.js","lib/process-ownership.js","lib/proxy.js","lib/reporter.js","lib/request-utils.js","lib/resources.js","lib/sentry.js","lib/snapshot.js","lib/tmp-cleanup.js","lib/tracing.js","lib/upload-paths.js","mcp/README.md","mcp/lib/config.mjs","mcp/lib/cookies.mjs","mcp/lib/tool-contracts.mjs","mcp/package-lock.json","mcp/package.json","mcp/server.mjs","openapi.json","openclaw.plugin.json","package-lock.json","package.json","plugin.js","plugin.ts","plugins/persistence/AGENTS.md","plugins/persistence/README.md","plugins/persistence/index.js","plugins/persistence/persistence.test.js","plugins/persistence/plugin.test.js","plugins/vnc/AGENTS.md","plugins/vnc/README.md","plugins/vnc/apt.txt","plugins/vnc/index.js","plugins/vnc/plugin.json","plugins/vnc/spawn.js","plugins/vnc/vnc-launcher.js","plugins/vnc/vnc-launcher.test.js","plugins/vnc/vnc-watcher-lib.sh","plugins/vnc/vnc-watcher.sh","plugins/vnc/vnc-watcher.test.js","plugins/vnc/vnc.test.js","plugins/youtube/AGENTS.md","plugins/youtube/apt.txt","plugins/youtube/index.js","plugins/youtube/post-install.sh","plugins/youtube/youtube.js","plugins/youtube/youtube.test.js","railway.toml","release.sh","run.sh","scripts/exec.js","scripts/generate-openapi.js","scripts/install-plugin-deps.sh","scripts/mcp-call.mjs","scripts/mcp-run.mjs","scripts/plugin.js","scripts/plugin.test.js","scripts/postinstall.js","scripts/postinstall.test.js","scripts/sync-version.js","scripts/test-mcp-package.mjs","scripts/test-mcp.mjs","server.js","tests/e2e/concurrency.test.js","tests/e2e/downloadsImages.test.js","tests/e2e/evaluateNavigationRace.test.js","tests/e2e/formSubmission.test.js","tests/e2e/globalSetup.js","tests/e2e/globalTeardown.js","tests/e2e/macroNavigation.test.js","tests/e2e/navigation.test.js","tests/e2e/screenshot.test.js","tests/e2e/scroll.test.js","tests/e2e/sharedEnv.js","tests/e2e/snapshot-truncation.test.js","tests/e2e/snapshotLinks.test.js","tests/e2e/snapshotScreenshot.test.js","tests/e2e/tabLifecycle.test.js","tests/e2e/typingEnter.test.js","tests/e2e/upload.test.js","tests/e2e/viewport.test.js","tests/helpers/client.js","tests/helpers/startServer.js","tests/helpers/test-env.js","tests/helpers/testSite.js","tests/live/googleSearch.test.js","tests/live/macroExpansion.test.js","tests/unit/accessKey.test.js","tests/unit/auth.test.js","tests/unit/autoCookieImport.test.js","tests/unit/browserErrors.test.js","tests/unit/browserProcesses.test.js","tests/unit/camoufoxExecutable.test.js","tests/unit/clickBoundingBoxTimeout.test.js","tests/unit/config.test.js","tests/unit/cookies.test.js","tests/unit/crashRelay.test.js","tests/unit/crashRelayWorker.test.js","tests/unit/downloads.test.js","tests/unit/evaluateErrors.test.js","tests/unit/extract.test.js","tests/unit/flyReplay.test.js","tests/unit/healthSemantics.test.js","tests/unit/idleShutdown.test.js","tests/unit/inflight.test.js","tests/unit/launchCompat.test.js","tests/unit/macros.test.js","tests/unit/mcp-contracts.test.js","tests/unit/memoryPressure.test.js","tests/unit/navigateAbort.test.js","tests/unit/navigationTimeout.test.js","tests/unit/netscapeParser.test.js","tests/unit/newPageRecovery.test.js","tests/unit/noSecrets.test.js","tests/unit/openapi.test.js","tests/unit/openclawManifest.test.js","tests/unit/operationalFailures.test.js","tests/unit/pageLease.test.js","tests/unit/plugins.test.js","tests/unit/processOwnership.test.js","tests/unit/proxy.test.js","tests/unit/proxyRotation.test.js","tests/unit/reporter.test.js","tests/unit/resources.test.js","tests/unit/screenshotToolResult.test.js","tests/unit/security.test.js","tests/unit/serverShutdownEvent.test.js","tests/unit/sessionCleanup.test.js","tests/unit/sessionDestroyingEvent.test.js","tests/unit/snapshot.test.js","tests/unit/syncVersion.test.js","tests/unit/tabIdUuid.test.js","tests/unit/tabLeak.test.js","tests/unit/tabLifecycleContract.test.js","tests/unit/tabRecycling.test.js","tests/unit/tmpCleanup.test.js","tests/unit/tracing.test.js","tests/unit/tracingApi.test.js","tests/unit/typeKeyboardMode.test.js","tests/unit/uploadEndpoint.test.js","tests/unit/uploadPaths.test.js","tests/unit/viewport.test.js","tests/vnc-linux-smoke.sh","tsconfig.json","workers/crash-reporter/index.ts","workers/crash-reporter/wrangler.toml","x-banner.png"],"storefront":"/r/jo-inc","claimed":false,"request_supported":{"post":"https://gitbuyer.com/r/jo-inc/camofox-browser/request-supported","requests":0},"note":"indexed from public GitHub; nothing is for sale on this page. Clone it from GitHub. Paid listings live at /search."}