
Camofox Cloaked Browser
- 4 installs
- 60 repo stars
- Updated June 24, 2026
- tmchow/agent-skills
Runs the Camofox/Camoufox anti-detection browser server for agent workflows that need cloaked browsing via REST and plugin tools.
About
An opt-in anti-detection browser server for cloaked agent browsing, covering npm/npx startup, REST commands, session and tab workflow, and environment variables. A developer uses it when an agent workflow needs cloaked browsing rather than normal automation.
- npx-launched Camofox server with REST and OpenClaw plugin tools
- Rules to always send userId and re-snapshot after state changes
Camofox Cloaked Browser by the numbers
- 4 all-time installs (skills.sh)
- Ranked #1,780 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/tmchow/agent-skills --skill camofox-cloaked-browserAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 60 |
| Last updated | June 24, 2026 |
| Repository | tmchow/agent-skills ↗ |
What it does
Runs the Camofox/Camoufox anti-detection browser server for agent workflows that need cloaked browsing via REST and plugin tools.
Files
Camofox Cloaked Browser
When to use
Use this skill only when the task needs Camofox/Camoufox specifically:
- user names Camofox, Camoufox, anti-detection browsing, cloaked browser, browser fingerprint spoofing, or stealth browsing
- a site is likely to block normal Playwright/Chrome automation
- the task needs stable accessibility refs from a Camofox browser server
- OpenClaw has the
camofox-browserplugin/tools available
Do not use it for ordinary web search, simple page fetches, static text extraction, or normal browser automation. Use the cheaper default stack unless cloaking is actually load-bearing.
If the user names another browser target explicitly — Browserbase, Selkies, a tailnet browser, normal Hermes browser, Chrome DevTools, etc. — stop and use that target/skill instead. Do not silently route through Camofox.
Default target
Default local server:
http://127.0.0.1:9377Equivalent localhost URL is usually fine:
http://localhost:9377Prefer 127.0.0.1 in examples to avoid IPv6/localhost oddities.
There is no container target in this skill. Do not mention or rely on container names; this skill is about the npm server and OpenClaw plugin/API.
Operating model
Camofox Browser is a Node server and OpenClaw plugin wrapper around Camoufox, a Firefox-based anti-detection browser.
Primary local startup:
npx -y @askjo/camofox-browser
# serves http://127.0.0.1:9377 by defaultAlternative cloned-repo startup:
git clone https://github.com/jo-inc/camofox-browser
cd camofox-browser
npm install
npm startAlternative global install:
npm install -g @askjo/camofox-browser
camofox-browsernpm install / npx downloads the Camoufox browser binary on first run via the package postinstall unless CAMOUFOX_EXECUTABLE points to an existing compatible Camoufox bundle. Expect roughly a few hundred MB for the browser payload.
OpenClaw plugin mode
If OpenClaw has the upstream plugin installed, prefer the plugin tools over raw curl because they auto-manage userId from ctx.agentId, use sessionKey, and can auto-start the server.
Install shape:
openclaw plugins install @askjo/camofox-browser
# or whatever ClawHub install command the registry page currently showsUseful OpenClaw CLI commands from the plugin:
openclaw camofox status
openclaw camofox start
openclaw camofox stop
openclaw camofox tabs
openclaw camofox configurePlugin config shape shown by upstream:
plugins:
entries:
camofox-browser:
enabled: true
config:
port: 9377
autoStart: true
maxSessions: 5
maxTabsPerSession: 3
sessionTimeoutMs: 600000
browserIdleTimeoutMs: 300000
maxOldSpaceSize: 128The upstream plugin exposes these core tools:
camofox_create_tab— create tab; returnstabIdcamofox_snapshot— accessibility snapshot with refs and screenshot; primary observation toolcamofox_click— click by ref or CSS selectorcamofox_type— type by ref or selector; optionalpressEntercamofox_navigate— navigate by URL or search macrocamofox_scroll— scroll pagecamofox_screenshot— screenshot onlycamofox_close_tab— close a tabcamofox_evaluate— execute JS; gated by server auth middlewarecamofox_list_tabs— list tabs for the current usercamofox_import_cookies— import Netscape cookies; useCAMOFOX_API_KEYfor this sensitive endpoint
Hard workflow rules
Always follow these rules when using Camofox:
1. Check /health before doing browser work. 2. Always send userId in raw REST calls. 3. Prefer sessionKey when creating tabs so task tabs group together. 4. Open or reuse a tab intentionally; do not spray new tabs. 5. Snapshot before selecting refs. 6. Re-snapshot after every state-changing action: click, type with submit, press, scroll, navigation, back, forward, refresh, JS evaluate that mutates state. 7. Element refs reset after navigation and may become stale after DOM changes. 8. Prefer refs from the latest snapshot over CSS selectors. Use selectors only when refs are unavailable or unstable. 9. Close tabs when done unless preserving the session is explicitly useful. 10. Do not claim Camofox is in use until both the server is healthy and the actual agent/client is pointed at it.
REST API quick commands
Set base variables:
BASE="${CAMOFOX_BASE_URL:-http://127.0.0.1:9377}"
USER_ID="${CAMOFOX_USER_ID:-agent1}"
SESSION_KEY="${CAMOFOX_SESSION_KEY:-task1}"If CAMOFOX_ACCESS_KEY or CAMOFOX_API_KEY is set, include auth where required:
AUTH_HEADER=()
if [ -n "${CAMOFOX_ACCESS_KEY:-}" ]; then
AUTH_HEADER=(-H "Authorization: Bearer ${CAMOFOX_ACCESS_KEY}")
elif [ -n "${CAMOFOX_API_KEY:-}" ]; then
AUTH_HEADER=(-H "Authorization: Bearer ${CAMOFOX_API_KEY}")
fiHealth
curl -fsS "$BASE/health"Create tab
TAB_ID="$(curl -fsS -X POST "$BASE/tabs" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"sessionKey\":\"$SESSION_KEY\",\"url\":\"https://example.com\"}" \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["tabId"])')"
printf 'TAB_ID=%s\n' "$TAB_ID"Navigate
curl -fsS -X POST "$BASE/tabs/$TAB_ID/navigate" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"url\":\"https://example.com\"}"Search macro example:
curl -fsS -X POST "$BASE/tabs/$TAB_ID/navigate" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"macro\":\"@google_search\",\"query\":\"site:example.com pricing\"}"Known macros include:
@google_search@youtube_search@amazon_search@reddit_search@wikipedia_search@twitter_search@yelp_search@spotify_search@netflix_search@linkedin_search@instagram_search@tiktok_search@twitch_search
Snapshot
curl -fsS "$BASE/tabs/$TAB_ID/snapshot?userId=$USER_ID"With screenshot and pagination offset:
curl -fsS "$BASE/tabs/$TAB_ID/snapshot?userId=$USER_ID&includeScreenshot=true&offset=0"Click
curl -fsS -X POST "$BASE/tabs/$TAB_ID/click" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"ref\":\"e1\"}"Selector fallback:
curl -fsS -X POST "$BASE/tabs/$TAB_ID/click" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"selector\":\"button[type=submit]\"}"Type
curl -fsS -X POST "$BASE/tabs/$TAB_ID/type" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"ref\":\"e2\",\"text\":\"hello world\"}"Type and submit:
curl -fsS -X POST "$BASE/tabs/$TAB_ID/type" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"ref\":\"e2\",\"text\":\"query\",\"pressEnter\":true}"Press key
curl -fsS -X POST "$BASE/tabs/$TAB_ID/press" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"key\":\"Enter\"}"Wait
curl -fsS -X POST "$BASE/tabs/$TAB_ID/wait" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"timeout\":3000}"Scroll
curl -fsS -X POST "$BASE/tabs/$TAB_ID/scroll" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"direction\":\"down\",\"amount\":700}"Back / forward / refresh
curl -fsS -X POST "$BASE/tabs/$TAB_ID/back" -H 'Content-Type: application/json' "${AUTH_HEADER[@]}" -d "{\"userId\":\"$USER_ID\"}"
curl -fsS -X POST "$BASE/tabs/$TAB_ID/forward" -H 'Content-Type: application/json' "${AUTH_HEADER[@]}" -d "{\"userId\":\"$USER_ID\"}"
curl -fsS -X POST "$BASE/tabs/$TAB_ID/refresh" -H 'Content-Type: application/json' "${AUTH_HEADER[@]}" -d "{\"userId\":\"$USER_ID\"}"Links / images / screenshot
curl -fsS "$BASE/tabs/$TAB_ID/links?userId=$USER_ID&limit=50"
curl -fsS "$BASE/tabs/$TAB_ID/images?userId=$USER_ID&limit=50"
curl -fsS "$BASE/tabs/$TAB_ID/screenshot?userId=$USER_ID" --output screenshot.pngEvaluate JavaScript
This endpoint is auth-gated by the server middleware. Use only when needed.
curl -fsS -X POST "$BASE/tabs/$TAB_ID/evaluate" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"expression\":\"document.title\"}"Structured extract
curl -fsS -X POST "$BASE/tabs/$TAB_ID/extract" \
-H 'Content-Type: application/json' \
"${AUTH_HEADER[@]}" \
-d "{\"userId\":\"$USER_ID\",\"schema\":{\"type\":\"object\",\"properties\":{\"title\":{\"type\":\"string\"}}}}"List and close tabs
curl -fsS "$BASE/tabs?userId=$USER_ID"
curl -fsS -X DELETE "$BASE/tabs/$TAB_ID?userId=$USER_ID" "${AUTH_HEADER[@]}"Delete session data
This endpoint is auth-gated.
curl -fsS -X DELETE "$BASE/sessions/$USER_ID" "${AUTH_HEADER[@]}"Environment variables
Server/client target
CAMOFOX_PORT: server port; default9377PORT: generic port fallback ifCAMOFOX_PORTis unsetCAMOFOX_BASE_URL: not an upstream server env var; useful shell convention for scripts in this skillCAMOFOX_URL: Hermes-specific browser-backend switch; do not set/export globally; see below
Auth and sensitive operations
CAMOFOX_ACCESS_KEY: global bearer token for all routes except/health; use when anything can reach the server beyond loopbackCAMOFOX_API_KEY: optional bearer token used only for sensitive endpoints such as cookie import/traces; not needed for normal browsing, snapshots, navigation, clicks, or typingCAMOFOX_ADMIN_KEY: protects/stopwhen configured
For local development with neither key set, upstream allows loopback requests in non-production mode. Do not expose that to a network. That would be the kind of convenience feature that becomes an incident report.
Storage / runtime tuning
CAMOFOX_COOKIES_DIR: cookie import source directory; default~/.camofox/cookiesCAMOFOX_PROFILE_DIR: profile directory; default~/.camofox/profilesCAMOFOX_TRACES_DIR: trace directory; default~/.camofox/tracesCAMOFOX_TRACES_MAX_BYTES: default 50MBCAMOFOX_TRACES_TTL_HOURS: default 24MAX_CONCURRENT_PER_USER: default 3MAX_SESSIONS: default 50MAX_TABS_PER_SESSION: default 10MAX_TABS_GLOBAL: default 50SESSION_TIMEOUT_MS: default 600000 in current codeTAB_INACTIVITY_MS: default 300000BROWSER_IDLE_TIMEOUT_MS: default 300000NAVIGATE_TIMEOUT_MS: default 25000BUILDREFS_TIMEOUT_MS: default 12000NATIVE_MEM_RESTART_THRESHOLD_MB: default 300BROWSER_RSS_RESTART_THRESHOLD_MB: default 1500
Browser binary
CAMOUFOX_EXECUTABLE: external Camoufox executable/bundle; skips bundled download when validCAMOUFOX_EXECUTABLE_PATH: compatibility aliasCAMOFOX_EXECUTABLE_PATH: legacy aliasCAMOFOX_SKIP_DOWNLOAD=1|true: skip postinstall browser download; only use if an executable is provided another way
Proxy / GeoIP
PROXY_STRATEGYPROXY_PROVIDERPROXY_HOSTPROXY_PORTPROXY_PORTSPROXY_USERNAMEPROXY_PASSWORDPROXY_BACKCONNECT_HOSTPROXY_BACKCONNECT_PORTPROXY_COUNTRYPROXY_STATEPROXY_CITYPROXY_ZIPPROXY_SESSION_DURATION_MINUTES
Telemetry
Upstream crash/hang telemetry is enabled unless disabled:
CAMOFOX_CRASH_REPORT_ENABLED=falseUse that for privacy-conservative local runs unless the user wants upstream crash reporting.
Hermes-specific CAMOFOX_URL footgun
This section is load-bearing for Hermes agents. Read it before setting environment variables.
In Hermes, CAMOFOX_URL is not just a harmless client hint. It is a browser-backend switch. If CAMOFOX_URL is visible in the Hermes process environment, Hermes considers Camofox mode enabled for that process and normal Hermes browser calls can be forced through Camofox.
Hard rules for Hermes:
- Do not add
CAMOFOX_URLto~/.hermes/.env. - Do not export
CAMOFOX_URLin shell profiles such as~/.zshrc,~/.bashrc, launchd plists, Docker env, or service env. - Do not put
CAMOFOX_URLin the Hermes gateway environment unless the explicit intent is for the entire gateway process to use Camofox for browser calls. - Do not use
hermes config set ... CAMOFOX_URL ...; this is runtime state, not durable config. - Use
CAMOFOX_URLonly as an inline, one-process env var for a dedicated cloaked Hermes run:
CAMOFOX_URL="http://127.0.0.1:9377" hermes chat -q 'Use cloaked Camofox browsing for this task: <task>'- After removing an accidentally global
CAMOFOX_URL, restart the affected Hermes CLI/gateway process; running processes keep their old environment.
Safer default for Hermes agents: run the Camofox server normally, store the stable server URL as skills.config.camofox.base_url or CAMOFOX_BASE_URL for REST examples, and do not set `CAMOFOX_URL` at all unless launching a dedicated cloaked Hermes process.
This routing claim is Hermes-specific. For OpenClaw, use the upstream plugin config/tools unless you have verified equivalent env semantics.
Verification checklist
Before claiming success:
1. Server health responds:
curl -fsS "${CAMOFOX_BASE_URL:-http://127.0.0.1:9377}/health"2. OpenClaw plugin mode, if applicable:
openclaw camofox status3. Raw REST mode: create a tab, snapshot it, close it.
4. Hermes mode: verify CAMOFOX_URL is absent from global Hermes env and present only on the dedicated cloaked Hermes process, if Hermes process routing is intentionally being used.
5. Cleanup: close tabs or stop the managed server if the task started it only for one job.
Common mistakes
- Using Camofox when normal search/extract tools are cheaper and sufficient.
- Forgetting
userIdin raw REST calls. - Clicking stale refs after navigation or DOM changes.
- Setting/exporting
CAMOFOX_URLglobally in Hermes (~/.hermes/.env, gateway env, shell profile, service env) and accidentally routing all browser calls through Camofox. - Assuming
CAMOFOX_API_KEYis needed for normal browser work; it is only for sensitive endpoints such as cookie import/traces. - Exposing a no-auth local development server beyond loopback.
- Treating MCP tool names from a separate MCP wrapper as if they are the upstream OpenClaw plugin tools. The MCP wrapper may expose many more tools; this skill is centered on upstream
@askjo/camofox-browserplus its REST API.
Output format when using this skill
Report:
- runtime: OpenClaw plugin, raw REST, Hermes, or other
- base URL: server URL used
- startup: npx/package, cloned repo npm start, OpenClaw autoStart, or existing server
- auth: no auth/local loopback,
CAMOFOX_ACCESS_KEY, orCAMOFOX_API_KEYfor sensitive endpoints - user/session:
userId,sessionKey - tab:
tabIdused/closed/preserved - verification: health + snapshot/action result summary
- cleanup: tabs closed and whether server was left running
camofox-cloaked-browser
Agent skill for using Camofox/Camoufox as an opt-in anti-detection browser server when normal automation is likely to get blocked.
This skill is intentionally npm-first. It does not include a container workflow.
Prerequisites
- Node.js 22+
- npm / npx
- curl for raw REST examples
- Optional: OpenClaw with the upstream
@askjo/camofox-browserplugin installed
Install this skill
Hermes
Install from the raw SKILL.md URL:
hermes skills install https://raw.githubusercontent.com/tmchow/agent-skills/main/camofox-cloaked-browser/SKILL.mdFrom an interactive Hermes CLI session, use the slash command path:
/skills install https://raw.githubusercontent.com/tmchow/agent-skills/main/camofox-cloaked-browser/SKILL.md
/reload-skills
/skill camofox-cloaked-browserUse /reload-skills if installing into an already-running session; then load it with /skill camofox-cloaked-browser when needed.
OpenClaw
Install from ClawHub:
openclaw skills install camofox-cloaked-browserClawHub page: https://clawhub.ai/tmchow/camofox-cloaked-browser
Default Camofox target
http://127.0.0.1:9377Start Camofox locally
npx -y @askjo/camofox-browserOr from a clone:
git clone https://github.com/jo-inc/camofox-browser
cd camofox-browser
npm install
npm startThe first install/run downloads the Camoufox browser binary unless CAMOUFOX_EXECUTABLE points to an existing compatible bundle.
What the skill teaches agents
- When Camofox is actually warranted and when to use cheaper tools instead
- OpenClaw plugin tools and CLI commands:
openclaw camofox status/start/stop/tabs/configure - Raw REST API commands for tabs, navigation, snapshots, clicks, typing, scrolling, screenshots, links/images, JS evaluation, structured extraction, and cleanup
- Hard workflow rules: check
/health, always senduserId, prefersessionKey, snapshot before refs, re-snapshot after state changes - Environment variables for npm/server mode, auth, telemetry, browser binary overrides, proxy settings, and Hermes
CAMOFOX_URL - Hermes-specific gotcha: globally visible
CAMOFOX_URLroutes Hermes browser calls through Camofox for that process
Important defaults
- Default base URL:
http://127.0.0.1:9377 - No auth is needed for local loopback development unless sensitive endpoints are used
- Set
CAMOFOX_ACCESS_KEYif exposing beyond localhost - Set
CAMOFOX_API_KEYfor cookie import - Set
CAMOFOX_CRASH_REPORT_ENABLED=falseto disable upstream crash/hang telemetry