# Browser CLI

> Control Firefox browser from the command line. Use for web automation, scraping, testing, or any browser interaction tasks.

- Skill: `mic92/browser-cli` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mic92/browser-cli`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mic92/browser-cli/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Mic92 (https://skillmd.com/u/mic92)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/mic92/browser-cli

---


# Usage

```bash
TAB=$(browser-cli --go "https://example.com")  # tab ID on stdout
browser-cli $TAB <<< 'snap()'                  # execute JS in that tab
browser-cli --list                             # TSV: id⇥*⇥url⇥title
browser-cli --list --json                      # machine-readable
```

# JavaScript API

Actions return confirmations; use `snap()` to get page state. Refs `[N]` come
from `snap()` output. CSS selectors also work: `click("#submit")`,
`click("Sign In", "text")`.

```javascript
// Interaction
await click(1)                       // also: {double: true}
await type(2, "text")                // also: {clear: true}
await hover(3)
await drag(4, 5)
await select(6, "value")
key("Enter")

// Inspection
snap()                               // full snapshot first call,
                                     // diff vs previous on later calls
snap({full: true})                   // force full snapshot
snap({interactive: true})            // only buttons/links/inputs (cheap)
snap({forms|links|buttons: true})    // filter by type (always full)
snap({text: "login"})                // filter by text (always full)
get(1, "text")                       // text|html|value|attr:name|count
is(2, "visible")                     // visible|enabled|checked -> bool
logs()                               // console logs

// Waiting
await wait(1000)                     // ms
await wait("idle")                   // DOM stable
await wait("text", "Success")        // text appears
await wait("gone", "Loading")        // text disappears

// Other
scroll("down")                       // also: up|top|bottom, or scroll(ref)
await upload(3, "/path/to/file.pdf") // <input type=file> (chunked, any size)
await download(url, "file.pdf")      // -> ~/Downloads/
await shot("/tmp/page.png")          // screenshot (omit path for data URL)
read()                               // article text via Readability
                                     // opts: {maxLength, includeMetadata}
```

Alternative to `read()`: `curl -sL "https://r.jina.ai/$URL"` returns clean
markdown without a browser tab — prefer for public static articles/docs.

# Snapshot Format

```
[1] heading "Welcome"
[2] input[email] "Email" [required]
[3] button "Sign In"
```

`[N]` = ref for click/type/etc. Shows role, name, and attrs like `[disabled]`,
`[checked]`, `[required]`.

# Example: Login Flow

```bash
TAB=$(browser-cli --go "https://example.com/login")
browser-cli $TAB <<< 'snap()'
# [1] input "Email"  [2] input "Password"  [3] button "Sign In"

browser-cli $TAB <<'EOF'
await type(1, "user@test.com")
await type(2, "secret123")
await click(3)
await wait("text", "Welcome")
snap()
EOF
```

