| name | cloak-agent |
| description | Stealth browser automation CLI for AI agents. Use when automating browsers, scraping sites with bot detection, filling forms, navigating pages, or any task requiring undetectable browser control. Replaces agent-browser with stealth Chromium that passes all bot detection tests. |
| trigger | Use when the user asks to automate a browser, scrape a website, interact with a web page, fill forms, click buttons, take screenshots, or any browser-based task. Especially use when stealth/anti-detection is needed (Cloudflare, reCAPTCHA, bot detection). |
| invariants | ["Always snapshot after navigation to get fresh refs","Use snapshot -i (interactive) by default to minimize tokens","Refs (@e1, @e2) are only valid until the next navigation","Use fill instead of type for input fields (fill clears first)","Run stealth status after launch to verify detection evasion","Use fingerprint rotate when switching tasks or identities","Use --dry-run for destructive actions when unsure"] |
Browser Automation with cloak-agent
Stealth browser automation CLI built for AI agents. Uses CloakBrowser's patched Chromium (C++ source-level patches, not JavaScript injection) so bot detection sees a real browser — because it is one.
Installation
From source
git clone https://github.com/nerveband/cloak-agent.git
cd cloak-agent
cd daemon && npm install && cd ..
make build
make install
Installs to ~/.cloak-agent/, exposes cloak-agent through a writable PATH location when possible, and downloads/checks the stealth Chromium binary (~200MB).
Prerequisites
Quick start
cloak-agent open https://example.com
cloak-agent snapshot -i
cloak-agent click @e1
cloak-agent stealth status
Core workflow
- Navigate:
cloak-agent open <url>
- Snapshot:
cloak-agent snapshot -i (returns elements with refs like @e1, @e2)
- Interact using refs from the snapshot
- Re-snapshot after navigation or significant DOM changes
- Verify stealth:
cloak-agent stealth status after launch
For tricky interactions, follow docs/interaction-playbook.md. That playbook credits browser-harness as inspiration for screenshot-first debugging, explicit interaction playbooks, runtime proof in diagnostics, and a narrow raw-CDP fallback.
Architecture
Two processes, one job:
Go CLI (sub-ms) <--Unix socket--> Node.js daemon (long-running)
parse args CloakBrowser via Playwright
send JSON ARIA snapshots + 70+ actions
format output Zod validation
The daemon starts automatically on first command and stays alive between commands.
Commands
Navigation
cloak-agent open <url>
cloak-agent open <url> --wait networkidle
cloak-agent back
cloak-agent forward
cloak-agent reload
cloak-agent close
Snapshot (page analysis)
cloak-agent snapshot
cloak-agent snapshot -i
cloak-agent snapshot -c
cloak-agent snapshot -d 3
cloak-agent snapshot -s "#main"
Output format:
- button "Submit" [ref=e1]
- textbox "Email" [ref=e2]
- link "Sign up" [ref=e3]
Stats: 3 refs, 89 chars, ~23 tokens
Interactions (use @refs from snapshot)
cloak-agent click @e1
cloak-agent dblclick @e1
cloak-agent focus @e1
cloak-agent fill @e2 "text"
cloak-agent type @e2 "text"
cloak-agent press Enter
cloak-agent press Control+a
cloak-agent keydown Shift
cloak-agent keyup Shift
cloak-agent hover @e1
cloak-agent check @e1
cloak-agent uncheck @e1
cloak-agent select @e1 "value"
cloak-agent scroll down 500
cloak-agent scrollintoview @e1
cloak-agent drag @e1 @e2
cloak-agent upload @e1 file.pdf
Get information
cloak-agent get title
cloak-agent get url
cloak-agent get text @e1
cloak-agent get html @e1
cloak-agent get value @e2
cloak-agent get attr @e1 href
cloak-agent get count ".item"
cloak-agent get box @e1
Check state
cloak-agent is visible @e1
cloak-agent is enabled @e1
cloak-agent is checked @e1
Screenshots & PDF
cloak-agent screenshot
cloak-agent screenshot output.png
cloak-agent screenshot --full
cloak-agent pdf output.pdf
Wait
cloak-agent wait @e1
cloak-agent wait 2000
cloak-agent wait --text "Success"
cloak-agent wait --url "/dashboard"
cloak-agent wait --load networkidle
cloak-agent wait --fn "window.ready"
Stealth (cloak-agent exclusive)
These don't exist in other browser CLIs:
cloak-agent stealth status
cloak-agent fingerprint rotate
cloak-agent fingerprint rotate --seed 42
cloak-agent profile create shopping
cloak-agent profile list
What gets patched at the C++ level:
navigator.webdriver removed
- GPU renderer/vendor randomized
- Screen dimensions from fingerprint seed
- Hardware concurrency randomized
- Device memory randomized
- Platform string matches configured OS
- Canvas, WebGL, audio, fonts noise
- CDP automation signals removed
Stealth tips:
- Run
stealth status after launch to verify all 30 tests pass
- Use
fingerprint rotate when switching tasks or identities
- Use
fingerprint rotate --seed 42 for deterministic identity (same seed = same fingerprint)
- Use persistent profiles for sites that track returning visitors (avoids incognito detection)
- Use proxies with geoip for timezone/locale consistency
Semantic locators (alternative to refs)
cloak-agent find role button click --name "Submit"
cloak-agent find text "Sign In" click
cloak-agent find label "Email" fill "user@test.com"
cloak-agent find first ".item" click
cloak-agent find nth 2 "a" text
Browser settings
cloak-agent set viewport 1920 1080
cloak-agent set device "iPhone 14"
cloak-agent set geo 37.7749 -122.4194
cloak-agent set offline on
cloak-agent set headers '{"X-Key":"v"}'
cloak-agent set credentials user pass
cloak-agent set media dark
Cookies & Storage
cloak-agent cookies
cloak-agent cookies set name value
cloak-agent cookies clear
cloak-agent storage local
cloak-agent storage local key
cloak-agent storage local set k v
cloak-agent storage local clear
Tabs
cloak-agent tab
cloak-agent tab new [url]
cloak-agent tab 2
cloak-agent tab close
Network
cloak-agent network requests
cloak-agent network requests --filter api
cloak-agent network route <url>
cloak-agent network route <url> --abort
cloak-agent network route <url> --body '{}'
cloak-agent network unroute [url]
Dialogs
cloak-agent dialog accept [text]
cloak-agent dialog dismiss
JavaScript
cloak-agent eval "document.title"
cloak-agent cdp Runtime.evaluate '{"expression":"document.title","returnByValue":true}'
State management
cloak-agent state save auth.json
cloak-agent state load auth.json
Debugging
cloak-agent open example.com --headed
cloak-agent console
cloak-agent console --clear
cloak-agent errors
cloak-agent errors --clear
cloak-agent highlight @e1
cloak-agent trace start
cloak-agent trace stop trace.zip
cloak-agent record start ./demo.webm
cloak-agent record stop
Schema introspection (for AI agents)
cloak-agent schema
cloak-agent schema navigate
Self-update
cloak-agent upgrade
cloak-agent version
Sessions (parallel browsers)
cloak-agent --session shop1 open https://store-a.com
cloak-agent --session shop2 open https://store-b.com
cloak-agent --session shop1 snapshot -i
cloak-agent --session shop2 snapshot -i
cloak-agent session list
Global flags
| Flag | What it does |
|---|
--session <name> | Named session (parallel browsers) |
--json | JSON output mode |
--json '{...}' | Raw JSON payload |
--timeout <ms> | Command timeout |
--headed | Show browser window |
--dry-run | Validate without executing |
--fields <list> | Limit response fields |
JSON output (for parsing)
cloak-agent snapshot -i --json
cloak-agent get text @e1 --json
Raw JSON mode (for agents)
cloak-agent --json '{"action":"navigate","url":"https://example.com","waitUntil":"networkidle"}'
Environment variables
| Variable | Description |
|---|
CLOAK_AGENT_SESSION | Default session name |
CLOAK_AGENT_SOCKET_DIR | Custom socket directory |
CLOAK_AGENT_DAEMON_DIR | Custom daemon directory |
CLOAK_AGENT_HEADED | Show browser window |
CLOAK_AGENT_PROXY | Proxy server URL |
CLOAK_AGENT_PROXY_BYPASS | Proxy bypass list |
CLOAK_AGENT_PROFILE | Persistent profile name |
CLOAK_AGENT_ARGS | Extra Chromium args (comma-separated) |
CLOAK_AGENT_USER_AGENT | Custom user agent |
CLOAK_AGENT_STATE | Path to storage state JSON |
CLOAK_AGENT_IGNORE_HTTPS_ERRORS | Ignore HTTPS errors |
CLOAK_AGENT_EXECUTABLE_PATH | Custom Chromium binary |
Example: Form submission
cloak-agent open https://example.com/form
cloak-agent snapshot -i
cloak-agent fill @e1 "user@example.com"
cloak-agent fill @e2 "password123"
cloak-agent click @e3
cloak-agent wait --load networkidle
cloak-agent snapshot -i
Example: Login with saved state
cloak-agent open https://app.com/login
cloak-agent snapshot -i
cloak-agent fill @e1 "user@email.com"
cloak-agent fill @e2 "password"
cloak-agent click @e3
cloak-agent wait --url "/dashboard"
cloak-agent state save auth.json
cloak-agent state load auth.json
cloak-agent open https://app.com/dashboard
Example: Stealth browsing with fingerprint rotation
cloak-agent open https://bot.sannysoft.com
cloak-agent stealth status
cloak-agent fingerprint rotate
cloak-agent stealth status
Example: Persistent profile for returning visitor
cloak-agent profile create shopping
CLOAK_AGENT_PROFILE=shopping cloak-agent open https://store.com
Example: Proxy with auto geoip
CLOAK_AGENT_PROXY=http://user:pass@us-proxy:8080 cloak-agent open https://example.com
cloak-agent stealth status
Key differences from agent-browser
| Feature | agent-browser | cloak-agent |
|---|
| Stealth Chromium (C++ patches) | no | yes |
| Fingerprint randomization | no | yes |
| GPU/platform spoofing | no | yes |
| Bot detection check | no | yes |
| Fingerprint rotation | no | yes |
| Persistent profiles | no | yes |
| Raw JSON payload mode | no | yes |
| Schema introspection | no | yes |
| Dry-run validation | no | yes |
| Input hardening | no | yes |
| ARIA snapshots + @refs | yes | yes |
| All standard browser commands | yes | yes |
Troubleshooting
- Element not found: Re-snapshot to get fresh refs. Refs change after navigation.
- Page not loaded: Add
cloak-agent wait --load networkidle after navigation.
- Blocked by overlay: Dismiss modals/cookie banners first, then retry.
- Click fails: Try
scrollintoview @e1 before clicking. Use --headed to debug visually.
- Detection failing: Run
stealth status to check. Try fingerprint rotate for a fresh identity.
- Daemon not starting: Check Node.js 20+ is installed. Check
~/.cloak-agent/ for socket files.
Notes
- Refs are stable per page load but change on navigation — always re-snapshot.
- Use
fill instead of type for inputs (fill clears existing text first).
- The daemon auto-starts on first command and stays alive between commands.
- Stealth Chromium binary downloads automatically on first run (~200MB).
- Every snapshot includes token count estimates so agents can decide on detail level.
Reporting issues