camofox-browser

redf0x1MIT活跃维护

把 Camoufox 反检测浏览器引擎封装成 REST API 服务,让 AI 智能体通过接口驱动浏览器自动化,绕过指纹识别和机器人检测。

Anti-detection browser server for AI agents — REST API wrapping Camoufox engine with OpenClaw plugin support

v2.5.0发布于 2026-11-06 03:13 UTC442star +5 / 7 天64fork同步于 2026-11-10 23:58 UTC

怎么上手

由 README 提炼,执行前请确认
git clone https://github.com/redf0x1/camofox-browser.git
cd camofox-browser
npm install
npm run build
npm start
硬件要求按 README 说明

README 未说明显存或 GPU 要求;需 Node.js 22+,安装时下载 Camoufox 引擎,Linux 解压需 Python 3;Windows x64 仅支持 headless=true,虚拟显示模式仅限 Linux。

有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

给 AI Agent 用的反检测浏览器服务器,用 REST API 封装 Camoufox 引擎,在 C++ 引擎层伪装指纹

把 Camoufox 反检测浏览器引擎封装成 REST API 服务,让 AI 智能体通过接口驱动浏览器自动化,绕过指纹识别和机器人检测。

核心能力

  • 在 Camoufox 引擎层做 C++ 指纹伪装,不靠 JS 注入
  • 提供语言无关的 REST API,便于任意语言和 AI Agent 接入
  • 按 userId 隔离多会话,默认最多 50 会话、每会话 10 标签
  • 每个用户持久化 Firefox 配置,保留 Cookie 与 localStorage
  • 内置 8 个地区预设和 14 个搜索宏,支持按会话覆盖代理

容易踩的坑

