npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

camofox-browser

v1.3.0

Published

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

Downloads

685

Readme

CamoFox Browser Server

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

License: MIT TypeScript Node

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.

| Feature | Puppeteer/Playwright | CamoFox Browser Server | |---------|---------------------|------------------------| | Anti-detection | JavaScript patches (fragile) | C++ engine-level (robust) | | Fingerprint spoofing | Limited | Full (engine-level) | | Token efficiency | Raw HTML / screenshots | Accessibility snapshots (smaller + structured) | | Integration | Direct SDK | REST API for any language / AI agent | | AI agent support | Varies | MCP + 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
  • 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 (optional, gated by API key)
  • OpenClaw Plugin — OpenClaw-compatible endpoints (/start, /tabs/open, /act, etc.)
  • TypeScript — strict mode, typed request shapes, modular Express routes

Quick Start

From Source

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

Using npm (CLI)

This is a server, not a browser automation library. Most users should run it from source or Docker.

If you want a minimal CLI wrapper that starts the server (via the package bin):

npm install -g camofox-browser
camofox-browser

Or one-off:

npx camofox-browser

Using Docker

docker build -t camofox-browser .
docker run -p 9377:9377 camofox-browser

To persist browser profiles (cookies, localStorage, IndexedDB, etc.) across container restarts:

docker run -d \
  -p 9377:9377 \
  -v ~/.camofox:/home/node/.camofox \
  ghcr.io/redf0x1/camofox-browser:latest

The volume mount -v ~/.camofox:/home/node/.camofox ensures profiles persist across container restarts.

Using Docker Compose

services:
  camofox-browser:
    build: .
    ports:
      - "9377:9377"
    environment:
      CAMOFOX_PORT: "9377"
      # Optional auth gates
      # 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}

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 at ~/.camofox/profiles/{userId}/ (override via CAMOFOX_PROFILES_DIR)
  • Idle user contexts are closed via LRU eviction (profile data remains on disk)

API Reference

Base URL: http://localhost:9377

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, you will typically get 404 Tab not found.

| Method | Endpoint | Description | Required | Auth | |--------|----------|-------------|----------|------| | POST | /sessions/:userId/cookies | Import cookies into a user session (Playwright cookie objects) | Path: userId; Body: { "cookies": Cookie[] } | Authorization: Bearer $CAMOFOX_API_KEY | | GET | /health | Health check (also pre-launches the browser) | None | None | | GET | /presets | List available geo presets (built-in + custom) | None | None | | POST | /tabs | Create a new tab (supports preset + per-field overrides) | Body: userId + (sessionKey or listItemId) | None | | GET | /tabs?userId=... | List all tabs for a user (OpenClaw-compatible response shape) | Query: userId | None | | POST | /tabs/:tabId/navigate | Navigate to a URL, or expand a search macro + query | Body: userId + (url or macro) | None | | GET | /tabs/:tabId/snapshot?userId=... | Accessibility snapshot annotated with eN element refs | Query: userId | None | | POST | /tabs/:tabId/wait | Wait for page readiness (DOM + optional network idle) | Body: userId | None | | POST | /tabs/:tabId/click | Click by ref (e.g. e12) or CSS selector | Body: userId + (ref or selector) | None | | POST | /tabs/:tabId/type | Type into an element by ref or CSS selector | Body: userId + (ref or selector) + text | None | | POST | /tabs/:tabId/press | Press a key (e.g. Enter, Escape) | Body: userId + key | None | | POST | /tabs/:tabId/scroll | Scroll up/down by pixels | Body: userId | None | | POST | /tabs/:tabId/back | Go back | Body: userId | None | | POST | /tabs/:tabId/forward | Go forward | Body: userId | None | | POST | /tabs/:tabId/refresh | Refresh | Body: userId | None | | GET | /tabs/:tabId/links?userId=...&limit=50&offset=0 | Extract links (paginated) | Query: userId | None | | GET | /tabs/:tabId/screenshot?userId=...&fullPage=true | Screenshot (PNG bytes) | Query: userId | None | | GET | /tabs/:tabId/stats?userId=... | Tab stats + visited URLs | Query: userId | None | | DELETE | /tabs/:tabId | Close a tab (expects JSON body: { "userId": "..." }) | Body: userId | None | | DELETE | /tabs/group/:listItemId | Close a tab group (expects JSON body: { "userId": "..." }) | Body: userId | None | | DELETE | /sessions/:userId | Close all sessions for a user | Path: userId | None |

OpenClaw Endpoints

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

