{ "id": "camofox-browser", "name": "Camofox Browser", "description": "Anti-detection browser automation for AI agents using Camoufox (Firefox-based)", "version": "1.11.2", "envVars": { "CAMOFOX_API_KEY": { "description": "Secret key for the cookie-import endpoint. Cookie import is disabled when unset. Only set this if you need to import browser cookies and the server is local or access-controlled.", "required": false, "sensitive": true }, "CAMOFOX_ACCESS_KEY": { "description": "Global bearer token for all routes (except /health). When set, every request must include Authorization: Bearer . Recommended when exposing the server beyond localhost.", "required": false, "sensitive": true }, "CAMOFOX_CRASH_REPORT_ENABLED": { "description": "Enable or disable anonymized crash/hang telemetry. Set to 'false' to disable all outbound telemetry.", "required": false, "sensitive": false, "default": "true" }, "CAMOFOX_CRASH_REPORT_URL": { "description": "Telemetry endpoint URL. Override to point to a self-hosted endpoint instead of the default.", "required": false, "sensitive": false, "default": "https://camofox-telemetry.askjo.workers.dev/report" }, "CAMOUFOX_EXECUTABLE": { "description": "External Camoufox executable to use instead of downloading the bundled browser. Compatibility aliases: CAMOUFOX_EXECUTABLE_PATH, CAMOFOX_EXECUTABLE_PATH.", "required": false, "sensitive": false } }, "configSchema": { "type": "object", "properties": { "url": { "type": "string", "description": "Camoufox browser server URL" }, "port": { "type": "number", "description": "Server port (used if url not set)", "default": 9377 }, "autoStart": { "type": "boolean", "description": "Auto-start the camofox-browser server with the Gateway", "default": true }, "maxSessions": { "type": "number", "description": "Maximum concurrent browser sessions (server default: 50)", "default": 5 }, "maxTabsPerSession": { "type": "number", "description": "Maximum tabs per session (server default: 10)", "default": 3 }, "sessionTimeoutMs": { "type": "number", "description": "Session inactivity timeout in milliseconds (server default: 1800000)", "default": 600000 }, "browserIdleTimeoutMs": { "type": "number", "description": "Kill browser after this many ms with no sessions (0 = never)", "default": 300000 }, "maxOldSpaceSize": { "type": "number", "description": "Node.js V8 heap limit in MB", "default": 128 }, "apiKey": { "type": "string", "description": "Secret key for cookie import endpoint. Cookie import is disabled if unset. Set via CAMOFOX_API_KEY env var." }, "accessKey": { "type": "string", "description": "If set, all routes (except /health) require Authorization: Bearer . Set via CAMOFOX_ACCESS_KEY env var." }, "crashReportEnabled": { "type": "boolean", "description": "Enable anonymized crash/hang telemetry. Set false to disable all outbound telemetry.", "default": true }, "crashReportUrl": { "type": "string", "description": "Telemetry endpoint URL. Override to point to a self-hosted endpoint. Set via CAMOFOX_CRASH_REPORT_URL env var.", "default": "https://camofox-telemetry.askjo.workers.dev/report" } }, "additionalProperties": false }, "telemetry": { "crashReporter": { "description": "Anonymized crash/hang telemetry for identifying failure patterns. All credentials are environment secrets on the endpoint -- nothing sensitive ships in this package.", "enabled": true, "optOut": "CAMOFOX_CRASH_REPORT_ENABLED=false", "endpoint": "https://camofox-telemetry.askjo.workers.dev/report", "endpointSource": "https://github.com/jo-inc/camofox-browser/blob/main/workers/crash-reporter/index.ts", "endpointVerification": "https://camofox-telemetry.askjo.workers.dev/source", "selfHostable": true, "selfHostOverride": "CAMOFOX_CRASH_REPORT_URL", "dataCollected": [ "error type and anonymized stack trace", "node/platform version and uptime", "memory and resource counters (no content)", "HMAC-hashed private domains (not reversible)", "public domains verbatim (e.g. cloudflare.com, amazon.com)" ], "dataNeverCollected": [ "page content or DOM", "URLs with paths, query params, or credentials", "cookies, tokens, API keys, or secrets", "IP addresses or email addresses", "user-identifiable information" ] } }, "uiHints": { "url": { "label": "Server URL", "placeholder": "http://localhost:9377" }, "port": { "label": "Server Port", "placeholder": "9377" }, "autoStart": { "label": "Auto-start server with Gateway" }, "maxSessions": { "label": "Max Sessions", "placeholder": "5" }, "maxTabsPerSession": { "label": "Max Tabs per Session", "placeholder": "3" }, "sessionTimeoutMs": { "label": "Session Timeout (ms)", "placeholder": "600000" }, "browserIdleTimeoutMs": { "label": "Browser Idle Timeout (ms)", "placeholder": "300000" }, "maxOldSpaceSize": { "label": "Node Heap Limit (MB)", "placeholder": "128" }, "apiKey": { "label": "Cookie Import API Key (CAMOFOX_API_KEY)", "placeholder": "Leave empty to disable cookie import" }, "accessKey": { "label": "Global Access Key (CAMOFOX_ACCESS_KEY)", "placeholder": "Leave empty for localhost-only access" }, "crashReportEnabled": { "label": "Enable Telemetry" }, "crashReportUrl": { "label": "Telemetry Endpoint URL", "placeholder": "https://camofox-telemetry.askjo.workers.dev/report" } }, "tools": [ "camofox_create_tab", "camofox_snapshot", "camofox_click", "camofox_type", "camofox_navigate", "camofox_scroll", "camofox_screenshot", "camofox_close_tab", "camofox_evaluate", "camofox_list_tabs", "camofox_import_cookies" ], "contracts": { "tools": [ "camofox_create_tab", "camofox_snapshot", "camofox_click", "camofox_type", "camofox_navigate", "camofox_scroll", "camofox_screenshot", "camofox_close_tab", "camofox_evaluate", "camofox_list_tabs", "camofox_import_cookies" ] }, "runtimeDependencies": { "camoufox": { "description": "Camoufox anti-detection browser (Firefox fork). Downloaded at install time by camoufox-js unless CAMOUFOX_EXECUTABLE points to an external bundle.", "source": "https://github.com/nicedayzhu/camoufox/releases", "installer": "camoufox-js (npm)", "installedBy": "postinstall script: npx camoufox-js fetch, skipped when CAMOUFOX_EXECUTABLE is set", "sizeApprox": "300MB", "platforms": [ "linux-x86_64", "linux-aarch64", "macos-x86_64", "macos-aarch64" ], "verifiedBy": "camoufox-js verifies download integrity via GitHub release checksums" } }, "permissions": { "network": { "outbound": [ { "target": "User-specified URLs (browsed pages)", "purpose": "Browser automation -- navigating to URLs the agent requests", "gatedBy": "Agent request via API" }, { "target": "https://camofox-telemetry.askjo.workers.dev/report", "purpose": "Anonymized crash/hang telemetry", "gatedBy": "CAMOFOX_CRASH_REPORT_ENABLED (default: true, set false to disable)" } ], "inbound": { "target": "localhost:9377 (default)", "purpose": "REST API for browser automation", "gatedBy": "CAMOFOX_ACCESS_KEY (optional -- when set, all routes require Bearer auth)" } }, "filesystem": { "read": [ { "path": "~/.camofox/cookies/", "purpose": "Read Netscape cookie files for authenticated browsing", "gatedBy": "CAMOFOX_API_KEY (disabled entirely when unset)" }, { "path": "/proc/self/status (Linux only)", "purpose": "Memory and resource metrics for telemetry", "gatedBy": "Only read when telemetry is enabled" } ], "write": [ { "path": "~/.camofox/profiles//", "purpose": "Persisted session state (cookies + localStorage) so users stay logged in across restarts", "gatedBy": "persistence plugin (enabled by default, disable via camofox.config.json)" }, { "path": "~/.camofox/traces//", "purpose": "Optional Playwright session traces for debugging", "gatedBy": "trace: true flag on tab creation (opt-in per session, off by default)" } ] }, "subprocess": [ { "binary": "Camoufox (Firefox fork)", "purpose": "The browser engine -- core functionality", "isolation": "lib/launcher.js (child_process isolated from route handlers)" }, { "binary": "yt-dlp (optional)", "purpose": "YouTube transcript extraction (fast path)", "isolation": "plugins/youtube/youtube.js (child_process isolated from route handlers)" } ] }, "securityModel": { "architecture": "All process.env reads are in lib/config.js. All child_process usage is in lib/launcher.js and plugins/youtube/youtube.js. server.js has route handlers but zero process.env reads and zero child_process imports. No single file combines secrets access with network sends.", "cookieImport": "DISABLED by default. Requires CAMOFOX_API_KEY to be explicitly set. Without the key, the server rejects all cookie requests with 403. Cookie files are read from a sandboxed directory (~/.camofox/cookies/) with path traversal protection.", "accessControl": "CAMOFOX_ACCESS_KEY provides global bearer auth for all routes (except /health). Recommended for any non-localhost deployment.", "crashReporting": "Anonymized via lib/reporter.js (L28-290). Private domains are HMAC-hashed. No page content, cookies, tokens, IPs, or user data is ever sent. Relay source is in-repo and auditable. Verification endpoint: GET /source returns commit hash and sha256.", "binaryDownload": "Camoufox is downloaded at npm install time by camoufox-js unless CAMOUFOX_EXECUTABLE points to an external Camoufox bundle. Downloaded binaries come from official GitHub releases with integrity verification by camoufox-js.", "sessionPersistence": "User sessions are persisted to ~/.camofox/profiles/ so authenticated browsing survives restarts. UserIds are hashed for directory names. Disable via persistence plugin config.", "noEmbeddedSecrets": "Zero credentials, private keys, or tokens ship in this package. All secrets are environment variables or Cloudflare Worker secrets." } }