Commands reference
OmniScout is organized into command groups. Use omniscout --help to see all of
them, or omniscout <command> --help for command-specific options.
Global options
All commands support:
--json— emit machine-readable JSON to stdout. Logs go to stderr.--verbose,-v— verbose stderr logging.--version— print version and exit.
You can also set OMNISCOUT_JSON=1 in the environment to make JSON output
the default for every command in a session — the typical setup for an AI
agent.
Daemon (omniscout daemon ...)
The daemon is a long-lived process that holds Playwright (and optionally a
WebSocket bridge to the Chrome extension) open. Every omniscout browser ...
command is a thin HTTP client into the daemon.
omniscout daemon start
omniscout daemon start [--port N]
Idempotent. If a daemon is already up it returns the existing status. If
not, it spawns a background process and waits for /healthz.
{
"running": true,
"port": 7720,
"version": "0.1.0",
"protocol_version": "1",
"extension_connected": false,
"extension_id": null,
"uptime_seconds": 0,
"sessions": [],
"backends": ["playwright"],
"pid": 12345
}
omniscout daemon stop
SIGTERM, then SIGKILL after 5 seconds.
omniscout daemon restart
stop followed by start.
omniscout daemon status
Same JSON shape as start. Returns { "running": false } when down.
omniscout daemon logs
omniscout daemon logs [-n LINES] [-f] [--prev]
-n N— tail the last N lines (default 100).-f— follow the log live (Ctrl-C to exit).--prev— read the previous run's log (rotated on eachstart).
omniscout daemon trace
Show recent rows from the structured action history (one JSONL row per command the daemon has handled, capped at 10,000 rows then rotated).
omniscout daemon trace [-n N] [--session NAME] [--action VERB] [--since SECONDS] [--prev]
omniscout daemon trace last # shorthand: print the most recent row as JSON
Each row looks like:
{
"action_id": "8f3a7c9e1b2d4e5f",
"ts": "2026-05-26T19:00:42.123456Z",
"elapsed_ms": 42,
"ok": true,
"session": "default",
"action": "click",
"args": {"selector": "@e3"},
"snapshot_generation": 18,
"error_kind": null,
"error": null,
"backend": "playwright"
}
--prev also includes the rotated actions.prev.jsonl.
omniscout daemon replay
Re-run actions from the history without retyping them.
omniscout daemon replay <action_id> # single action
omniscout daemon replay --session NAME [--since SECONDS] # everything in a window
omniscout daemon replay --session NAME --dry-run # list, don't run
Interactive verbs (login, login_done, captcha_solve, upload) are
skipped by default. Pass --include-interactive to replay them too. The
replayed call's response includes a source_action_id field pointing
back to the original row for traceability.
omniscout daemon watch
Subscribe to the daemon's live event stream (Server-Sent Events).
omniscout daemon watch [--filter TYPE]... [--json-lines]
Events you'll see: action.start, action.finish, session.opened,
session.closed, extension.connected, extension.disconnected. Use
--filter action.finish to narrow down, and --json-lines to emit one
JSON object per line for piping into another tool.
Browser action vocabulary
These are the verbs an AI agent will use most. Same JSON shape regardless of which backend (Playwright or extension) handles the session.
All accept --session NAME (default default) to isolate parallel tasks.
omniscout browser navigate
omniscout browser navigate <url> [--new-tab] [--profile NAME] [--headful] \
[--wait-until {load,domcontentloaded,networkidle}] \
[--session NAME]
First call binds the session to a backend. Without --new-tab, navigates
the active tab.
{
"action": "navigate",
"url": "https://example.com",
"title": "Example Domain",
"tab_id": "0",
"status": 200
}
omniscout browser open is a backwards-compatible alias.
omniscout browser snapshot
omniscout browser snapshot [--refs-only] [--session NAME]
Returns the accessibility tree of the active page with stable @eN refs
on every focusable / semantic element. The primary way to address
elements — refs survive across calls until the next navigate.
{
"action": "snapshot",
"url": "https://example.com",
"title": "Example",
"refs": [
{ "ref": "@e1", "role": "heading", "name": "Example Domain", "value": "" },
{ "ref": "@e2", "role": "link", "name": "More information...", "value": "" }
],
"tree": { /* full nested tree, suppressed with --refs-only */ }
}
omniscout browser click
omniscout browser click <ref-or-selector> [--button {left,right,middle}] \
[--mod cmd|ctrl|alt|shift]... \
[--clicks N] [--session NAME]
omniscout browser click --coord X Y [--session NAME]
<ref-or-selector> is an @eN ref from snapshot (preferred), any CSS
selector, or omitted if you pass --coord. Coordinates are the
vision-agent escape hatch.
{ "action": "click", "mode": "selector", "tag": "BUTTON", "text": "Submit" }
omniscout browser fill
omniscout browser fill <ref-or-selector> <value> [--session NAME]
Replaces existing content. Works on <input> / <textarea> and[contenteditable] (ProseMirror, Lexical, Slate, TipTap, Quill) via
execCommand('insertText').
{ "action": "fill", "mode": "value", "tag": "input" }
mode is "value" for native inputs, "contenteditable" for rich-text.
omniscout browser type
omniscout browser type <ref-or-selector> <text> [--session NAME]
Appends keystrokes without clearing the field (unlike fill).
omniscout browser paste
omniscout browser paste <ref-or-selector> <text> [--session NAME]
Inserts text at the cursor (clipboard-style paste into the focused element).
omniscout browser select
omniscout browser select <ref-or-selector> <value> [--session NAME]
Selects an option on a native <select> by value or visible label.
omniscout browser scroll
omniscout browser scroll [up|down|left|right] [--amount N] [--ref REF] [--session NAME]
--amount is in 100px ticks (default 3). --ref scrolls within an
element instead of the page.
omniscout browser key
omniscout browser key <combo> [--session NAME]
combo is e.g. cmd+a, Escape, Enter, ctrl+shift+t. Aliases:
cmd/command→Meta, option→Alt, return→Enter, esc→Escape.
omniscout browser back / forward / reload
omniscout browser back [--session NAME]
omniscout browser forward [--session NAME]
omniscout browser reload [--session NAME]
History navigation on the active tab.
omniscout browser hover
omniscout browser hover <ref-or-selector> [--session NAME]
omniscout browser hover --coord X Y [--session NAME]
omniscout browser upload
omniscout browser upload <ref-or-selector> <file>... [--session NAME]
Attaches files to an <input type="file">. Playwright backend only.
omniscout browser screenshot
omniscout browser screenshot [URL] [-o PATH] [--ref REF] \
[--full-page | --full-length] \
[--format {png,jpeg}] [--quality 0-100] \
[--profile NAME] [--session NAME]
If URL is given, navigates first. By default only the visible viewport is
captured. Pass --full-page or --full-length (aliases) to capture the entire
scrollable page from top to bottom. --ref captures a single element instead.
The daemon writes the file to disk and returns the path — agents read the file via their file-read tool.
{
"action": "screenshot",
"format": "png",
"path": "/tmp/state.png",
"size_bytes": 7275,
"mime_type": "image/png"
}
omniscout browser pdf
omniscout browser pdf [URL] [-o PATH] [--paper {letter,a4,legal,a3,tabloid}] \
[--landscape] [--scale 0.1-2.0] [--session NAME]
Playwright backend only (requires headless Chrome's print pipeline).
omniscout browser eval
omniscout browser eval <js> [--session NAME]
Evaluates JavaScript in the active page. async/await supported.
omniscout browser eval "document.title"
# {"action":"evaluate","type":"str","value":"Example"}
omniscout browser get
omniscout browser get title [--session NAME]
omniscout browser get url [--session NAME]
omniscout browser get text [--session NAME]
omniscout browser get html [--session NAME]
Lightweight page inspection without a full snapshot.
omniscout browser is
omniscout browser is <ref-or-selector> <state> [--session NAME]
state is one of visible, hidden, enabled, disabled, checked,
editable.
omniscout browser wait
# Subcommands (preferred)
omniscout browser wait text <substring> [--timeout-ms 30000]
omniscout browser wait selector <ref-or-css> [--timeout-ms 30000]
omniscout browser wait networkidle [--timeout-ms 30000]
omniscout browser wait url <glob-pattern> [--timeout-ms 30000]
# Legacy flags (still supported)
omniscout browser wait [--ref REF] [--url PATTERN] [--idle] [--ms N] [--timeout-ms 30000]
For legacy mode, exactly one of --ref, --url, --idle, or --ms must be
set. --url takes a regex; the wait url subcommand takes a glob.
omniscout browser mouse
omniscout browser mouse scroll --coord X Y --delta DX DY [--session NAME]
omniscout browser mouse move --coord X Y [--session NAME]
Raw wheel and pointer moves at pixel coordinates (vision-agent escape hatch).
omniscout browser login
omniscout browser login <url> [--profile NAME] [--success-pattern REGEX] \
[--timeout-ms 300000] [--session NAME]
# In a second shell once you've authenticated:
omniscout browser login --done [--session NAME]
Opens headful Chrome on <url>, then blocks until either the URL
matches --success-pattern OR you call omniscout browser login --done
from another shell. Cookies persist in the profile, so subsequent
commands with the same --profile are already logged in.
{ "action": "login", "logged_in": true, "final_url": "https://github.com/" }
omniscout browser captcha
omniscout browser captcha [--detect-only] [--solver {none,2captcha,capsolver,manual}] \
[--api-key KEY] [--timeout-ms 120000] [--session NAME]
Detects reCAPTCHA v2/v3, hCaptcha, and Cloudflare Turnstile.
--detect-onlyreturns{ detected, type, sitekey, frame_url }and exits.- Default
--solver noneflips the tab headful and blocks the calling CLI until the page is captcha-free (typically because you solved it manually). --solver 2captcha/--solver capsolversends the sitekey + page URL to the third-party API. API key from--api-keyor env (TWOCAPTCHA_API_KEY/CAPSOLVER_API_KEY).
omniscout browser close
omniscout browser close [--session NAME] [--all]
Always call at the end of a task.
Tab management (omniscout browser tab ...)
omniscout browser tab list # show all tabs in the session
omniscout browser tab close [TAB_ID] # default = active tab
omniscout browser tab switch <TAB_ID> # make TAB_ID active
tab list JSON:
{
"action": "list_tabs",
"tabs": [
{ "tab_id": "0", "url": "https://...", "title": "...", "active": true }
]
}
Network capture (omniscout browser network ...)
omniscout browser network start # begin capturing requests + responses
omniscout browser network stop # stop and return count
omniscout browser network list [--filter REGEX]
omniscout browser network tail [--since ID] [--filter REGEX]
omniscout browser network detail <REQUEST_ID>
network tail returns incremental entries since --since (for polling loops).
{
"action": "network.list",
"entries": [
{ "id": 12345, "url": "https://api.example.com/track", "method": "POST",
"status": null, "kind": "request", "ts": 1716796020.34 }
],
"count": 1
}
Console capture (omniscout browser console ...)
omniscout browser console start
omniscout browser console stop
omniscout browser console list [--filter REGEX]
omniscout browser console tail [--since ID] [--filter REGEX]
Captures console.* messages and uncaught JS errors without screenshots.
Use tail for incremental polling like network tail.
Search, extract, research, graph
These existed before OmniScout's daemon work and still operate directly
(no daemon round-trip). graph uses the local answer LLM when enabled; other
commands in this group do not require it.
Stateful Workflow Commands
These top-level commands provide deterministic workflow continuity for agents:
omniscout search "OpenAI operator"
omniscout open 1
omniscout snapshot --refs-only
omniscout extract @e42
omniscout context
Deterministic shorthand rules:
omniscout open 1means index1from the latest search result set only.- Numeric
opentargets never map to tabs, snapshots, or mixed contexts. omniscout extract @eNresolves through the latest snapshot lineage.- If refs are stale, re-run
omniscout snapshotbefore retrying extraction.
omniscout open
omniscout open <url-or-index> [--session NAME] [--profile NAME] [--new-tab]
Opens a URL directly, or resolves an integer index from the most recent search.
omniscout snapshot
omniscout snapshot [--session NAME] [--refs-only] [--overlay]
Top-level alias for browser snapshot with @eN ref output.
omniscout context
omniscout context
Shows persisted workflow state: active session/page/tab, latest snapshot generation, latest search set, and tracked refs.
omniscout reset
omniscout reset
Clears workflow continuity state (open index mappings, snapshot ref lineage,
active workflow context) without force-closing browser sessions.
omniscout remember
omniscout remember <url> [--note TEXT] [--session NAME] [--cache/--no-cache]
Fetches and extracts a URL, then indexes it into browser memory as a
visit record. Optional --note adds a linked note record. Memory is
explicit only — normal navigate / extract / snapshot do not auto-index.
omniscout memory ...
omniscout memory list [--kind visit|note] [--limit N]
omniscout memory show <id>
omniscout memory note "text" [--session NAME]
omniscout memory delete <id>
omniscout memory delete --url <url>
omniscout memory clear --yes
omniscout memory stats
Memory lives in $OMNISCOUT_DATA_DIR/memory.sqlite with vectors in the
omniscout_memory Qdrant collection. Deletion removes both SQLite rows and
matching vectors. stats reports record counts, vector count, and storage hints.
omniscout workflow export
omniscout workflow export [--session NAME] [--since SECONDS] [--from-context] [--include-interactive]
Exports agent-friendly JSON steps:
{
"steps": [
{ "search": "OpenAI pricing" },
{ "open": 1 },
{ "snapshot": true },
{ "extract": "@e12" }
]
}
Sources: persisted workflow_state.json plus replayable rows from
daemon/actions.jsonl. Pass --from-context to export only current workflow
state without reading action history.
omniscout replay
Top-level alias for daemon replay:
omniscout replay action-<action_id>
omniscout replay session-<name> [--since SECONDS] [--dry-run] [--include-interactive]
Also accepts a bare 16-character hex action_id. See omniscout daemon replay.
omniscout search
omniscout search <query> [--limit N] [--source {ddg,index,memory,hybrid}] [--rerank/--no-rerank] [--data]
| Source | Meaning |
|---|---|
ddg | Live DuckDuckGo HTML results |
index | Local Qdrant crawl corpus from research |
memory | Remembered visits and notes (omniscout remember) |
hybrid | Memory + DDG, deduplicated by URL |
{ "query": "...", "source": "ddg", "count": 10, "hits": [ { "url": "...", "title": "...", "snippet": "...", "score": 0.92, "rank": 1 } ] }
For one-sentence factual answers, use omniscout answer "your question".
Search returns ranked hits only; it does not synthesize an answer sentence.
omniscout answer
omniscout answer <query> [--limit N] [--depth {auto,fast,balanced,deep}] [--data] [--no-llm]
Grounded answers from web retrieval plus a small local LLM (SmolLM2-360M,
cached on disk). The pipeline tries direct DuckDuckGo answers first
(HTML instant box, ranked snippets, Search Assist), then extractive synthesis
from filtered hits, then the local LLM, then a limited crawl for hard
who-is queries. Falls back to extractive-only when the model is unavailable
(--no-llm forces extractive only).
# Classifier-routed (default)
omniscout answer "who is the prime minister of india"
# Snippets-first (fast)
omniscout answer "who is the pm of singapore" --depth fast
# Factual lookups (capital, height, math)
omniscout answer "what is the capital of france"
omniscout answer "how tall is mount everest"
omniscout answer "what is 2+2"
# Crawl top sources when snippets are weak (slow)
omniscout answer "FedRAMP LLM hosting requirements" --depth deep
# Sources, timing, llm_backend
omniscout answer "..." --data
| Flag | Default | Meaning |
|---|---|---|
--depth | auto | fast (snippets + direct), balanced (same + refined retry), deep (crawl) |
--limit, -n | 10 | Max search hits to consider |
--data | off | Rich UI + diagnostics (elapsed_ms, llm_backend, supports) |
--no-llm | off | Skip local LLM; extractive fallback only |
With --data, retrieval and llm_backend show how the answer was produced:
| Label | Meaning |
|---|---|
direct+snippet | Named entity or factual value from a DDG snippet |
direct+assist | DuckDuckGo Search Assist box |
direct+zci | DuckDuckGo HTML instant/ZCI box |
direct+calc | Local arithmetic (simple math queries) |
direct+instant | DuckDuckGo Instant API (when populated and validated) |
extractive+ddg | Pattern extraction from ranked snippets |
llm+ddg | Local LLM over snippet sources |
extractive+crawl / llm+crawl | Crawled page chunks (deep mode or escalation) |
Without --data, stdout is plain text (just the answer sentence).
Prefetch the answer model:
omniscout install --answer-model
omniscout warmup # embedding + answer LLM in daemon
omniscout warmup
omniscout warmup [--answer-model/--no-answer-model]
Preloads the embedding model and (by default) the small answer LLM in the
daemon (not a throwaway CLI process). Models stay hot for subsequent
search, answer, research, and remember calls. Search commands
auto-start the daemon and route embeds through it by default, so warmup is
optional — use it when you want to pay the first-load cost before a batch.
Set OMNISCOUT_EMBED_DAEMON=0 to load the model in-process instead (tests,
debugging).
omniscout benchmark answers
omniscout benchmark answers [--queries 100] [--modes fast,balanced,deep] [--dataset PATH]
Runs a full matrix over answer modes with:
- cold + warm runs
- cache enabled + cache bypassed
- per-query correctness against the gold dataset
- persisted metrics (
p50,p95, success rate, cache hit rate, fallback frequency)
omniscout benchmark startup
omniscout benchmark startup [--iterations 10]
Profiles Python CLI startup overhead for critical commands and appends metrics to the benchmark metrics log.
Embed model in the daemon
Search, research, and memory commands route embedding through the same
long-lived daemon that powers browser automation (127.0.0.1:7720). The
sentence-transformers model loads once into daemon RAM (~80MB, ~2s) and stays
warm across CLI invocations.
omniscout daemon statusreportsembed_model_loaded,embed_model, andembed_model_dim.OMNISCOUT_EMBED_DAEMON=1(default) — embed via daemon; auto-starts if needed.OMNISCOUT_EMBED_DAEMON=0— in-process load (legacy behavior).- Model files are prefetched to disk by
omniscout install(default). If missing, the first embed attempt downloads them automatically.
omniscout extract
omniscout extract <url> [--format {markdown,text,json,structured}] [--cache/--no-cache]
omniscout extract <url> --format structured
omniscout extract <url> --format json --fields company,pricing,founder,description
omniscout extract <url> --format structured --data
omniscout extract --query "SpaceX founder" --format structured --fields founder
omniscout extract -q "Acme Inc pricing" --format structured --depth 3 --results 5
URL or query — pass a URL, or omit it and use --query / -q for
search-driven structured extraction (requires --format structured or
--fields). Query mode: DDG search → crawl top --results URLs (default 5) →
follow same-host links up to --depth levels (default 3) → merge text → extract
fields.
Formats
markdown/text— readable body content (default: markdown).json— fullExtractResultmetadata pluscontent/text.structured— flat JSON with extracted fields (fast NLP heuristics, no LLM). Without--fields, extracts everything it can: company metadata, pricing, founder, contact info, social links (Twitter/X, LinkedIn, GitHub, YouTube, etc.), important page URLs (docs, blog, careers, community, status, …), and anyLabel: valuelines on the page. Use--fieldsto limit output.
When key fields are missing, OmniScout may follow detail links from the page
(/pricing, /plans, /about, /contact, …) with one extra fetch per page
(cached like normal extract).
Structured output example (auto, fields only):
{
"company": "Acme Inc",
"description": "Acme builds local-first AI tools.",
"pricing": "$99/mo",
"title": "Acme — Home",
"site_name": "Acme"
}
With explicit fields:
omniscout extract https://example.com --format structured --fields company,pricing
Add --data to include the full ExtractResult (cached, structured_ms,
content, etc.) and stderr diagnostic logs. Without --data, structured mode
emits only the extracted fields JSON on stdout.
omniscout research
omniscout research <topic> [--depth N] [--results K] [--summarize/--no-summarize]
Multi-step: search → crawl → extract → embed → rerank → summarize.
omniscout graph
omniscout graph <entity> [--results K] [--website URL] [--data] [--no-llm]
Build a structured knowledge graph for a product, company, or person. Fetches
a small set of web sources (default 3), reranks passages, then synthesizes
a Unicode tree (Company, Founders, Category, Competitors, Models, Pricing,
Integrations, Features, Reviews, Documentation, News, …) via the local answer
LLM. Heuristic fallback when --no-llm or the model is unavailable.
Website mode — pass a URL as <entity> (cursor.com,
https://cursor.com) or pin a site with --website / -w. Skips DuckDuckGo;
BFS-crawls the seed URL and same-host links only (depth 2, up to --results
pages).
omniscout graph "Cursor"
omniscout graph "cursor.com"
omniscout graph "Cursor" --website cursor.com
OMNISCOUT_JSON=1 omniscout graph "Cursor" --data
| Flag | Default | Meaning |
|---|---|---|
--results, -k | 3 | DDG hits or in-site pages to fetch |
--website, -w | — | Crawl only this site + internal links |
--data | off | Sources, timing, retrieval mode |
--no-llm | off | Heuristic graph only (no local LLM) |
Human stdout is the tree. JSON output is a KnowledgeGraph object with
entity, nodes[] (nested name + children), sources[], and optional
data (elapsed_ms, retrieval, llm_backend).
Profiles (omniscout profile ...)
omniscout profile create <name>
omniscout profile list
omniscout profile delete <name>
Persistent Chrome user-data-dirs under
~/Library/Application Support/omniscout/profiles/<name>/. Login state and
cookies persist across runs.
Legacy sessions (omniscout session ...)
The pre-daemon long-lived browser session model. Still supported for direct CDP attach from other tools.
omniscout session start [--profile NAME] [--headful]
omniscout session list
omniscout session attach <SESSION_ID>
omniscout session kill [--id ID] [--all]
For agents, prefer the daemon model (--session NAME on every browser
command) over these.
Settings (omniscout settings ...)
View and change user settings in config.toml.
omniscout settings show
omniscout settings browsers
omniscout settings set browser <id> [--executable PATH]
Supported browser ids: chrome, edge, brave, vivaldi, opera, arc,
dia, thorium, chromium, custom. The custom id requires
--executable. settings browsers marks which ids are installed on this
machine and which one is current.
Environment override: OMNISCOUT_BROWSER=brave.
Install helper
omniscout install [--bundled] [--skill] [--browser ID] [--browser-executable PATH] [--print-data-dir]
--browser— write browser choice toconfig.tomlwithout prompting.--browser-executable— custom binary path (with--browser custom).--bundled— download Playwright's Chromium even if another browser exists.--skill— copySKILL.md+references/operations.mdinto~/.claude/skills/scout/,~/.cursor/skills-cursor/scout/,~/.codex/skills/scout/, and~/.gemini/config/skills/scout/.--print-data-dir— print the resolved data directory and exit.
Response envelope
Every command returns the same envelope. On success:
{
"ok": true,
"action": "click",
"data": {
"mode": "selector",
"tag": "BUTTON",
"text": "Sign in",
"snapshot_generation": 18
},
"elapsed_ms": 42,
"action_id": "8f3a7c9e1b2d4e5f"
}
The two cross-cutting fields agents should treat specially:
action_idis a stable hex ID for this exact invocation. Pass it todaemon trace,daemon replay, or correlate againstdaemon watchevents.data.snapshot_generationis a monotonic per-session counter that bumps whenever cached@eNrefs become invalid (snapshot,navigate,switch_tab,close_tabof the active tab). Re-snapshot if it differs from what your lastsnapshotreturned.
On failure:
{
"ok": false,
"action": "click",
"error": "ref @e9 not found (re-snapshot the page)",
"error_kind": "no_such_ref",
"elapsed_ms": 42,
"action_id": "8f3a7c9e1b2d4e5f"
}
Stable error_kind values agents can branch on:
| Kind | Meaning |
|---|---|
timeout | Operation exceeded its budget |
no_such_session | Session doesn't exist |
no_such_ref | @eN ref expired — re-snapshot |
backend_unavailable | Extension backend not connected |
invalid_args | Bad arguments |
internal | Unhandled error in the daemon |
requires_user | Human needed (captcha/login) |
unsupported | Backend doesn't implement this verb |
Environment variables
| Var | Purpose |
|---|---|
OMNISCOUT_JSON=1 | Force JSON output on every command |
OMNISCOUT_DAEMON_AUTO_START=0 | Don't auto-start the daemon on first call |
OMNISCOUT_DAEMON_PORT | Override the daemon's port (default 7720) |
OMNISCOUT_DATA_DIR | Override data dir (default ~/Library/Application Support/omniscout/) |
OMNISCOUT_CONFIG_DIR | Override config dir |
OMNISCOUT_CACHE_DIR | Override cache dir |
OMNISCOUT_EMBED_DAEMON=1 | Route embeds through daemon (default on) |
OMNISCOUT_EMBED_LOCAL_ONLY=0 | Allow runtime Hugging Face model fetches |
TWOCAPTCHA_API_KEY | API key for --solver 2captcha |
CAPSOLVER_API_KEY | API key for --solver capsolver |
Legacy OMNISCOUT_* names are accepted for all OMNISCOUT_* variables above.