| Method | Endpoint | Description | Required | Auth | |--------|----------|-------------|----------|------| | GET | / | Status (alias of /health) | None | None | | POST | /tabs/open | Open tab (OpenClaw request/response shape) | Body: userId + url | None | | POST | /start | Start browser engine | None | None | | POST | /stop | Stop browser engine | None | x-admin-key: $CAMOFOX_ADMIN_KEY | | POST | /navigate | Navigate (OpenClaw request shape: targetId in body) | Body: userId + targetId + url | None | | GET | /snapshot?userId=...&targetId=... | Snapshot (OpenClaw response shape) | Query: userId + targetId | None | | POST | /act | Combined actions (click, type, press, scroll, scrollIntoView, hover, wait, close) | Body: userId + targetId + kind | None |

Search Macros

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

| Macro | Engine | |-------|--------| | @google_search | Google | | @youtube_search | YouTube | | @amazon_search | Amazon | | @reddit_search | Reddit (JSON) | | @reddit_subreddit | Reddit subreddit (JSON) | | @wikipedia_search | Wikipedia | | @twitter_search | Twitter/X | | @yelp_search | Yelp | | @spotify_search | Spotify | | @netflix_search | Netflix | | @linkedin_search | LinkedIn | | @instagram_search | Instagram tags | | @tiktok_search | TikTok | | @twitch_search | Twitch |

Geo Presets

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

| Preset | Locale | Timezone | Location | |--------|--------|----------|----------| | us-east | en-US | America/New_York | New York (40.7128, -74.0060) | | us-west | en-US | America/Los_Angeles | Los Angeles (34.0522, -118.2437) | | japan | ja-JP | Asia/Tokyo | Tokyo (35.6895, 139.6917) | | uk | en-GB | Europe/London | London (51.5074, -0.1278) | | germany | de-DE | Europe/Berlin | Berlin (52.5200, 13.4050) | | vietnam | vi-VN | Asia/Ho_Chi_Minh | Ho Chi Minh City (10.8231, 106.6297) | | singapore | en-SG | Asia/Singapore | Singapore (1.3521, 103.8198) | | australia | en-AU | Australia/Sydney | Sydney (-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).

Environment Variables

| Variable | Default | Description | |----------|---------|-------------| | CAMOFOX_PORT | 9377 | Server port | | PORT | (optional) | Alternative port env var (common in PaaS) | | NODE_ENV | development | Node environment | | CAMOFOX_ADMIN_KEY | (empty) | Required for POST /stop (sent via x-admin-key) | | CAMOFOX_API_KEY | (empty) | Enables cookie import endpoint; sent via Authorization: Bearer ... | | CAMOFOX_COOKIES_DIR | ~/.camofox/cookies | Directory used by the OpenClaw plugin cookie tool | | CAMOFOX_PROFILES_DIR | ~/.camofox/profiles | Profile storage directory (persistent per-user Firefox profiles) | | CAMOFOX_PRESETS_FILE | (unset) | Optional JSON file defining/overriding geo presets | | CAMOFOX_SESSION_TIMEOUT | 1800000 | Session idle timeout in ms (min 60000) | | CAMOFOX_MAX_SESSIONS | 50 | Maximum concurrent sessions | | CAMOFOX_MAX_TABS | 10 | Maximum tabs per session | | PROXY_HOST | (empty) | Proxy host (enables proxy routing) | | PROXY_PORT | (empty) | Proxy port | | PROXY_USERNAME | (empty) | Proxy username | | PROXY_PASSWORD | (empty) | Proxy password |

Deployment

Docker (Recommended)

docker build -t camofox-browser .
docker run -p 9377:9377 \
  -v ~/.camofox:/home/node/.camofox \
  -e CAMOFOX_PORT=9377 \
  camofox-browser

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_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_PORT=9377 (or rely on Render PORT)

System Requirements

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

Used With

| Project | Description | |---------|-------------| | CamoFox MCP | MCP (Model Context Protocol) server for Claude, Cursor, VS Code | | OpenClaw | Open-source AI agent framework (compat endpoints included) | | Camoufox | Anti-detection Firefox browser engine |

Project Structure

src/
├── server.ts           # Express app entry point
├── types.ts            # Shared TypeScript interfaces
├── routes/
│   ├── core.ts         # Core REST API (~21 endpoints)
│   └── openclaw.ts     # OpenClaw compatibility (~7 endpoints)
├── services/
│   ├── browser.ts      # Browser lifecycle + persistent context pool
│   ├── session.ts      # Session management + limits
│   └── tab.ts          # Tab operations (snapshot/click/type/etc.)
├── middleware/         # Auth, logging, errors
└── utils/              # Config, presets, macros

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.