npm install 会下载 Camoufox 引擎,失败即中断,需预留 ZIP 和解压后两份磁盘空间;Linux 上解压依赖 python3,需先安装;设置 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 后须在启动前取消该变量并运行 npm run browser:install;非回环地址且 CAMOFOX_AUTH_MODE=auto 时必须设置 CAMOFOX_API_KEY;项目处于 Preview,升级可能需手动删除 profile、会话文件或下载注册表。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v2.5.0
  1. v2.5.0camofox-browser v2.5.0最新正式版2026-11-06 · 2026-11-06 03:13 UTC

    Network capture and safer navigation reporting

    • Add opt-in network capture before the first navigation, explicit session-tab enrollment, bounded retention, paginated inspection, and sanitized HAR 1.2 export.
    • Add explicitly enabled small response bodies and exact-match fetch/XHR abort/static mock rules. Metadata-only capture remains the default.
    • Align the OpenAPI interception contract with supported statuses, required fields, and UTF-8 byte limits.
    • Redact URL credentials, query strings, and fragments from snapshot/click/navigation logs.
    • Fix premature success reporting for delayed blocked select/evaluate navigations while preserving private-network denial and ordinary-action responsiveness.

    Use with camofox-mcp 1.17.0+ for the six network tools. Browser requires Node.js 22+. Windows x64 remains headless-only.

    Install

    Install the published npm version:

    npm install -g [email protected]
    

    The verified .tgz attached to this release remains available for direct installation.

    The Windows x64 portable ZIP bundles the runtime and engine. Docker: ghcr.io/redf0x1/camofox-browser:2.5.0.

    Safety and dependency scope

    Body capture and interception require explicit server-side enablement and authentication. Capture keys are private; URL paths and opted-in bodies can still contain application data, so review exports before sharing. This release does not change profile formats or require deleting existing profiles.

    The source/container dependency audit is clean. Fresh npm consumer installs follow upstream ranges and retain indirect glob/minimatch advisory warnings in the currently unused Camoufox dependency path; do not interpret the source audit as a clean audit of that consumer resolution.

    Verification

    The settled candidate passed 710 browser tests (19 intentionally skipped), Linux/Windows CI, Windows portable verification, package-contract checks, independent lifecycle review, and real Camoufox acceptance of both installable packages through MCP stdio and Streamable HTTP. See the repository changelog for details.

  2. v2.4.9camofox-browser v2.4.92026-10-25 · 2026-10-25 10:26 UTC
    查看更新说明

    Camofox Browser 2.4.9

    Fixes

    • Required browser installation now fails clearly if the engine cannot be downloaded, extracted or validated. Docker no longer publishes an apparently successful image with a missing engine; optional GeoLite downloads remain warning-only.
    • Browser downloads stream to disk, and extraction uses disk-backed system facilities rather than loading the entire archive into memory. Linux uses Python 3, macOS uses system tar, and Windows uses built-in PowerShell/.NET ZIP support.
    • Existing browser profiles and caches are preserved. Missing-engine recovery points to engine installation, not deletion of login profiles.
    • Published consumers receive the patched adm-zip range through the updated camoufox-js dependency. SQLite prebuild metadata is retained so clean dependency installation does not unnecessarily require a compiler.
    • The Windows portable build retains native-module version, architecture and SHA-256 verification.
    • The canonical AGENTS.md guide is now tracked in the repository.

    Upgrade requirements

    Node.js 22+ is required for npm installations. Upgrade Node before installing on Node 20 or older. The Windows portable package includes its own supported runtime.

    Linux npm hosts need python3. If an existing engine cache is incomplete, preserve it and your browser profiles; choose a new, non-existing CAMOUFOX_INSTALL_DIR and run npm run browser:install from the package directory. PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 explicitly defers engine provisioning and is not proof that the runtime is ready.

    Compatibility and verification

    The REST API remains compatible with Camofox MCP and Camo Gemini. Actual browser acceptance exercised custom Unicode search, evaluation, API-key protection on evaluation, cross-user isolation and correct tab cleanup using the released MCP/Gemini packages and disposable local fixtures. No Google account or customer session was used.

    Low-memory extraction was exercised with 1.5 GiB deflate/stored ZIP payloads under a 256 MiB Linux container limit, with matching payload hashes. See the platform CI and the release workflow for the platform test and portable-artifact records.

    Network capture/HAR/interception and optional screen-context integrations remain separate open feature requests; they are not included in this release.


    What's Changed

    New Contributors

    Full Changelog: https://github.com/redf0x1/camofox-browser/compare/v2.4.8...v2.4.9

  3. v2.4.8camofox-browser v2.4.82026-09-22 · 2026-09-22 05:59 UTC
    查看更新说明

    Patch release for navigation reliability and compatible dependency security updates.

    Changes

    • Bound post-action draining on pages with continuous timers or animations. Pending navigation safety checks and stalled pending-count reads now return an error at the deadline instead of reporting success or holding the tab lock indefinitely.
    • Update affected production dependencies while retaining Express 4 behavior for missing request bodies and array-style image extension filters.
    • Correct the CLI documentation for supported search engines and remove the retired drag command.

    Verification

    • Linux and Windows CI on Node 20 and 22.
    • Regression coverage for delayed navigation guards, tab-lock reuse, request-body validation, authentication, and image filter parsing.
    • Clean package installation and CLI checks; zero production dependency audit findings.
    • Windows x64 portable ZIP extracted and exercised from a path containing spaces.

    Install

    npm install -g [email protected]
    

    Container: ghcr.io/redf0x1/camofox-browser:2.4.8

    The Windows x64 portable ZIP is attached below. No configuration or data migration is required.

    Changes: https://github.com/redf0x1/camofox-browser/compare/v2.4.7...v2.4.8

  4. v2.4.7camofox-browser v2.4.72026-08-13 · 2026-08-13 08:37 UTC
    查看更新说明

    Install

    npm install -g [email protected]
    

    The npm latest dist-tag now resolves to 2.4.7. Registry tarball SHA-1: 2ed53751cf4f3905f4761e5c1f35e4b6ef551447; integrity: sha512-tb4DOGf/DvwmZ+6DBZIianZLPD2XQktUcmk1qmQ+GbwGBTBzK8VaSeGW4yXB21BZ6T7gYf8vcM43GTRSncDxWw==.

    For Windows without a global Node.js installation, download the portable x64 ZIP attached to this release.

    What's Changed

    New Contributors

    Full Changelog: https://github.com/redf0x1/camofox-browser/compare/v2.4.6...v2.4.7

  5. v2.4.6camofox-browser v2.4.62026-06-17 · 2026-06-17 00:50 UTC
    查看更新说明

    Fixed

    • Fixed fresh npm installs resolving incompatible Playwright builds that could crash Camoufox on first tab launch with a Browser.setDefaultViewport / isMobile protocol error.
    • playwright-core is now pinned to 1.58.1, matching the Camoufox binary/protocol bundle used by [email protected].

    Upgrade

    • Upgrade to [email protected].
    • If your project uses npm overrides, pnpm overrides, Yarn resolutions, or a manually installed playwright-core, make sure it does not force Playwright above 1.58.1 on this release line.

    Verification

    • npm [email protected] is published with the latest tag.
    • A clean npm install resolves [email protected].
    • npm run verify:package passed.
    • Full npm test passed: 64 suites and 495 tests.

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    CamoFox Browser Server

    Anti-detection browser server for AI agents — TypeScript REST API wrapping the Camoufox stealth browser engine

    License: MIT TypeScript Node npm

    Table of Contents

    Why CamoFox?

    The Problem: Standard browser automation (Puppeteer, Playwright, Selenium) is easily detected by modern anti-bot systems. JavaScript-level patches are fragile and get bypassed quickly.

    The Solution: CamoFox Browser Server wraps Camoufox, a Firefox fork with C++ engine-level fingerprint spoofing. No JavaScript injection — anti-detection happens at the browser engine level.

    FeaturePuppeteer/PlaywrightCamoFox Browser Server
    Anti-detectionJavaScript patches (fragile)C++ engine-level (robust)
    Fingerprint spoofingLimitedFull (engine-level)
    Token efficiencyRaw HTML / screenshotsAccessibility snapshots (smaller + structured)
    IntegrationDirect SDKREST API for any language / AI agent
    AI agent supportVariesMCP + OpenClaw compatible

    Features

    • C++ Anti-Detection — fingerprint spoofing at the Camoufox engine level (not JS injection)
    • REST API — language-agnostic HTTP endpoints for browser automation and AI agent integration
    • Multi-Session — concurrent isolated browser contexts per userId (defaults: max 50 sessions, max 10 tabs/session)
    • Persistent Browser Profiles — Each user gets a dedicated Firefox profile. Cookies, localStorage, IndexedDB, and all browser storage persist across sessions automatically.
    • Geo Presets — 8 built-in region presets (locale/timezone/geolocation) + custom presets file
    • Session-Level Proxy/Geo Overrides — per-session proxy configuration via named profiles or raw credentials, with hybrid geo modes (explicit-wins or proxy-locked)
    • 14 Search Macros — Google, YouTube, Amazon, Reddit (search + subreddit JSON), Wikipedia, Twitter, Yelp, Spotify, Netflix, LinkedIn, Instagram, TikTok, Twitch
    • Element Refs — accessibility snapshots annotated with stable eN element references for precise interaction
    • Cookie Persistence — import Netscape/Playwright-style cookies into a session (bearer auth required only when CAMOFOX_API_KEY is set)
    • OpenClaw Plugin — OpenClaw-compatible endpoints (/start, /tabs/open, /act, etc.)
    • TypeScript — strict mode, typed request shapes, modular Express routes
    • YouTube Transcript Extraction — yt-dlp + browser fallback (service-level; no public API route currently exposed)
    • Snapshot Pagination — offset-based windowing for large page snapshots
    • Image Listing Route — image-only extraction over the shared resource extractor with selector, extension, lazy-load, and blob-resolution controls
    • Structured Extract — deterministic schema-driven JSON extraction across core API, CLI, and OpenClaw without arbitrary JavaScript
    • Browser Health Monitoring — health probe with recovery/degraded state tracking
    • 🖥️ CLI Mode — 50+ commands for terminal-based browser automation
    • 🔐 Auth Vault — AES-256-GCM encrypted credential storage (LLM-safe)
    • 📜 Pipeline Scripting — Execute command scripts from files
    • 🔍 Console Capture — capture and filter browser console messages and uncaught errors
    • 📼 Playwright Tracing — record and export Playwright traces for debugging
    • 🗂️ Trace Artifact Management — list, download, and delete managed trace ZIPs per user session

    Preview Status

    CamoFox Browser Server is in Preview (Phase 1). Preview releases are functional for browser automation and agent integration, but carry specific compatibility commitments and explicit non-goals.

    What Preview Means

    • The REST API and CLI are usable for agent workflows today; CamoFox MCP is available as an external companion integration
    • New features may be added between minor versions
    • Backward-compatible aliases are maintained for renamed or moved endpoints (see Compatibility Policy)
    • Local state (profiles, registries, sessions) uses versioned formats with fail-closed integrity checks

    What Preview Does NOT Guarantee

    • Frozen API surface — endpoint behavior, request shapes, or response formats may change between minor versions
    • Automatic local-state migration — browser profiles, download registries, and session files use versioned sidecar formats; incompatible upgrades require manual reset (see Local State Recovery)
    • Downgrade safety — rolling back to an older version may require clearing local state
    • Fixed GA timeline — promotion to GA requires meeting evidence-based exit criteria, not a calendar date

    Compatibility Policy

    During Preview, CamoFox follows an additive-only deprecation model:

    • Legacy aliases (e.g., listItemId accepted alongside sessionKey, OpenClaw /act routing to core endpoints) continue to work alongside their replacements
    • Deprecated fields are accepted silently; no removal until GA or a documented migration window with advance notice in CHANGELOG
    • No existing endpoint is removed in a minor version — removals happen only in major versions with prior CHANGELOG notice

    Local State Recovery

    Browser profiles, download registries, and CLI session files use versioned sidecar formats. When upgrading CamoFox:

    • Compatible versions: State loads normally
    • Incompatible or corrupt state: The server refuses to load incompatible profiles and download registries; the CLI rejects incompatible saved-session files. Both log an actionable error with the specific recovery path.
    • Recovery: Delete the affected profile directory, session file, or download registry as indicated in the error message. Clean state is recreated on next use.

    Supported sidecars include limited forward-migration paths (e.g., fingerprint v0 → v1); when no migration path exists for a given version, the server refuses to load the file and logs an actionable recovery message. There is no silent repair or downgrade path — this fail-closed default prevents data corruption at the cost of manual intervention on unsupported version jumps.

    Quick Start

    From Source

    Requires Node.js 22+. Browser installation runs during npm install and fails if the required engine cannot be downloaded, extracted, or validated. Downloads are streamed to disk; extraction uses Python 3 on Linux (install python3 first), system tar on macOS, and built-in PowerShell/.NET ZIP support on Windows. Keep sufficient disk space for both the ZIP and extracted engine. Docker installs the engine once using the same installer. Optional GeoLite download failures only produce a warning.

    Set PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 only when deliberately deferring browser provisioning (for example, a source-only CI build or an existing portable bundle). Before launching, run npm run browser:install from the package directory with that variable unset. A supported cache with a nonempty executable is reused without a network update check. CAMOUFOX_INSTALL_DIR selects the cache directory. Existing incomplete/unsupported caches are preserved and rejected: choose a new path with CAMOUFOX_INSTALL_DIR to install afresh, and retain the old cache for diagnosis. Missing engine/version errors require engine installation, not deleting profiles.

    git clone https://github.com/redf0x1/camofox-browser.git
    cd camofox-browser
    npm install
    npm run build
    npm start
    

    Using npm (CLI)

    npm install -g camofox-browser
    
    # Start the server
    camofox-browser
    
    # Or use the CLI for browser automation
    camofox open https://example.com
    camofox snapshot
    camofox click e5
    

    See CLI for the complete command reference.

    Windows x64 Portable

    Windows x64 is supported as a headless-first portable distribution. Release ZIPs are named camofox-browser-<version>-windows-x64.zip and contain the Node.js runtime, application runtime, and the pinned Camoufox Windows x64 engine, so a global Node.js installation is not required.

    Extract the ZIP to a writable directory and run the bundled launchers from PowerShell or Command Prompt:

    .\camofox.cmd --version
    .\camofox.cmd server start --background
    .\camofox.cmd server status
    .\camofox.cmd server stop
    

    Portable runtime state stays under data\home inside the extracted directory. This includes camofox-browser's .camofox profiles/logs and the bundled Camoufox cache, so the portable distribution does not use the normal Windows user profile for its application state.

    The portable ZIP intentionally excludes Camoufox's upstream bundled fonts/ directory because the exact upstream source explicitly does not permit redistribution of those copyrighted Windows/macOS fonts. On Windows, CamoFox uses fonts installed on the host system instead.

    The supported Windows x64 display contract is headless=true. headless=false and headless="virtual" are rejected with a clear error before any Linux-only display process is attempted. Xvfb/VNC virtual display mode remains Linux-only, and native headed Windows mode is not part of the verified support contract.

    The release workflow verifies the ZIP after extracting it into a path containing spaces, starts the CLI using bundled Node.js with global Node removed from PATH, checks /health, runs a local create → navigate → snapshot → close browser flow, and confirms server shutdown and portable-state placement.

    Using Docker

    Docker image: ghcr.io/redf0x1/camofox-browser

    docker build -t camofox-browser .
    docker run -d \
      --name camofox-browser \
      -p 9377:9377 \
      -p 6080:6080 \
      -e CAMOFOX_HOST=0.0.0.0 \
      -e CAMOFOX_AUTH_MODE=auto \
      -e CAMOFOX_API_KEY=change-me \
      -v ~/.camofox:/home/node/.camofox \
      camofox-browser
    

    To persist browser profiles (cookies, localStorage, IndexedDB, etc.) across container restarts, keep the volume mount shown above.

    Using Docker Compose

    services:
      camofox-browser:
        build: .
        ports:
          - "9377:9377"
        environment:
          CAMOFOX_HOST: "0.0.0.0"
          CAMOFOX_PORT: "9377"
          # auto requires CAMOFOX_API_KEY when CAMOFOX_HOST is non-loopback
          CAMOFOX_AUTH_MODE: "auto"
          CAMOFOX_API_KEY: "change-me"
          # CAMOFOX_ADMIN_KEY: "change-me"
          # Optional: proxy routing (also enables Camoufox geoip mode)
          # PROXY_HOST: ""
          # PROXY_PORT: ""
          # PROXY_USERNAME: ""
          # PROXY_PASSWORD: ""
    

    Verify

    curl http://localhost:9377/health
    # {"ok":true,"engine":"camoufox","browserConnected":true}
    

    CLI

    CamoFox Browser includes a powerful CLI for browser automation directly from the terminal. The CLI auto-starts the server when needed.

    Installation

    # Global install (recommended)
    npm install -g camofox-browser
    
    # Or use npx (no install needed)
    npx camofox-browser open https://example.com
    

    Quick Start

    camofox open https://example.com       # Open a page in anti-detection browser
    camofox snapshot                       # Get accessibility tree with element refs
    camofox click e5                       # Click element [e5]
    camofox type e3 "hello world"         # Type into element [e3]
    camofox screenshot --output page.png   # Save screenshot
    camofox close                          # Close the tab
    

    Core Commands

    # Browser lifecycle
    camofox open <url>                     # Open URL in new tab
    camofox close [tabId]                  # Close tab
    camofox navigate <url>                 # Navigate current tab to URL
    
    # Inspection
    camofox snapshot                       # Get accessibility tree with [eN] refs
    camofox screenshot [--output file]     # Take screenshot (saves to file)
    camofox annotate                       # Screenshot + element ref overlay
    camofox get-url                        # Get current page URL
    camofox get-text                       # Get page text content
    camofox get-links                      # Get all links on page
    camofox get-tabs                       # List open tabs
    camofox extract-structured @schema.json # Extract deterministic JSON from a schema
    
    # Interaction
    camofox click <ref>                    # Click element by ref
    camofox type <ref> <text>              # Type text into element
    camofox fill '[e1]="user" [e2]="pw"'  # Fill multiple fields at once
    camofox scroll <direction>             # Scroll up/down/left/right
    camofox select <ref> <value>           # Select dropdown option
    camofox hover <ref>                    # Hover over element
    camofox press <key>                    # Press keyboard key
    
    # Navigation
    camofox go-back                        # Browser back
    camofox go-forward                     # Browser forward
    camofox search "query" --engine google # Search (8 engines supported)
    camofox eval "document.title"          # Execute JavaScript
    camofox wait <selector> [--timeout ms] # Wait for element
    

    Text input: CamoFox has no character limit for typed or filled text. Short text stays humanized for anti-detection, while long text automatically switches to bulk DOM insertion so large inputs do not truncate.

    Session Management

    camofox session save <name>            # Save current browser state
    camofox session load <name>            # Restore browser state
    camofox session list                   # List saved sessions
    camofox session delete <name>          # Delete saved session
    

    Cookie Management

    camofox cookie export <file>           # Export cookies to JSON file
    camofox cookie import <file>           # Import cookies from JSON file
    

    Auth Vault

    Securely store credentials locally with AES-256-GCM encryption. Credentials are never output to stdout — safe for LLM agent automation.

    camofox auth save <profile> [--url URL]  # Save credentials (prompts for master password)
    camofox auth load <profile>              # Show profile info (username only)
    camofox auth list                        # List saved profiles (no secrets shown)
    camofox auth delete <profile>            # Delete a profile
    camofox auth change-password <profile>   # Change master password
    
    # Inject credentials into a browser tab (LLM-safe)
    camofox snapshot                         # Get element refs first
    camofox auth load gmail --inject --username-ref e5 --password-ref e12
    

    Security: Master passwords use Argon2id KDF (with PBKDF2 fallback). Vault files are stored with 0600 permissions. The --inject flag sends credentials directly to the browser — the LLM agent never sees the password.

    Pipeline Scripting

    Execute multiple commands from a file for automation workflows:

    # Create a script
    cat > login-flow.txt << 'EOF'
    # Login automation script
    open https://example.com/login
    snapshot
    type e3 "username"
    type e5 "password"
    click e7
    wait .dashboard --timeout 5000
    screenshot --output result.png
    close
    EOF
    
    # Run it
    camofox run login-flow.txt
    
    # Continue on errors
    camofox run login-flow.txt --continue-on-error
    
    # Read from stdin
    echo "get-url" | camofox run -
    

    Server Management

    camofox server start                   # Start server daemon
    camofox server start --background      # Start in background
    camofox server stop                    # Stop server daemon
    camofox server status                  # Check server status
    

    Diagnostics

    camofox health                         # System health report
    camofox version                        # CLI + server version
    camofox info                           # Configuration info
    

    Console Capture

    camofox console [tabId]                  # View console messages
    camofox console [tabId] --type error     # Filter by type (log/warning/error/info/debug)
    camofox console [tabId] --clear          # View then clear messages
    camofox errors [tabId]                   # View uncaught JavaScript errors
    camofox errors [tabId] --clear           # View then clear errors
    

    Playwright Tracing

    camofox trace start [tabId]              # Start recording trace
    camofox trace stop [tabId] [-o file.zip] # Stop and save trace ZIP
    camofox trace chunk-start [tabId]        # Start new trace chunk
    camofox trace chunk-stop [tabId] [-o f]  # Stop chunk and save ZIP
    camofox trace status [tabId]             # Check active trace status
    

    View traces at trace.playwright.dev

    Global Options

    FlagEnv VarDescriptionDefault
    --user <id>CAMOFOX_USERUser/profile IDcli-default
    --port <port>PORTServer port9377
    --format <fmt>—Output: json, text, plaintext
    -V, --version—Show version—
    -h, --help—Show help—

    Output Formats

    camofox get-url --format json          # {"url":"https://example.com"}
    camofox get-url --format text          # URL: https://example.com
    camofox get-url --format plain         # https://example.com
    

    Tip: Use --format json for programmatic parsing and LLM agent integration.

    Security

    Anti-Detection

    CamoFox uses Camoufox, a Firefox fork with C++ level fingerprint spoofing. Unlike Chromium-based tools, CamoFox passes bot detection on Google, Cloudflare, and other anti-bot services.

    Auth Vault

    • AES-256-GCM encryption with Argon2id key derivation (PBKDF2 fallback)
    • Credentials never appear in stdout (safe for LLM agent pipelines)
    • Vault files stored with 0600 permissions
    • Master password required for all vault operations

    LLM Agent Safety

    • The --inject flag sends credentials directly to the browser — the LLM agent orchestrating the CLI never sees raw passwords
    • Output formats are designed for safe parsing without credential exposure
    • Pipeline scripts can reference auth profiles without embedding secrets

    Usage with AI Agents

    CamoFox works seamlessly with AI coding agents and LLM-powered automation:

    AI Coding Assistants (Recommended)

    Add CamoFox skills to your AI coding assistant for full browser automation context:

    npx skills add redf0x1/camofox-browser
    

    This works with Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, Goose, OpenCode, Windsurf, and 40+ other agents.

    Available skills:

    SkillFocusBest For
    camofox-browserFull coverage (CLI + API + OpenClaw)Complete reference
    camofox-cliCLI-only (50+ commands)Terminal-first workflows
    dogfoodQA testing workflowSystematic web app testing
    gemini-imageGemini image generationAI image automation
    redditReddit automationReddit posting/commenting

    The installer will prompt you to choose which skills and which agents to configure.

    Claude Code
    npx skills add redf0x1/camofox-browser
    # Installs to .claude/skills/camofox-browser/SKILL.md
    
    Cursor / GitHub Copilot / Codex
    npx skills add redf0x1/camofox-browser
    # Installs to .agents/skills/ directory
    

    Tip: Skills are symlinked from the repo, so they stay up to date. Do not manually copy SKILL.md files.

    MCP Integration (Recommended)

    Use CamoFox MCP for direct integration with Claude, Cursor, Windsurf, and other MCP-compatible agents. See Used With.

    CLI Integration

    AI agents can use the CLI with --format json for structured output:

    camofox open https://example.com       # Open page
    camofox snapshot --format json         # Get structured element tree
    camofox click e5                       # Interact with elements
    camofox auth load gmail --inject --username-ref e5 --password-ref e12  # Safe credential injection
    

    Pipeline Automation

    Create reusable automation scripts that AI agents can execute:

    camofox run automation-flow.txt        # Execute multi-step workflow
    

    Architecture

    AI Agent (MCP / OpenClaw / REST Client)
        │
        ▼ HTTP REST API (port 9377)
    ┌──────────────────────────────────────────┐
    │          CamoFox Browser Server          │
    │          (Express + TypeScript)          │
    ├──────────────────────────────────────────┤
    │ Routes                 Services          │
    │  ├── Core API           ├── Browser      │
    │  └── OpenClaw compat    ├── Session      │
    │                         └── Tab ops      │
    ├──────────────────────────────────────────┤
    │        Camoufox Engine (anti-detect)     │
    │   Firefox fork + engine-level spoofing   │
    └──────────────────────────────────────────┘
    

    Persistent Profiles (v1.3.0)

    • Each userId runs in its own persistent Firefox process/context (backed by launchPersistentContext(userDataDir))
    • Profile data is stored under ~/.camofox/profiles/ (override via CAMOFOX_PROFILES_DIR). Linux/macOS keep the readable default-user directory name; new Windows profiles use a deterministic hashed directory name so case-insensitive or trailing-dot/space-equivalent user IDs cannot share a Firefox profile. Existing Windows directories from the previous layout are read in place only when their exact on-disk name is unambiguous and no hashed directory also exists; conflicting layouts fail closed with both recovery paths in the error.
    • Idle user contexts are closed via LRU eviction (profile data remains on disk)

    API Reference

    Base URL: http://localhost:9377

    Security defaults: CAMOFOX_HOST now defaults to 127.0.0.1, and CAMOFOX_AUTH_MODE=auto keeps local loopback usage open while requiring CAMOFOX_API_KEY when you bind beyond loopback (for example 0.0.0.0 in Docker or PaaS). Set CAMOFOX_AUTH_MODE=required to require API-key auth everywhere. Set CAMOFOX_AUTH_MODE=disabled only for trusted private agent networks whose clients cannot send bearer tokens; this disables API-key auth for protected endpoints and keeps private-network navigation blocked. On non-loopback binds, navigation targets on loopback/private/link-local/metadata hosts are blocked by default unless you explicitly set CAMOFOX_ALLOW_PRIVATE_NETWORK=true. If you also configure PROXY_HOST/PROXY_PORT, exposed deployments must opt into CAMOFOX_ALLOW_PRIVATE_NETWORK=true until proxy-side private-target validation exists.

    API Documentation

    The Camofox Browser API includes OpenAPI 3.1.0 docs for a representative subset of the shipped route surface:

    The OpenAPI spec covers a representative subset of core and OpenClaw endpoints, including request schemas, response shapes, authentication requirements, and validation rules.

    Core Endpoints

    Note: For any endpoint that targets an existing tab (/tabs/:tabId/...), the server resolves tabId within a userId scope. If you omit userId from the request body, the server returns 400 { "error": "userId is required" }. If userId is present but the tab belongs to a different user, the server returns 404 Tab not found — except DELETE /tabs/:tabId, which is idempotent and returns 200 { "ok": true } when no matching tab is found under the given userId scope (the tab is already gone from the caller's perspective). For endpoints that accept userId as a query parameter (e.g. GET /tabs/:tabId/snapshot), omitting it may also result in a 400 or 404 depending on the route.

    MethodEndpointDescriptionRequiredAuth
    POST/sessions/:userId/cookiesImport cookies into a user session (Playwright cookie objects)Path: userId; Body: { "cookies": Cookie[] }Conditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/healthHealth check (also pre-launches the browser)NoneNone
    GET/presetsList available geo presets (built-in + custom)NoneNone
    POST/tabsCreate a new tab (supports preset + per-field overrides)Body: userId + (sessionKey or listItemId)Conditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/tabs?userId=...List all tabs for a user (OpenClaw-compatible response shape)Query: userIdNone
    POST/tabs/:tabId/navigateNavigate to a URL, or expand a search macro + queryBody: userId + (url or macro)Conditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/tabs/:tabId/snapshot?userId=...Accessibility snapshot annotated with eN element refsQuery: userIdNone
    POST/tabs/:tabId/waitWait for page readiness (DOM + optional network idle)Body: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/clickClick by ref (e.g. e12) or CSS selectorBody: userId + (ref or selector)Conditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/typeType into an element by ref or CSS selectorBody: userId + (ref or selector) + textConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/pressPress a key (e.g. Enter, Escape)Body: userId + keyConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/scrollScroll up/down/left/right by pixelsBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/scroll-elementScroll specific element into viewBody: userId, ref/selectorConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/backGo backBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/forwardGo forwardBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/refreshRefreshBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/tabs/:tabId/links?userId=...&limit=50&offset=0Extract links (paginated)Query: userIdNone
    GET/tabs/:tabId/images?userId=...List extracted imagesQuery: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/tabs/:tabId/screenshot?userId=...&fullPage=trueScreenshot (PNG bytes)Query: userIdNone
    GET/tabs/:tabId/stats?userId=...Tab stats + visited URLsQuery: userIdNone
    DELETE/tabs/:tabIdClose a tab (expects JSON body: { "userId": "..." })Body: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    DELETE/tabs/group/:listItemIdClose a tab group (expects JSON body: { "userId": "..." })Body: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    DELETE/sessions/:userIdClose all sessions for a userPath: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/sessions/:userId/toggle-displayToggle display mode (headless/headed/virtual)Path: userId; Body: { "headless": true|false|"virtual" }Conditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/tabs/:tabId/cookiesExport tab cookiesQuery: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/tabs/:tabId/downloadsList tab downloadsQuery: userIdNone
    GET/users/:userId/downloadsList user downloadsPath: userIdNone
    GET/downloads/:downloadIdDownload metadataQuery: userIdNone
    GET/downloads/:downloadId/contentStream download contentQuery: userIdNone
    DELETE/downloads/:downloadIdDelete tracked downloadBody or Query: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/extract-resourcesExtract downloadable resourcesBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/batch-downloadBatch download resourcesBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/resolve-blobsResolve blob URLs to base64Body: userId + urls[]None
    POST/tabs/:tabId/trace/startStart trace recordingBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/trace/stopStop and save trace ZIPBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/trace/chunk/startStart trace chunkBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/trace/chunk/stopStop chunk and save ZIPBody: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/tabs/:tabId/trace/statusCheck trace statusQuery: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/sessions/:userId/tracesList managed trace ZIPs for a userPath: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/sessions/:userId/traces/:filenameDownload a managed trace ZIPPath: userId, filenameConditional: Authorization: Bearer $CAMOFOX_API_KEY
    DELETE/sessions/:userId/traces/:filenameDelete a managed trace ZIPPath: userId, filenameConditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/tabs/:tabId/consoleGet console messagesQuery: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/tabs/:tabId/errorsGet uncaught JS errorsQuery: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/console/clearClear console + errorsBody or Query: userIdConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/tabs/:tabId/extract-structuredExtract deterministic JSON from a structured schemaBody: userId + schemaConditional: Authorization: Bearer $CAMOFOX_API_KEY

    Toggle Display Mode

    POST /sessions/:userId/toggle-display
    {"headless": "virtual"}
    

    Auth: Conditional — requires Authorization: Bearer $CAMOFOX_API_KEY when CAMOFOX_AUTH_MODE=required or when auto mode has an API key configured. No auth is required in CAMOFOX_AUTH_MODE=disabled. Switch browser between headless and headed mode. When encountering CAPTCHAs or issues requiring visual interaction, switch to headed mode to show the browser window.

    Platform note: The Windows x64 contract is headless-only. Requests with headless: false or headless: "virtual" return HTTP 400 on Windows. The Xvfb/VNC behavior described below is Linux-only.

    Returns:

    {"ok": true, "headless": "virtual", "vncUrl": "http://localhost:6080/vnc.html?autoconnect=true&resize=scale&token=...", "message": "Browser visible via VNC", "userId": "agent1"}
    

    Note: This restarts the browser context. All tabs are invalidated but cookies/auth state persist via the persistent profile.

    Browser Viewer (noVNC)

    On Linux, when the display mode is set to "virtual" or a headed request requires a virtual display, the server can start a VNC viewer accessible via web browser.

    # 1. Switch to virtual mode
    POST /sessions/:userId/toggle-display
    {"headless": "virtual"}
    # Response includes vncUrl — open in browser to see Firefox
    
    # 2. Solve CAPTCHA or interact with the browser
    
    # 3. Switch back to headless
    POST /sessions/:userId/toggle-display
    {"headless": true}
    # VNC automatically stops
    

    The VNC session auto-terminates after 2 minutes (configurable via CAMOFOX_VNC_TIMEOUT_MS).

    Evaluate JavaScript

    Execute a JavaScript expression in the page context and return the JSON-serializable result.

    Auth: required when CAMOFOX_AUTH_MODE=required or when auto mode has an API key configured; no auth is required in CAMOFOX_AUTH_MODE=disabled.

    Note: async expressions must be wrapped in an async IIFE (for example, (async () => { ... })()). Top-level await is not supported.

    POST /tabs/:tabId/evaluate
    {"userId": "agent1", "expression": "document.title"}
    

    Returns: {"ok": true, "result": "Page Title", "resultType": "string", "truncated": false}

    Evaluate JavaScript (Extended)

    Execute a long-running JavaScript expression (up to 300s timeout). Conditionally API-key protected. Rate limited.

    Auth: required when CAMOFOX_AUTH_MODE=required or when auto mode has an API key configured; no auth is required in CAMOFOX_AUTH_MODE=disabled.

    Note: async expressions must be wrapped in an async IIFE (for example, (async () => { ... })()). Top-level await is not supported.

    POST /tabs/:tabId/evaluate-extended
    {"userId": "agent1", "expression": "(async () => { const response = await fetch('/api/data'); return await response.json(); })()", "timeout": 60000}
    

    Returns: {"ok": true, "result": {...}, "resultType": "object", "truncated": false}

    OpenClaw Endpoints

    OpenClaw-compatible aliases (used by the OpenClaw plugin).

    MethodEndpointDescriptionRequiredAuth
    GET/Status (alias of /health)NoneNone
    POST/tabs/openOpen tab (OpenClaw request/response shape)Body: userId + urlConditional: Authorization: Bearer $CAMOFOX_API_KEY
    POST/startStart browser engineNoneNone
    POST/stopStop browser engineNonex-admin-key: $CAMOFOX_ADMIN_KEY
    POST/navigateNavigate (OpenClaw request shape: targetId in body)Body: userId + targetId + urlConditional: Authorization: Bearer $CAMOFOX_API_KEY
    GET/snapshot?userId=...&targetId=...Snapshot (OpenClaw response shape)Query: userId + targetIdNone
    POST/actCombined actions (click, type, press, scroll, scrollIntoView, hover, wait, close, extractStructured)Body: userId + targetId + kindConditional: Authorization: Bearer $CAMOFOX_API_KEY

    Network capture

    Set networkCapture: {} on POST /tabs or POST /tabs/open to record metadata before the tab's first navigation. The response includes a private networkKey. Use networkCapture: { "start": false } to reserve a key and start recording on demand. OpenClaw's POST /tabs/open uses the existing canonical profile.

    For a capture spanning multiple tabs, set networkCapture: { "scope": "session" } on the first tab. On subsequent tab creation in the same logical session, send networkCapture: { "scope": "session", "join": true } and the capture key in the X-Camofox-Network-Key header. Tabs without explicit enrollment are excluded, even when they share the same browser context.

    MethodEndpointPurpose
    GET/network/capabilitiesDiscover capture contract version and HAR support
    POST/network/capture/startStart a prepared capture
    POST/network/capture/stopFreeze the captured records
    GET/network/requestsList records, using after and limit for pagination
    GET/network/requests/:idInspect one request
    GET/network/harDownload the retained records as HAR 1.2 JSON

    Capture operations require ?userId=... and the X-Camofox-Network-Key header. Send the server API key as a bearer token when browser authentication is configured. Keep capture keys out of URLs and shared logs. The list response includes nextCursor and the number of evicted entries in dropped.

    Captures hold up to 256 requests each, with up to 32 captures server-wide. Lower the entry count or active lifetime using CAMOFOX_NETWORK_MAX_ENTRIES and CAMOFOX_NETWORK_TTL_MS. The default active lifetime is 15 minutes. A stopped capture expires after 5 minutes or when its last enrolled tab closes, whichever comes first. Export before closing the tabs.

    The recorder observes HTTP and HTTPS requests emitted by enrolled pages, including their frames. It stores sanitized URLs without credentials, query strings, or fragments, plus selected response metadata. Response sizes are best-effort. URL paths may contain application data, so review exports before sharing them. The recorder stores metadata by default.

    To enable opt-in response bodies, configure CAMOFOX_NETWORK_BODY_CAPTURE=true and CAMOFOX_API_KEY, then set networkCapture.captureBodies to true when creating a capture. Retrieve an available body with includeBody=true on the request detail endpoint. Eligible bodies are small UTF-8 JSON, HTML, plain text, or CSV responses with a verified unencoded length. Compressed, streamed, and oversized payloads are skipped. Limits are 16 KiB per body and 64 KiB per capture. Lists and HAR exports contain metadata only.

    To enable request interception, configure both CAMOFOX_API_KEY and CAMOFOX_NETWORK_INTERCEPTION=true. Use PUT /network/intercept?userId=... with a tab capture key and a JSON body containing rules. Each rule matches an exact HTTP(S) URL and method for a fetch or XHR request. An abort rule takes action, url, and method. A fulfill rule additionally takes a static body, status, and contentType of application/json or text/plain. There are at most four rules per tab and each mock is capped at 16 KiB. An empty array clears rules. Stopping a capture removes its interception handler. Playwright routing can disable HTTP caching while the handler is active.

    Structured Extract

    Structured extract returns deterministic JSON from a DOM schema without arbitrary JavaScript. Use it when you want stable data contracts instead of ad-hoc evaluate() calls.

    Core API:

    curl -X POST "$CAMOFOX_URL/tabs/$TAB_ID/extract-structured" \
      -H 'Content-Type: application/json' \
      -d '{
        "userId": "agent1",
        "schema": {
          "kind": "object",
          "fields": {
            "title": { "kind": "text", "selector": "h1", "required": true, "trim": true },
            "products": {
              "kind": "list",
              "selector": ".product",
              "item": {
                "kind": "object",
                "fields": {
                  "name": { "kind": "text", "selector": ".name", "required": true, "trim": true },
                  "href": { "kind": "url", "selector": "a.product-link", "attr": "href", "required": true }
                }
              }
            }
          }
        }
      }'
    

    CLI:

    camofox extract-structured @schema.json <tabId> --user <userId> --format json
    

    OpenClaw:

    curl -X POST "$CAMOFOX_URL/act" \
      -H 'Content-Type: application/json' \
      -d '{
        "kind": "extractStructured",
        "targetId": "tab-123",
        "userId": "agent1",
        "schema": {
          "kind": "object",
          "fields": {
            "title": { "kind": "text", "selector": "h1", "required": true }
          }
        }
      }'
    

    Notes:

    • invalid schemas fail with HTTP 400
    • required runtime misses fail the whole request with HTTP 422 and fieldPath
    • optional scalar/object/list nodes normalize to null / null / []
    • selectors must be CSS; no XPath, arbitrary JavaScript, or AI extraction
    • raw resource extraction and structured extraction stay separate on purpose

    Search Macros

    Use macros via POST /tabs/:tabId/navigate with { "macro": "@google_search", "query": "..." }.

    MacroEngine
    @google_searchGoogle
    @youtube_searchYouTube
    @amazon_searchAmazon
    @reddit_searchReddit (JSON)
    @reddit_subredditReddit subreddit (JSON)
    @wikipedia_searchWikipedia
    @twitter_searchTwitter/X
    @yelp_searchYelp
    @spotify_searchSpotify
    @netflix_searchNetflix
    @linkedin_searchLinkedIn
    @instagram_searchInstagram tags
    @tiktok_searchTikTok
    @twitch_searchTwitch

    Geo Presets

    Built-in presets (also exposed via GET /presets):

    PresetLocaleTimezoneLocation
    us-easten-USAmerica/New_YorkNew York (40.7128, -74.0060)
    us-westen-USAmerica/Los_AngelesLos Angeles (34.0522, -118.2437)
    japanja-JPAsia/TokyoTokyo (35.6895, 139.6917)
    uken-GBEurope/LondonLondon (51.5074, -0.1278)
    germanyde-DEEurope/BerlinBerlin (52.5200, 13.4050)
    vietnamvi-VNAsia/Ho_Chi_MinhHo Chi Minh City (10.8231, 106.6297)
    singaporeen-SGAsia/SingaporeSingapore (1.3521, 103.8198)
    australiaen-AUAustralia/SydneySydney (-33.8688, 151.2093)

    Create a tab with a preset:

    curl -X POST http://localhost:9377/tabs \
      -H 'Content-Type: application/json' \
      -d '{"userId":"agent1","sessionKey":"task1","preset":"japan","url":"https://example.com"}'
    

    Custom presets: set CAMOFOX_PRESETS_FILE=/path/to/presets.json (JSON object; keys become preset names).

    Session-Level Proxy and Geo Overrides

    CamoFox supports session-level proxy and geolocation configuration with a hybrid model that combines server defaults with per-session overrides.

    Proxy Configuration Model

    Server-level baseline (via environment variables):

    • PROXY_HOST, PROXY_PORT, PROXY_USERNAME, PROXY_PASSWORD — applied as the default for all sessions
    • Enables Camoufox geoip mode when configured

    Session-level overrides (via POST /tabs or CLI):

    • proxyProfile — select a named proxy profile from CAMOFOX_PROXY_PROFILES_FILE
    • proxy — provide raw proxy fields (host, port, username, password) directly
    • Session-level proxy overrides the server baseline for that specific userId + sessionKey combination

    Session identity rules:

    • The same userId may run different sessionKey profiles in parallel with different proxy/geo configurations
    • The same userId + sessionKey combination maintains a stable proxy/geo identity — requests with conflicting proxy/geo fields are rejected
    • Session reuse and cleanup scope proxy/geo identity by userId + sessionKey, not just userId

    Geo Mode Behavior

    CamoFox offers two geo modes that control how explicit geo fields (locale, timezone, geolocation) interact with proxy-derived geo:

    geoMode=explicit-wins (default):

    • Explicit geo fields (locale, timezone, geolocation) remain authoritative
    • Proxy-derived geo suggestions are ignored
    • Use this mode when you want precise geo control regardless of proxy location

    geoMode=proxy-locked:

    • Explicit geo fields that conflict with proxy-derived geo are rejected
    • Proxy-derived geo is authoritative
    • Use this mode to ensure geo consistency with proxy exit location

    CLI Examples

    Session-level proxy with named profile:

    camofox open https://example.com --proxy-profile tokyo-exit --user agent1
    

    Session-level proxy with raw fields:

    camofox open https://example.com \
      --proxy-host proxy.example.com \
      --proxy-port 8080 \
      --proxy-username user \
      --proxy-password pass \
      --user agent1
    

    Combine proxy with geo mode:

    camofox open https://example.com \
      --proxy-profile london-exit \
      --geo uk \
      --geo-mode proxy-locked \
      --user agent1
    

    API Examples

    Using a named proxy profile with explicit geo:

    curl -X POST http://localhost:9377/tabs \
      -H 'Content-Type: application/json' \
      -d '{
        "userId": "agent1",
        "sessionKey": "task1",
        "url": "https://example.com",
        "proxyProfile": "tokyo-exit",
        "preset": "japan",
        "geoMode": "explicit-wins"
      }'
    

    Using raw proxy fields with proxy-locked geo:

    curl -X POST http://localhost:9377/tabs \
      -H 'Content-Type: application/json' \
      -d '{
        "userId": "agent1",
        "sessionKey": "task2",
        "url": "https://example.com",
        "proxy": {
          "host": "proxy.example.com",
          "port": 8080,
          "username": "user",
          "password": "pass"
        },
        "geoMode": "proxy-locked"
      }'
    

    Named Proxy Profiles

    Define proxy profiles in a JSON file and point CAMOFOX_PROXY_PROFILES_FILE to it:

    {
      "tokyo-exit": {
        "server": "http://tokyo.proxy.example.com:8080",
        "username": "user",
        "password": "pass"
      },
      "london-exit": {
        "server": "http://london.proxy.example.com:8080"
      }
    }
    

    Then use profiles by name in API requests or CLI commands.

    Environment Variables

    VariableDefaultDescription
    CAMOFOX_PORT9377Server port
    PORT(optional)Alternative port env var (common in PaaS)
    NODE_ENVdevelopmentNode environment
    CAMOFOX_HOST127.0.0.1Server bind host. Set 0.0.0.0 for Docker/PaaS/network exposure. Non-loopback binds require CAMOFOX_API_KEY unless CAMOFOX_AUTH_MODE=disabled.
    CAMOFOX_ADMIN_KEY(empty)Required for POST /stop (sent via x-admin-key)
    CAMOFOX_AUTH_MODEautoAPI-key policy: auto allows loopback without auth and requires CAMOFOX_API_KEY for non-loopback binds; required requires CAMOFOX_API_KEY for every bind; disabled disables API-key auth for protected endpoints and is only for trusted private agent networks.
    CAMOFOX_API_KEY(empty)Guards protected endpoints (tab creation, navigation, interaction, session management, downloads, image extraction, tracing, console) via Authorization: Bearer header when set. Required in CAMOFOX_AUTH_MODE=required, and required by auto whenever CAMOFOX_HOST exposes the server beyond loopback. Must be unset when CAMOFOX_AUTH_MODE=disabled.
    CAMOFOX_ALLOW_PRIVATE_NETWORKtrue on loopback binds, false otherwiseAllows navigation to loopback/private/link-local/metadata targets. Leave unset for the safe default; enable only for trusted deployments that intentionally need internal-network reachability.
    CAMOFOX_HEADLESStrueDisplay mode: true (headless), false (headed), virtual (Xvfb). Windows x64 supports true only; Xvfb/VNC is Linux-only.
    CAMOFOX_VNC_RESOLUTION1920x1080x24Virtual Xvfb display resolution (WIDTHxHEIGHTxDEPTH)
    CAMOFOX_VNC_TIMEOUT_MS120000Max VNC session duration in ms before auto-stop
    CAMOFOX_EVAL_EXTENDED_RATE_LIMIT_MAX20Max evaluate-extended requests per user per window
    CAMOFOX_EVAL_EXTENDED_RATE_LIMIT_WINDOW_MS60000Rate limit window duration in ms
    CAMOFOX_COOKIES_DIR~/.camofox/cookiesDirectory used by the OpenClaw plugin cookie tool
    CAMOFOX_PROFILES_DIR~/.camofox/profilesProfile storage directory (persistent per-user Firefox profiles)
    CAMOFOX_DOWNLOADS_DIR~/.camofox/downloadsDownload artifact directory
    CAMOFOX_DOWNLOAD_TTL_MS86400000Download metadata retention TTL
    CAMOFOX_MAX_DOWNLOAD_SIZE_MB100Max single download size
    CAMOFOX_MAX_BATCH_CONCURRENCY5Batch download concurrency cap
    CAMOFOX_MAX_BLOB_SIZE_MB5Max blob payload size
    CAMOFOX_MAX_DOWNLOADS_PER_USER500Per-user download record cap
    CAMOFOX_CONSOLE_BUFFER_SIZE1000Per-tab console/error message buffer size (minimum 100)
    HANDLER_TIMEOUT_MS30000Handler timeout fallback
    MAX_CONCURRENT_PER_USER3Concurrent operations per user
    CAMOFOX_VNC_BASE_PORT6080noVNC/websockify base port
    CAMOFOX_VNC_HOSTlocalhostnoVNC host in returned URL
    CAMOFOX_CLI_USERcli-defaultDefault CLI user id
    CAMOFOX_SERVER_PID_FILE(unset)Optional daemon PID file path used by the CLI server manager
    CAMOFOX_IDLE_TIMEOUT_MS1800000Stage 1 idle cleanup threshold (ms)
    CAMOFOX_IDLE_EXIT_TIMEOUT_MS1800000Stage 2 daemon exit quiet window (ms, defaults to match Stage 1)
    CAMOFOX_PRESETS_FILE(unset)Optional JSON file defining/overriding geo presets
    CAMOFOX_PROXY_PROFILES_FILE(unset)Optional JSON file defining named proxy profiles for session-level overrides
    CAMOFOX_SESSION_TIMEOUT1800000Session idle timeout in ms (min 60000)
    CAMOFOX_MAX_SESSIONS50Maximum concurrent sessions
    CAMOFOX_MAX_TABS10Maximum tabs per session
    PROXY_HOST(empty)Proxy host (server-level default; enables proxy routing)
    PROXY_PORT(empty)Proxy port (server-level default)
    PROXY_USERNAME(empty)Proxy username (server-level default)
    PROXY_PASSWORD(empty)Proxy password (server-level default)
    CAMOFOX_MAX_SNAPSHOT_CHARS80000Max characters in snapshot before truncation
    CAMOFOX_MAX_SNAPSHOT_NODES2000Max accessibility snapshot nodes before truncation
    CAMOFOX_SNAPSHOT_TAIL_CHARS5000Characters preserved at end of truncated snapshot
    CAMOFOX_BUILDREFS_TIMEOUT_MS12000Timeout for building element refs
    CAMOFOX_TAB_LOCK_TIMEOUT_MS30000Timeout for acquiring tab lock
    CAMOFOX_TRACES_DIR~/.camofox/tracesManaged Playwright trace artifact directory
    CAMOFOX_TRACE_MAX_DURATION_MS300000Maximum trace recording duration before automatic stop
    CAMOFOX_HEALTH_PROBE_INTERVAL_MS60000Health probe check interval
    CAMOFOX_FAILURE_THRESHOLD3Consecutive failures before health degradation
    CAMOFOX_YT_DLP_TIMEOUT_MS30000Timeout for yt-dlp subtitle extraction
    CAMOFOX_YT_BROWSER_TIMEOUT_MS25000Timeout for browser transcript fallback
    CAMOFOX_OS(unset)Optional server-wide Camoufox OS override (windows, macos, linux, or comma-separated list for randomization)
    CAMOFOX_ALLOW_WEBGL(unset)Optional server-wide WebGL override; malformed values fail startup
    CAMOFOX_SCREEN_WIDTH(unset)Optional screen width override; applied only with CAMOFOX_SCREEN_HEIGHT
    CAMOFOX_SCREEN_HEIGHT(unset)Optional screen height override; applied only with CAMOFOX_SCREEN_WIDTH
    CAMOFOX_HUMANIZE(unset)Optional server-wide humanization override

    CAMOFOX_OS and CAMOFOX_SCREEN_* are generation-time controls: they affect only newly generated fingerprints and have no effect while an existing fingerprint.json sidecar is in use. Reset the profile or delete fingerprint.json to force regeneration under the new defaults. CAMOFOX_ALLOW_WEBGL and CAMOFOX_HUMANIZE are launch-time overrides and apply on every browser launch regardless of whether a sidecar is reused.

    Idle Lifecycle Policy

    CamoFox implements a two-stage idle lifecycle for graceful cleanup and daemon exit:

    Stage 1 — Idle Cleanup

    • After CAMOFOX_IDLE_TIMEOUT_MS of idle time (default: 30 minutes), the server runs cleanup to close idle sessions and tabs
    • Cleanup is delayed if browser contexts are launching or sessions are being created
    • New interactive activity (tab creation, navigation, interaction) cancels any pending cleanup

    Stage 2 — Daemon Exit

    • After Stage 1 cleanup completes, the server waits for CAMOFOX_IDLE_EXIT_TIMEOUT_MS (default: matches Stage 1 timeout)
    • If no new activity occurs during this quiet window, the daemon process exits gracefully
    • Any new request activity cancels the pending exit timer

    Activity detection:

    • Live tabs, launching browser contexts, or staged session creation count as active work and prevent cleanup
    • Empty sessions (sessions with no tabs) do not block cleanup but do disarm pending daemon exit
    • New interactive activity resets both cleanup and exit timers

    This two-stage model ensures cleanup runs before daemon exit, preventing resource leaks while allowing the server to shut down cleanly when fully idle.

    Deployment

    Docker (Recommended)

    docker build -t camofox-browser .
    docker run -p 9377:9377 -p 6080:6080 \
      -v ~/.camofox:/home/node/.camofox \
      -e CAMOFOX_HOST=0.0.0.0 \
      -e CAMOFOX_PORT=9377 \
      -e CAMOFOX_AUTH_MODE=auto \
      -e CAMOFOX_API_KEY=change-me \
      camofox-browser
    

    For private Docker networks used by agents such as Hermes, OpenClaw, or GoClaw that cannot send a bearer token, keep the service off published host ports and disable API-key auth explicitly:

    docker network create camofox-agents
    docker run -d \
      --name camofox-browser \
      --network camofox-agents \
      -e CAMOFOX_HOST=0.0.0.0 \
      -e CAMOFOX_AUTH_MODE=disabled \
      -v ~/.camofox:/home/node/.camofox \
      camofox-browser
    

    Then configure the agent with CAMOFOX_URL=http://camofox-browser:9377 from another container on the same Docker network. Do not combine CAMOFOX_AUTH_MODE=disabled with public port publishing or CAMOFOX_ALLOW_PRIVATE_NETWORK=true.

    Fly.io

    This repo includes a starter fly.toml for one-command deploys.

    fly launch
    fly deploy
    

    Railway

    • Create a new project → deploy from this GitHub repo
    • Set CAMOFOX_HOST=0.0.0.0
    • Set CAMOFOX_API_KEY to a strong secret
    • Set CAMOFOX_PORT=9377 (Railway will also provide PORT, which is supported)
    • Ensure the service exposes port 9377

    Render

    • Create a new Web Service → deploy from this GitHub repo
    • Use Docker (recommended) and expose port 9377
    • Set CAMOFOX_HOST=0.0.0.0
    • Set CAMOFOX_API_KEY to a strong secret
    • Set CAMOFOX_PORT=9377 (or rely on Render PORT)

    System Requirements

    • Node.js 22+
    • 2GB+ RAM (browser + contexts require significant memory)
    • Linux recommended for production; macOS is fine for development

    Used With

    ProjectDescription
    CamoFox MCPMCP (Model Context Protocol) server for Claude, Cursor, VS Code
    OpenClawOpen-source AI agent framework (compat endpoints included)
    CamoufoxAnti-detection Firefox browser engine

    Project Structure

    src/
    ├── cli/
    │   ├── commands/       # Command modules (core, navigation, interaction, etc.)
    │   │   ├── console.ts   # Console capture commands
    │   │   └── trace.ts     # Playwright tracing commands
    │   ├── vault/          # Auth vault (encryption, storage)
    │   ├── server/         # Server lifecycle management
    │   ├── transport/      # HTTP transport layer
    │   ├── output/         # Output formatting
    │   └── utils/          # Shared utilities
    ├── server.ts           # Express app entry point
    ├── types.ts            # Shared TypeScript interfaces
    ├── routes/
    │   ├── core.ts         # Core REST API (~42 endpoints)
    │   └── openclaw.ts     # OpenClaw compatibility (~7 endpoints)
    ├── services/
    │   ├── browser.ts      # Browser lifecycle + persistent context pool
    │   ├── batch-downloader.ts # Batch download orchestrator
    │   ├── context-pool.ts # Browser context pool with LRU eviction
    │   ├── download.ts     # Download tracking service
    │   ├── health.ts       # Browser health tracking
    │   ├── resource-extractor.ts # Page resource extraction
    │   ├── session.ts      # Session management + limits
    │   ├── tab.ts          # Tab operations (snapshot/click/type/etc.)
    │   ├── tracing.ts      # Playwright tracing service
    │   ├── vnc.ts          # VNC/virtual display lifecycle
    │   └── youtube.ts      # YouTube transcript extraction
    ├── middleware/
    │   ├── auth.ts         # API/admin auth helpers
    │   ├── errors.ts       # Error handling
    │   ├── logging.ts      # Structured logging
    │   └── rate-limit.ts   # In-memory rate limiter
    └── utils/
      ├── config.ts       # Environment config parsing
      ├── cookies.ts      # Cookie utilities
      ├── download-helpers.ts # Download helper functions
      ├── launcher.ts     # Browser launcher utilities
      ├── macros.ts       # Search macro expansion
      ├── presets.ts      # Geo preset definitions/loader
      └── snapshot.ts     # Snapshot truncation/windowing
    

    Contributing

    See CONTRIBUTING.md

    Credits

    This project is based on camofox-browser by Jo Inc (YC W24) and the Camoufox anti-detection browser engine by daijro.

    License

    MIT

    Crypto Scam Warning

    Sketchy people are doing sketchy things with crypto tokens named "Camofox" now that this project is getting attention. Camofox is not a crypto project and will never be one. Any token, coin, or NFT using the Camofox name has nothing to do with us.