Remote Browser CLI
The remote-browser CLI is the command-line client bundled with the Sa2web MCP project. It starts the same MCP server over stdio and translates commands into sa2_* or browser_* tool calls. Use it for manual testing, automation scripts, and connectivity checks.
The project is open source at sa2web/sa2web-mcp and published on npm as @sa2web/mcp. A global install exposes three entries:
sa2: recommended CLI command.sa2-browser: compatibility alias forsa2.sa2-mcp: stdio server entry for MCP clients.
Prepare the CLI
Install the npm package globally:
npm install @sa2web/mcp -g
npx playwright install --with-depsThen run:
sa2 help
sa2-browser helpsa2-mcp is meant to be launched by an MCP client over stdio, so you normally do not run it manually.
For source development, clone the repository and build it:
git clone https://github.com/sa2web/sa2web-mcp.git
cd sa2web-mcp
npm install
npx playwright install --with-deps
npm run build
# Run the TypeScript source during development
npm run cli -- help
# Run the compiled file
node dist/cli.js help
# Use a bin entry after npm link or npm install -g .
sa2 help
sa2-browser helpThe child MCP server inherits the CLI process environment. At minimum, configure SA2_LOGIN_URL:
export SA2_LOGIN_URL='https://<APP_DOMAIN>/agent/login?clientId=...&clientSecret=...'
sa2 targetsSet SA2_IGNORE_HTTPS_ERRORS=false if you need strict HTTPS certificate validation. It defaults to true, which ignores certificate errors from the target site or remote-browser page.
Credential safety
The login URL normally contains clientSecret. Keep the real URL out of shell history, source-controlled scripts, and CI logs. Use protected environment variables or secret management in production.
One-shot commands and persistent shell
Each direct sa2 <command> invocation starts and then closes its own MCP server. A command that needs page state must therefore include --url, --target-id, or another target selector.
Use sa2 shell for a sequence of operations on the same browser session. repl is an alias. Snapshot refs remain available to later commands in that shell:
sa2> open https://example.com
sa2> snapshot
sa2> click --ref e3
sa2> type --selector '#email' --text hello@example.com
sa2> press Enter
sa2> wait --url-includes dashboard
sa2> screenshot --output page.png
sa2> exitUse exit or quit to leave. When a page command has no target and the session has not opened a page, the CLI opens SA2_LOGIN_URL first.
Command reference
| Command | Purpose | Common arguments |
|---|---|---|
help | Show usage | --help and -h also work |
shell / repl | Start a persistent session | exit or quit to leave |
targets | List proxies and saved targets | none |
open | Open a public or saved target | --url, --target-id, --type, --id, --name, --surf, --wait-until |
workspace / saas / inner | Saved-target shortcuts | ID or name |
snapshot | Return a semantic snapshot and refs | --filter <css> plus target arguments |
text | Extract visible text | --selector <css> plus target arguments |
click | Click an element or coordinates | --ref, --selector, --role, --name, text, --x, --y |
type | Fill or type text | required --text; locator arguments, --press-enter, --append |
paste | Paste text, HTML, RTF, or files | --text, --html, --rtf, repeatable --path, locator arguments |
press | Press a keyboard key | positional key or --key |
wait | Wait for time, text, element, or URL | --ms, --text, --selector, --url-includes |
scroll | Scroll the page or an element | direction, --amount, --mode, locator arguments, --x, --y |
device / toggle-device | List device presets or switch desktop/mobile emulation | list, preset, --enabled, orientation, dimensions, DPR, touch, UA, --reload |
screenshot | Save a PNG file | --output, --full-page, plus target arguments |
back / forward / reload | Control navigation | none |
close | Close the browser session | none |
tool | Call any MCP tool directly | tool name and a --json object |
Use --headless true or --headless false when starting the CLI to override SA2_HEADLESS for that process. For a persistent session, set it on startup, for example sa2 shell --headless true; changing it inside the shell does not restart the browser.
Open targets
Public URLs:
sa2 open https://example.com
sa2 open --url https://example.com --surf direct
sa2 open cloud https://example.com --wait-until domcontentloadedSaved targets:
sa2 targets
sa2 open --target-id workspace:123
sa2 open workspace 123
sa2 workspace 123
sa2 saas GitHub
sa2 inner 7
sa2 open --type saas --name GitHubPrefer the stable targetId returned by targets. Name matching is case-insensitive, but an ID avoids ambiguity.
Inspect and interact
Commands below that omit a target assume an already-open page in the persistent shell. Add --url or --target-id when running them as one-shot commands.
sa2 snapshot --url https://example.com
sa2 snapshot --url https://example.com --filter 'main article'
sa2 text --url https://example.com --selector 'main'Use actionable ref=eN values from snapshot. Values such as id=tN and context=[tN] are snapshot text references, not refs or CSS selectors.
sa2 click --ref e3
sa2 click --selector 'button[type=submit]'
sa2 click --role button --name Save
sa2 click 'Learn more'
sa2 click --x 420 --y 260
sa2 type --selector '#email' --text hello@example.com
sa2 type --ref e5 --text 'new value' --press-enter
sa2 type --selector textarea --text 'more text' --append
sa2 press Enter
sa2 wait --ms 1000
sa2 wait --text Ready
sa2 wait --selector '.result'
sa2 wait --url-includes dashboardFor a one-shot command with --ref, the CLI first takes a snapshot so the server can resolve that ref. In a persistent shell, the latest snapshot refs are reused.
Paste and scroll
sa2 paste --selector '[contenteditable]' --html '<b>Hello</b>'
sa2 paste --selector '.paste-zone' --path image.png
sa2 paste --selector 'input[type=file]' --path a.png --path b.pdf
sa2 scroll down --amount 800
sa2 scroll top
sa2 scroll --ref e8 --mode intoView
sa2 scroll --mode to --x 0 --y 1200Switch devices
sa2 device list
sa2 device ls
sa2 device 'Pixel 7'
sa2 device 'iPhone 13' --orientation landscape --reload
sa2 device --preset 'iPad Mini' --width 1024 --height 768
sa2 device --enabled true --device-scale-factor 3 --has-touch true
sa2 device Desktoptoggle-device is an alias of device. The positional preset, --device, or --preset maps to the MCP device argument. Other mappings are --device-scale-factor to deviceScaleFactor, --has-touch to hasTouch, and --user-agent to userAgent. Use --orientation portrait|landscape and --reload as needed.
Device switching needs a page session. Prefer switching after opening the target inside sa2 shell, which preserves cookies and login state. Take a new snapshot after switching. sa2 device Desktop restores desktop mode.
Screenshot
sa2 screenshot --url https://example.com --output page.png
sa2 screenshot --output full.png --full-pageThe default screenshot filename is screenshot.png. Repeating --path creates a file list.
Call a raw MCP tool
The tool command covers MCP tools without CLI shortcuts. --json must contain a JSON object:
sa2 tool browser_resize --json '{"width":1280,"height":720}'
sa2 tool browser_handle_dialog --json '{"accept":true}'
sa2 tool browser_hover --json '{"selector":".menu"}'Use single quotes around JSON in Bash or zsh; PowerShell quoting differs. Obtain explicit user confirmation before publishing, submitting, deleting, purchasing, authorizing, transferring money, or sending messages.
Argument rules
- Both
--key valueand--key=valueare accepted. - A valueless flag such as
--press-entermeanstrue; booleans also accepttrueandfalse. --no-<key>sets that option tofalse.- Repeated options such as
--pathbecome arrays. - Shell mode supports single quotes, double quotes, and backslash escaping.
Troubleshooting
| Symptom | Resolution |
|---|---|
Unknown command | Run sa2 help and check the command name |
dist/server.js is missing | Reinstall @sa2web/mcp, or run npm run build when using a source checkout |
SA2_LOGIN_URL is not configured | Export it in the current terminal or inject it through the runtime |
| A one-shot ref targets the wrong page | Use sa2 shell, or pass --url / --target-id to the command |
| A target is missing | Run sa2 targets, use its targetId, and check account permissions |
| An element is missing | Take a fresh snapshot and use the latest ref=eN or a real CSS selector |
| A screenshot cannot be saved | Check write permission for the --output directory |