Browser
stealthy-auto-browse
Control a stealthy browser that evades bot detection
---
name: stealthy-auto-browse
description: Control a stealthy browser that evades bot detection using OS-level input
homepage: https://github.com/psyb0t/docker-stealthy-auto-browse
user-invocable: true
metadata:
{
"openclaw":
{
"emoji": "🕵️",
"primaryEnv": "STEALTHY_AUTO_BROWSE_URL",
"always": true,
},
}
---
# stealthy-auto-browse
## Setup Required
This skill requires a running stealthy-auto-browse container. Set the `STEALTHY_AUTO_BROWSE_URL` environment variable to connect.
**1. Run the container:**
```bash
docker run -d -p 8080:8080 -p 5900:5900 psyb0t/stealthy-auto-browse
```
**2. Configure OpenClaw** (`~/.openclaw/openclaw.json`):
```json
{
"skills": {
"entries": {
"stealthy-auto-browse": {
"env": {
"STEALTHY_AUTO_BROWSE_URL": "http://localhost:8080"
}
}
}
}
}
```
Or set the environment variable directly:
```bash
export STEALTHY_AUTO_BROWSE_URL=http://localhost:8080
```
**3. Verify:** Visit http://localhost:5900 to see the browser via VNC.
---
Control a headless browser that evades bot detection. Uses Camoufox (custom Firefox) with OS-level mouse/keyboard input via PyAutoGUI - completely undetectable by behavioral analysis.
## Key Concepts
**Why this exists:** Standard browser automation (Selenium, Playwright, Puppeteer) is detectable via CDP (Chrome DevTools Protocol) fingerprinting and synthetic event detection. This browser:
- Uses Firefox (no CDP exposure)
- Generates consistent fingerprints via browserforge
- Executes mouse/keyboard at OS level, not via JavaScript injection
**Two input modes:**
1. **Playwright methods** (`click`, `fill`, `type`) - Uses CSS selectors, faster but detectable
2. **System methods** (`system_click`, `system_type`, `mouse_move`) - OS-level input, undetectable but needs coordinates
**Workflow for undetectable interaction:**
1. Navigate to page with `goto`
2. Get elements with `get_interactive_elements`
3. Find target element's `x`, `y` coordinates
4. Click using `system_click` with those coordinates
5. Type using `system_type`
## Environment
Set `STEALTHY_AUTO_BROWSE_URL` to the browser API endpoint (e.g., `http://localhost:8080`).
## API Reference
All commands are POST requests to `$STEALTHY_AUTO_BROWSE_URL/` with JSON body `{"action": "<name>", ...params}`.
### Navigation
**goto** - Navigate to URL
```json
{
"action": "goto",
"url": "https://example.com",
"wait_until": "domcontentloaded"
}
```
`wait_until`: `domcontentloaded` (default), `load`, `networkidle`
### Undetectable Input (Use These!)
**system_click** - Move mouse and click at coordinates (UNDETECTABLE)
```json
{ "action": "system_click", "x": 500, "y": 300, "duration": 0.3 }
```
`duration`: Optional mouse movement duration in seconds
**mouse_move** - Move mouse to coordinates without clicking
```json
{ "action": "mouse_move", "x": 500, "y": 300, "duration": 0.5 }
```
**mouse_click** - Click at current position or specific coordinates
```json
{"action": "mouse_click"}
{"action": "mouse_click", "x": 500, "y": 300}
```
**system_type** - Type text using OS keyboard (UNDETECTABLE)
```json
{ "action": "system_type", "text": "hello world", "interval": 0.08 }
```
`interval`: Delay between keystrokes in seconds (default: 0.08)
**send_key** - Send special key (enter, tab, escape, etc.)
```json
{"action": "send_key", "key": "enter"}
{"action": "send_key", "key": "tab"}
{"action": "send_key", "key": "escape"}
```
**scroll** - Scroll page
```json
{"action": "scroll", "amount": -3}
{"action": "scroll", "amount": 5, "x": 500, "y": 300}
```
`amount`: Negative = scroll down, positive = scroll up
### Playwright Input (Detectable - Use Only When Necessary)
**click** - Click element by CSS selector (detectable)
```json
{"action": "click", "selector": "#submit-btn"}
{"action": "click", "selector": "button.login"}
```
**fill** - Fill input field (clears first)
```json
{
"action": "fill",
"selector": "input[name='email']",
"value": "[email protected]"
}
```
**type** - Type into element character by character
```json
{ "action": "type", "selector": "#search", "text": "query", "delay": 0.05 }
```
### Page Inspection
**get_interactive_elements** - Get all clickable elements with coordinates (ESSENTIAL!)
```json
{ "action": "get_interactive_elements", "visible_only": true }
```
Returns array of elements:
```json
{
"elements": [
{
"i": 0,
"tag": "button",
"text": "Sign In",
"selector": "#login-btn",
"x": 500,
"y": 300,
"w": 100,
"h": 40,
"visible": true
}
]
}
```
Use `x` and `y` coordinates with `system_click` for undetectable clicks!
**get_text** - Get page text content
```json
{ "action": "get_text" }
```
**get_html** - Get full page HTML
```json
{ "action": "get_html" }
```
**eval** - Execute JavaScript in page context
```json
{"action": "eval", "expression": "document.title"}
{"action": "eval", "expression": "window.scrollY"}
```
### Screenshots
**GET /screenshot/browser** - Browser viewport PNG
**GET /screenshot/desktop** - Full desktop PNG
Use curl or fetch:
```bash
curl $STEALTHY_AUTO_BROWSE_URL/screenshot/browser -o screenshot.png
```
### State & Utility
**GET /state** - Current browser state (url, title, window_offset)
**GET /health** - Health check (returns "ok")
**ping** - Check connection, returns current URL
```json
{ "action": "ping" }
```
**close** - Shut down the browser and server
```json
{ "action": "close" }
```
**calibrate** - Recalculate window offset for coordinate translation
```json
{ "action": "calibrate" }
```
### Resolution
**get_resolution** - Get current resolution
```json
{ "action": "get_resolution" }
```
### Fullscreen
**enter_fullscreen** / **exit_fullscreen**
```json
{"action": "enter_fullscreen"}
{"action": "exit_fullscreen"}
```
## Complete Workflow Example
Here's how to login to a site undetectably:
```bash
# 1. Navigate to login page
curl -X POST $STEALTHY_AUTO_BROWSE_URL -H "Content-Type: application/json" \
-d '{"action": "goto", "url": "https://example.com/login"}'
# 2. Get all interactive elements
curl -X POST $STEALTHY_AUTO_BROWSE_URL -H "Content-Type: application/json" \
-d '{"action": "get_interactive_elements"}'
# Response shows email input at x:400, y:200 and password at x:400, y:260
# 3. Click email field (undetectable)
curl -X POST $STEALTHY_AUTO_BROWSE_URL -H "Content-Type: application/json" \
-d '{"action": "system_click", "x": 400, "y": 200}'
# 4. Type email (undetectable)
curl -X POST $STEALTHY_AUTO_BROWSE_URL -H "Content-Type: application/json" \
-d '{"action": "system_type", "text": "[email protected]"}'
# 5. Click password field
curl -X POST $STEALTHY_AUTO_BROWSE_URL -H "Content-Type: application/json" \
-d '{"action": "system_click", "x": 400, "y": 260}'
# 6. Type password
curl -X POST $STEALTHY_AUTO_BROWSE_URL -H "Content-Type: application/json" \
-d '{"action": "system_type", "text": "secretpassword"}'
# 7. Find and click submit button (from get_interactive_elements, e.g., x:400, y:320)
curl -X POST $STEALTHY_AUTO_BROWSE_URL -H "Content-Type: application/json" \
-d '{"action": "system_click", "x": 400, "y": 320}'
```
## Response Format
All POST responses follow this format:
```json
{
"success": true,
"timestamp": 1234567890.123,
"data": { ... },
"error": "message if failed"
}
```
## Tips
1. **Always use `get_interactive_elements` first** to find coordinates for clicking
2. **Prefer `system_click` and `system_type`** over Playwright methods for stealth
3. **Add small delays** between actions to appear more human-like
4. **Use `calibrate`** if clicks seem offset after page changes
5. **Check screenshots** to debug what the browser sees
6. **Match timezone** - The container's TZ must match the IP's location for fingerprint consistency
## VNC Access
Connect to port 5900 via noVNC web viewer to see the browser in action.
browser
By
Comments
Sign in to leave a comment