@thinkrun/cli
v0.1.39
Published
CLI for controlling browsers via ThinkRun cloud and local infrastructure
Maintainers
Readme
@thinkrun/cli
CLI for ThinkRun browser automation.
thinkrun is the single CLI for controlling browsers via ThinkRun cloud and local (native host) infrastructure.
Requirements
- Node.js 18+ (uses native
fetch)
OS Support
- macOS, Linux, Windows
Installation
npm install -g @thinkrun/cli # works with npm, bun, pnpm, yarn
thinkrun setup # download native host + register the ThinkRun browser extensionInstall directly from this repository on your machine:
npm install -g /path/to/mech-browse/packages/cli
thinkrun setupCustom Chromium data directories
On Linux and macOS, register the native host for the exact directory passed to
Chromium's --user-data-dir:
thinkrun install --user-data-dir "/absolute/path/Chromium data" --extension-id <extension-id>
thinkrun install --check --user-data-dir "/absolute/path/Chromium data"Use the data directory itself, not its Default or Profile 1 subdirectory.
The installer writes NativeMessagingHosts/com.thinkbrowse.host.json there,
creates the directory if needed, and preserves previously allowed extension IDs.
With this option, registration and inspection target only that directory; the
binary is still installed in ~/.thinkbrowse/bin. Without it, standard browser
registration works as before. Windows uses registry registration and does not
support this option.
Chromium's path provider resolves user native messaging manifests from the active user data directory. Register each custom directory separately, then reconnect or reload the ThinkRun extension if it previously reported a missing native host.
Quick Start
# 1. Install native host and configure API key
thinkrun setup
# 2. Configure API key (if not done during setup)
thinkrun config set-key tb_your_api_key_here
# 3. Start a cloud browser session (waits for provisioning)
thinkrun cloud start
# 4. Navigate and interact
thinkrun navigate "https://example.com"
thinkrun snapshot # Get accessibility tree
thinkrun click "button.submit"
thinkrun screenshot --output page.png
# 5. Stop the session
thinkrun cloud stopStateless page cache (no session)
One-shot HTML, text, or screenshot via POST /api/cache/* (uses your configured API URL and key — same as cloud commands):
thinkrun cache text https://example.com --json
thinkrun cache html https://example.com --provider local --sensitive
thinkrun cache screenshot https://example.com --jsonLocal Endpoint Quick Start (mech-browser-service)
# 1. Point CLI at local server
thinkrun config set apiUrl http://localhost:3009
# 2. Use local TEST_API_KEY from mech-browser-service/.env (often ak_...)
thinkrun config set-key ak_your_local_test_key
# 3. Start/select session, then run actions
thinkrun cloud start
thinkrun navigate http://localhost:3000Use thinkrun doctor anytime to verify endpoint mode, health, bridge status, and active session.
When changing CLI behavior in this repository, use the agent DX release checklist in docs/AGENT_CLI_DX_CHECKLIST.md. Parity-sensitive CLI/MCP screenshot and observation claims are backed by docs/mcp-cli-parity-evidence.md.
Local Audit Mode
Audit mode is a local-only capture toggle for attached Chromium tabs. When enabled, ThinkRun attempts an extra screenshot after each state-changing action so the Activity Feed and session detail page show an audit trail without requiring manual screenshot calls.
thinkrun tabs
thinkrun attach <tabId>
thinkrun audit on
thinkrun navigate "https://example.com"
thinkrun click "a.more"
thinkrun audit status
thinkrun audit offRules:
thinkrun audit on|off|statusoperates on the current attached local tab- audit mode only applies to local attached-tab sessions, not cloud sessions
- with an accepted API key,
attachandnew-windowcreate or recover a durable Activity Feed session before returning;audit onthen syncs the audit state to that session - persistence is bounded and best effort: local browser control still succeeds if the API is unavailable, while human and JSON output report whether the Activity Feed is connected
thinkrun doctorchecks both public API health and protected API-key acceptance; use it when a local session is missing from the Activity Feed- observation commands (
extract,evaluate,snapshot,url,title,html,console,network,wait) do not trigger audit screenshots - screenshots are fire-and-forget best effort; browser actions do not fail just because audit capture fails
- explicit precedence is:
--auditattach flag >THINKRUN_AUDITenv var > stored per-tab toggle
AI Agent Workflow
The snapshot command returns an accessibility tree — ideal for AI agents that need to understand page structure without screenshots:
thinkrun cloud start
thinkrun navigate "https://github.com/trending"
thinkrun snapshot # Returns accessibility tree
thinkrun click "a.repo-name" # AI decides what to click
thinkrun wait-for-text "README" # Wait for content
thinkrun extract "article" --format json
thinkrun cloud stopCommands
Session Management
| Command | Description |
|---------|-------------|
| cloud start | Start a new cloud browser session |
| cloud stop | Stop the active session |
| cloud list | List all active sessions |
| cloud status | Show session details |
| cloud artifacts | List session artifacts (screenshots, logs, actions) |
| cloud use <id> | Switch active session |
| doctor | Diagnose endpoint/auth/session setup |
| audit on|off|status | Enable, disable, or inspect local audit mode for the attached tab |
Recording upload
Upload an explicit local video for ThinkRun analysis without using the extension bridge:
thinkrun recording upload ./walkthrough.webm --intent feedback --title "Checkout issue" --url https://example.com
thinkrun recording upload ./walkthrough.webm --dry-runOnly regular readable .webm, .mp4, and .mov files up to 5 GiB are accepted. The command creates a recording, uploads directly with the service-provided presign when available, then finalizes analysis; it falls back to the authenticated recording stream only when direct upload is unavailable. --dry-run validates locally and makes no API request.
Cloud Start Options
thinkrun cloud start [options]
Options:
-b, --browser <type> Browser: chromium (default), firefox, webkit
--proxy Enable proxy rotation
--stealth Enable anti-detection mode
--no-wait Return immediately without waiting for readyNavigation
| Command | Description |
|---------|-------------|
| navigate <url> | Navigate to a URL |
| back | Go back in browser history |
| forward | Go forward in browser history |
thinkrun navigate "https://example.com" --wait-until networkidle
thinkrun back
thinkrun forwardnavigate, evaluate, screenshot, snapshot, click, and related browser actions run against:
- the attached local tab after
thinkrun attach <tabId> - a cloud session after
thinkrun cloud startorthinkrun cloud use <id>
Use --mode local or --mode cloud to override persisted context for a single command.
thinkrun attach <tabId> --audit enables audit mode immediately for that attached local tab.
Interaction
| Command | Description |
|---------|-------------|
| click <selector> | Click an element |
| type <selector> <text> | Append text to an editable element; use --clear to replace and --delay <ms> (0–5000) for per-character delay |
| fill <selector> <value> | Replace the content of an editable element |
| press <key> | Press keyboard key |
| scroll | Scroll the page |
| hover <selector> | Hover over element |
| select <selector> <value> | Select dropdown option |
thinkrun fill "#email" "[email protected]"
thinkrun fill "#password" "secret123"
thinkrun type "[contenteditable=true]" "Draft text" --clear --delay 25
thinkrun press Enter
thinkrun click ".submit-btn" --timeout 5000
thinkrun hover ".dropdown-trigger"
thinkrun select "#country" "US"
thinkrun scroll --down 500
thinkrun scroll --to "#footer"type and fill accept enabled, rendered text inputs, textareas, and
contenteditable elements. Local extension mode also supports elements with
role="textbox"; cloud mode follows Playwright's editable-element rules. type
appends by default, while --clear uses replacement semantics. Both modes reject
missing, hidden, disabled, or non-editable targets instead of reporting success.
The per-character delay must be an integer from 0 through 5000 milliseconds.
Waiting
| Command | Description |
|---------|-------------|
| wait <condition> | Wait for element or time (ms) |
| wait-for-text <text> | Wait for text on page |
thinkrun wait 2000 # Wait 2 seconds
thinkrun wait ".loading-complete" # Wait for element
thinkrun wait ".spinner" --hidden # Wait for element to hide
thinkrun wait-for-text "Success" --timeout 10000 # Wait for textObservation
| Command | Description |
|---------|-------------|
| snapshot | Get accessibility tree |
| screenshot | Capture screenshot (--caption required when syncing a local session to ThinkRun) |
| extract <selector> | Extract content from elements |
| evaluate [script] | Execute JavaScript in page |
| url | Get the current page URL (cloud) |
| title | Get the current page title (cloud) |
| html | Get the full page HTML (cloud) |
thinkrun snapshot
thinkrun screenshot --output page.png --full-page
thinkrun extract "h1"
thinkrun extract ".item" --all --format json
thinkrun extract "a" --attr href --all
thinkrun evaluate "document.title"
thinkrun evaluate --file script.js
thinkrun url
thinkrun title
thinkrun html > page.htmlIf a local tab is already synced into ThinkRun, extract and evaluate results now show up in the dashboard session detail as per-action Result panels. This is display-only documentation for the existing sync path; it does not add a new CLI command or flag.
If a local tab is already synced into the Activity Feed, screenshots must include an explicit caption so the dashboard reflects the agent's intent:
thinkrun screenshot --caption "Checkout confirmation before submit" --output page.pngDialog Handling
| Command | Description |
|---------|-------------|
| dialog get | Check for pending dialog |
| dialog accept [text] | Accept dialog |
| dialog dismiss | Dismiss dialog |
thinkrun dialog get # Check for alerts/confirms/prompts
thinkrun dialog accept # Accept alert/confirm
thinkrun dialog accept "my answer" # Accept prompt with text
thinkrun dialog dismiss # Dismiss/cancel dialogMonitoring
| Command | Description |
|---------|-------------|
| console | Get browser console messages |
| network | Get in-page fetch/XHR requests observed in the active tab |
| clear-logs | Clear console and network logs (cloud) |
thinkrun console # View console.log, warnings, errors
thinkrun network # View network requests
thinkrun clear-logs # Reset logs for the active sessionLocal Mode (Native Host)
These commands require the native host to be running (thinkrun doctor will confirm).
In local mode, network reflects the in-page requests the extension observes from the active tab. Top-level navigations may not appear until the page itself issues fetch/XHR traffic after the interceptors are active.
| Command | Description |
|---------|-------------|
| tabs | List open tabs in your Chromium-based browser |
| new-tab [url] | Open a new local browser tab without rebinding the active session |
| close-tab [tabId] | Close a local browser tab (defaults to the attached tab) |
| attach <tabId> | Attach to a tab and set it as the active session |
| switch-tab <tabId> | Switch the active tab in your Chromium-based browser without changing session config |
| focus | Bring the attached tab's browser window to the foreground |
| new-window [url] | Open a new local window and auto-attach to it |
| release | Release the local session lock and close the synced CLI session |
# List all open tabs
thinkrun tabs
# Open a new background tab, inspect it, then close it
thinkrun new-tab https://example.com
thinkrun tabs
thinkrun close-tab 12345
# Attach to a specific tab by ID, then run actions against it
thinkrun attach 12345
thinkrun snapshot
thinkrun navigate "https://example.com"
# Switch which tab is active in your Chromium-based browser without updating the session config
thinkrun switch-tab 12345If attach succeeds but a later browser action still reports a session error, run thinkrun session debug --json. That output distinguishes persisted local tab binding, working-location lock, and cloud session context.
Configuration
thinkrun config set-key <api-key> # Set API key
thinkrun config show # Show current config
thinkrun config set apiUrl <url> # Set custom API URL
thinkrun config set defaultBrowser firefox
thinkrun config reset # Reset all configConfig file: ~/.config/thinkrun/config.json
Global Options
--json— Force JSON output (auto-enabled for non-TTY)--quiet— Suppress non-error output--verbose— Show debugging info
Examples
Web Scraping
thinkrun cloud start
thinkrun navigate "https://news.ycombinator.com"
thinkrun extract ".titleline > a" --all --format json > titles.json
thinkrun screenshot --output hn.png
thinkrun cloud stopForm Automation
thinkrun cloud start
thinkrun navigate "https://example.com/login"
thinkrun fill "#email" "[email protected]"
thinkrun fill "#password" "secret123"
thinkrun click "button[type=submit]"
thinkrun wait-for-text "Dashboard"
thinkrun screenshot --output logged-in.png
thinkrun cloud stopDebugging a Page
thinkrun cloud start
thinkrun navigate "https://myapp.com"
thinkrun console # Check for JS errors
thinkrun network # Check failed requests
thinkrun snapshot # See page structure
thinkrun url # Confirm current URL
thinkrun title # Confirm page title
thinkrun cloud stopError Handling
The CLI returns structured errors with suggestions:
Error: API key not configured
Tip: Run: thinkrun config set-key <your-api-key>Retryable errors (502, 503) are automatically retried with exponential backoff.
Troubleshooting
| Issue | Solution |
|-------|----------|
| API key not configured | Run thinkrun config set-key <key> |
| Invalid API key (local URL) | Use local TEST_API_KEY from mech-browser-service/.env |
| No active session | Run thinkrun cloud start, or thinkrun cloud list then thinkrun cloud use <id> |
| Session provisioning timed out | Check thinkrun cloud status, try again |
| fetch is not defined | Upgrade to Node.js 18+ |
| All requests return 404 | Update to latest CLI version |
License
MIT
