{"id":50791544,"url":"https://github.com/operasoftware/opera-browser-cli","last_synced_at":"2026-06-12T11:30:52.736Z","repository":{"id":355598336,"uuid":"1224622764","full_name":"operasoftware/opera-browser-cli","owner":"operasoftware","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-10T10:00:38.000Z","size":680,"stargazers_count":22,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-10T11:16:43.021Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/operasoftware.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-29T13:13:47.000Z","updated_at":"2026-06-10T10:00:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/operasoftware/opera-browser-cli","commit_stats":null,"previous_names":["operasoftware/opera-cli"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/operasoftware/opera-browser-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operasoftware%2Fopera-browser-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operasoftware%2Fopera-browser-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operasoftware%2Fopera-browser-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operasoftware%2Fopera-browser-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/operasoftware","download_url":"https://codeload.github.com/operasoftware/opera-browser-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operasoftware%2Fopera-browser-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34243051,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-12T11:30:51.357Z","updated_at":"2026-06-12T11:30:52.731Z","avatar_url":"https://github.com/operasoftware.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eopera-browser-cli\u003c/h1\u003e\n\n\u003ch3 align=\"center\"\u003eThe most agent-ergonomic browser automation\u003c/h3\u003e\n\n`opera-browser-cli` is a fork of [chrome-devtools-axi](https://github.com/kunchenguid/chrome-devtools-axi).\nIt wraps [opera-devtools-mcp](https://github.com/operasoftware/opera-devtools-mcp) with an [AXI](https://axi.md)-compliant CLI.\n\n- **Token-efficient** — TOON-encoded output cuts token usage ~40% vs raw JSON\n- **Combined operations** — one command navigates, captures, and suggests next steps\n- **Contextual suggestions** — every response includes actionable next-step hints\n\n## Quick Start\n\n```sh\nnpm install -g opera-browser-cli\nopera-browser-cli setup   # interactive wizard — run in a terminal where you can answer prompts\nopera-browser-cli open https://example.com\n```\n\nOnce installed, `open` navigates to a URL and returns a structured snapshot you can act on:\n\n```sh\n$ opera-browser-cli open https://example.com\npage: {title: \"Example Domain\", url: \"https://example.com\", refs: 1}\nsnapshot:\nRootWebArea \"Example Domain\"\n  heading \"Example Domain\"\n  paragraph \"This domain is for use in illustrative examples...\"\n  uid=1 link \"More information...\"\nhelp[1]:\n  Run `opera-browser-cli click @1` to click the \"More information...\" link\n\n$ opera-browser-cli click @1\npage: {title: \"IANA — IANA-Managed Reserved Domains\", refs: 12}\nsnapshot:\n...\n```\n\n### Opera AI features\n\nWith any Opera browser, you can use the built-in AI chat:\n\n```sh\nopera-browser-cli chat \"summarise this page\"       # ask the built-in AI about the current page\n```\n\n[Opera Neon](https://www.operaneon.com) additionally unlocks three advanced AI commands:\n\n```sh\nopera-browser-cli invoke-do \"book a table for 2\"   # let the AI perform a multi-step browsing task\nopera-browser-cli make \"a todo app in vanilla JS\"  # generate and open a webpage or mini-app\nopera-browser-cli research \"solid-state batteries\" # in-depth research across multiple sources\n```\n\nRun `opera-browser-cli setup` to get started, or `opera-browser-cli doctor` to check your configuration.\n\n## Install\n\nPrerequisites: **Node.js \u003e= 20**, **Opera** browser ([Opera Neon](https://www.operaneon.com) recommended for AI features).\n\n### npm (recommended)\n\n```sh\nnpm install -g opera-browser-cli\n```\n\nRun first-time setup — this is an interactive wizard, so run it in a terminal where you can answer prompts:\n\n```sh\nopera-browser-cli setup\n```\n\nThis detects Opera installations, lets you pick one, saves configuration to `~/.opera-browser-cli/config`, and installs the Claude Code skill to `~/.claude/skills/opera-browser-cli/SKILL.md`.\n\nVerify:\n\n```sh\nopera-browser-cli --version\nopera-browser-cli open https://example.com\n```\n\n### From source\n\n```sh\n# in this repo\nnpm install \u0026\u0026 npm run build \u0026\u0026 npm link\n```\n\nThen run `opera-browser-cli setup` as above.\n\n### Usage examples\n\n```sh\n# Basic navigation\nopera-browser-cli open https://example.com\n\n# Use Opera as the browser\nOPERA_CLI_EXECUTABLE_PATH=\"/Applications/Opera.app/Contents/MacOS/Opera\" \\\n  opera-browser-cli open https://example.com\n\n# Headed mode (visible browser window)\nOPERA_CLI_HEADED=1 opera-browser-cli open https://example.com\n\n# Persistent profile (stay logged in across sessions)\nOPERA_CLI_USER_DATA_DIR=~/.opera-profile opera-browser-cli open https://example.com\n\n# Connect to already-running browser\nOPERA_CLI_BROWSER_URL=http://127.0.0.1:9222 opera-browser-cli open https://example.com\n```\n\n## How It Works\n\n```\n┌───────────────────────┐\n│  opera-browser-cli    │  CLI — parse args, format output\n└──────────┬────────────┘\n           │ HTTP (localhost:9225)\n           ▼\n┌───────────────────────┐\n│     Bridge Server     │  Persistent process, manages MCP session\n└──────────┬────────────┘\n           │ stdio\n           ▼\n┌───────────────────────┐\n│  opera-devtools-mcp   │  Headless Chrome via DevTools Protocol\n└───────────────────────┘\n```\n\n- **Persistent bridge** — a detached process keeps the MCP session alive across commands, so Chrome doesn't restart every invocation\n- **Auto-lifecycle** — the bridge starts on first command and writes a PID file to `~/.opera-browser-cli/bridge.pid`\n- **Snapshot parsing** — accessibility tree snapshots are extracted and analyzed for interactive elements (`uid=` refs)\n- **TOON encoding** — structured metadata uses [TOON format](https://www.npmjs.com/package/@toon-format/toon) for compact, token-efficient output\n\n## CLI Reference\n\n### Navigation\n\n| Command           | Description                                  |\n|-------------------|----------------------------------------------|\n| `open \u003curl\u003e`      | Navigate to URL and snapshot                 |\n| `snapshot`        | Capture current page state                   |\n| `screenshot \u003cp\u003e`  | Save a screenshot to a file                  |\n| `scroll \u003cdir\u003e`    | Scroll: up, down, top, bottom                |\n| `back`            | Navigate back                                |\n| `wait \u003cms\\|text\u003e` | Wait for time or text to appear              |\n| `eval \u003cjs\u003e`       | Evaluate a JavaScript expression or function |\n| `run`             | Execute a multi-step script from stdin       |\n\n`eval` wraps plain input as `() =\u003e (\u003cexpr\u003e)` before sending it to DevTools. For multi-statement logic, pass an arrow function, `function`, or IIFE yourself.\n\n```sh\nopera-browser-cli eval \"document.title\"\nopera-browser-cli eval \"(() =\u003e { const rows = [...document.querySelectorAll('tr')]; return rows.map((row) =\u003e row.textContent) })()\"\n```\n\n### Interaction\n\n| Command                    | Description                    |\n|----------------------------|--------------------------------|\n| `click @\u003cuid\u003e`             | Click an element by ref        |\n| `fill @\u003cuid\u003e \u003ctext\u003e`       | Fill a form field              |\n| `type \u003ctext\u003e`              | Type text at current focus     |\n| `press \u003ckey\u003e`              | Press a keyboard key           |\n| `hover @\u003cuid\u003e`             | Hover over an element          |\n| `drag @\u003cfrom\u003e @\u003cto\u003e`       | Drag an element onto another   |\n| `fillform @\u003cuid\u003e=\u003cval\u003e...` | Fill multiple form fields      |\n| `dialog \u003caccept\\|dismiss\u003e` | Handle a browser dialog        |\n| `upload @\u003cuid\u003e \u003cpath\u003e`     | Upload a file through an input |\n\n### Page Management\n\n| Command           | Description                 |\n|-------------------|-----------------------------|\n| `pages`           | List all open tabs          |\n| `newpage \u003curl\u003e`   | Open a new tab              |\n| `selectpage \u003cid\u003e` | Switch to a tab by ID       |\n| `closepage \u003cid\u003e`  | Close a tab by ID           |\n| `resize \u003cw\u003e \u003ch\u003e`  | Resize the browser viewport |\n\n### Emulation\n\n| Command   | Description                     |\n|-----------|---------------------------------|\n| `emulate` | Emulate device/network/viewport |\n\n### DevTools Debugging\n\n| Command            | Description                    |\n|--------------------|--------------------------------|\n| `console`          | List console messages          |\n| `console-get \u003cid\u003e` | Get a specific console message |\n| `network`          | List network requests          |\n| `network-get [id]` | Get a specific network request |\n\n### Performance\n\n| Command                     | Description                   |\n|-----------------------------|-------------------------------|\n| `lighthouse`                | Run a Lighthouse audit        |\n| `perf-start`                | Start a performance trace     |\n| `perf-stop`                 | Stop the performance trace    |\n| `perf-insight \u003cset\u003e \u003cname\u003e` | Analyze a performance insight |\n| `heap \u003cpath\u003e`               | Capture a heap snapshot       |\n\n### Opera AI\n\n| Command              | Description                                   | Requires   |\n|----------------------|-----------------------------------------------|------------|\n| `chat \u003cprompt\u003e`      | Send a chat message to Opera's built-in AI    | Any Opera  |\n| `invoke-do \u003cprompt\u003e` | Ask the AI to perform a complex browsing task | Opera Neon |\n| `make \u003cprompt\u003e`      | Ask the AI to build a webpage or app          | Opera Neon |\n| `research \u003cprompt\u003e`  | Ask the AI to research a topic in depth       | Opera Neon |\n\n`research` accepts `--type local` (default), `--type one-minute`, or `--type deep`.\n\n### Configuration\n\n| Command  | Description                                      |\n|----------|--------------------------------------------------|\n| `setup`  | Interactive first-time setup (browser path, etc) |\n| `doctor` | Check configuration and environment              |\n| `logs`   | Show bridge server logs                          |\n\n### Bridge\n\n| Command | Description             |\n|---------|-------------------------|\n| `start` | Start the bridge server |\n| `stop`  | Stop the bridge server  |\n\nRunning with no command shows the CLI home view. It prepends `bin` and\n`description` metadata, then includes the current snapshot when a browser\nsession is active or the no-session status/help block when one is not.\n\n### Flags\n\n| Flag                        | Description                                 |\n|-----------------------------|---------------------------------------------|\n| `--help`                    | Show usage information                      |\n| `-v`, `-V`, `--version`     | Show the installed CLI version              |\n| `--full`                    | Show complete output without truncation     |\n| `--background`              | Open new page in background (newpage)       |\n| `--uid @\u003cuid\u003e`              | Target a specific element (screenshot)      |\n| `--full-page`               | Capture entire scrollable page (screenshot) |\n| `--format \u003cfmt\u003e`            | Image format: png, jpeg, webp (screenshot)  |\n| `--viewport \u003cspec\u003e`         | Viewport like \"390x844x3,mobile\" (emulate)  |\n| `--color-scheme \u003cvalue\u003e`    | dark, light, or auto (emulate)              |\n| `--network \u003ccondition\u003e`     | Network throttle: Slow 3G, etc. (emulate)   |\n| `--cpu \u003crate\u003e`              | CPU throttling rate 1-20 (emulate)          |\n| `--geolocation \u003clat\u003ex\u003clon\u003e` | Set geolocation (emulate)                   |\n| `--user-agent \u003cstring\u003e`     | Custom user agent (emulate)                 |\n| `--type \u003ctype\u003e`             | Filter by type (console, network)           |\n| `--limit \u003cn\u003e`               | Max items to return (console, network)      |\n| `--page \u003cn\u003e`                | Pagination (console, network)               |\n| `--device \u003cdevice\u003e`         | desktop or mobile (lighthouse)              |\n| `--mode \u003cmode\u003e`             | navigation or snapshot (lighthouse)         |\n| `--output-dir \u003cpath\u003e`       | Directory for reports (lighthouse)          |\n| `--no-reload`               | Skip page reload (perf-start)               |\n| `--no-auto-stop`            | Disable auto-stop (perf-start)              |\n| `--file \u003cpath\u003e`             | Save trace data to file (perf-start/stop)   |\n| `--response-file \u003cpath\u003e`    | Save response body (network-get)            |\n| `--request-file \u003cpath\u003e`     | Save request body (network-get)             |\n\n## Configuration\n\n| Variable                    | Default                          | Purpose                                                          |\n|-----------------------------|----------------------------------|------------------------------------------------------------------|\n| `OPERA_CLI_PORT`            | `9225`                           | Bridge server port                                               |\n| `OPERA_CLI_MCP_BIN`         | _(bundled `opera-devtools-mcp`)_ | Override the MCP server binary                                   |\n| `OPERA_CLI_EXECUTABLE_PATH` | _(system Chrome)_                | Custom browser binary                                            |\n| `OPERA_CLI_BROWSER_URL`     | —                                | Connect to an existing browser instance instead of launching one |\n| `OPERA_CLI_USER_DATA_DIR`   | —                                | Persistent Chrome profile directory (skips isolated mode)        |\n| `OPERA_CLI_HEADED`          | —                                | Set to `1` to run in headed (visible) mode                       |\n| `OPERA_CLI_CHROME_ARGS`     | —                                | Extra Chrome flags, space-separated                              |\n| `OPERA_CLI_DISABLE_HOOKS`   | —                                | Set to `1` to skip auto-installing session hooks                 |\n\nState is stored in `~/.opera-browser-cli/`:\n\n| File         | Purpose                            |\n|--------------|------------------------------------|\n| `bridge.pid` | PID and port of the running bridge |\n\n### Session Hooks\n\nOn supported agents, the packaged CLI also installs a `SessionStart` hook in `~/.claude/settings.json` and `~/.codex/hooks.json`, and enables `codex_hooks` in `~/.codex/config.toml`.\n\nSet `OPERA_CLI_DISABLE_HOOKS=1` to skip that auto-install behavior.\n\nDevelopment entrypoints such as `npm run dev` and `bin/opera-browser-cli.ts` do not modify those hook files.\n\n## Docker / OpenClaw\n\nA ready-made Docker setup runs `opera-browser-cli` as a tool inside an\n[OpenClaw](https://openclaw.ai) agent gateway, with a headless Chrome sidecar handling\nthe browser. No local browser or Node.js install is required on the host — Docker is\nthe only prerequisite. The skill is registered automatically so OpenClaw agents can\ninvoke `opera-browser-cli` commands directly.\n\nThe `docker/` directory ships with the npm package:\n\n```sh\ncd \"$(npm root -g)/opera-browser-cli/openclaw\"\n```\n\nSee [`openclaw/README.md`](openclaw/README.md) for the full setup guide.\n\n## Local Setup (Full Stack)\n\nBoth `opera-devtools-mcp` and `opera-browser-cli` need to be built and linked so they're available in PATH.\n\n**1. Build and link `opera-devtools-mcp`:**\n\n```sh\n# in the opera-devtools-mcp repo\nnpm install\nnpm run build\nnpm link\n```\n\n**2. Build and link `opera-browser-cli`:**\n\n```sh\n# in this repo\nnpm install\nnpm run build\nnpm link\n```\n\n**3. Set the browser executable path:**\n\n```sh\nexport OPERA_CLI_EXECUTABLE_PATH=\"/Applications/Opera Neon.app/Contents/MacOS/Opera\"\n```\n\n**Tip:** Set `OPERA_CLI_MCP_BIN` to point to the locally linked `opera-devtools-mcp`:\n\n```sh\nexport OPERA_CLI_MCP_BIN=opera-devtools-mcp\n```\n\n**Tip:** Set `OPERA_CLI_HEADED=1` to launch the browser in headed (visible) mode — useful during development to watch what's happening:\n\n```sh\nexport OPERA_CLI_HEADED=1\n```\n\n## Benchmarks\n\n### Page Snapshot\n\nRuns snapshot command on 50 static pages (Wikipedia, GitHub, MDN, Python docs, RFC Editor) and counts output tokens via tiktoken. No LLM involved — purely mechanical measurement.\n\n**Results (50 runs each):**\n\n| Condition       | Avg tokens | Median tokens | p95 tokens |\n|-----------------|------------|---------------|------------|\n| `opera-compact` | 60.6k      | 24.3k         | 256.1k     |\n| `mcp-raw`       | 94.7k      | 45.0k         | 391.3k     |\n| `opera-raw`     | 94.9k      | 45.1k         | 381.4k     |\n| `axi`           | 98.5k      | 46.6k         | 396.9k     |\n\n`--full` variants (no char limit) are also measured; see the [detailed README](page-token-benchmark/README.md) and [results report](page-token-benchmark/results/report.md).\n\n---\n\n### Agentic Use\n\nAn LLM agent completes 7 browser tasks (adapted from the [axi bench-browser benchmark](https://github.com/kunchenguid/axi/tree/main/bench-browser)) across 4 conditions. Each run is graded pass/fail by an LLM judge. Captures input tokens, snapshot size, wall time, and tool call count.\nThe agent was selecting each tool with or without `--full` flag, depending on the context. \n\n**Results (35 runs each, 5 repeats × 7 tasks):**\n\n| Condition     | Pass [%] | Avg input length [tokens] | Avg snapshot length [chars] | Avg task time [seconds] | Avg tool calls |\n|---------------|----------|---------------------------|-----------------------------|-------------------------|----------------|\n| opera-compact | 100%     | 36.3k                     | 83.1k                       | 6.8                     | 1.4            |\n| opera-raw     | 100%     | 107.5k                    | 198.1k                      | 8.5                     | 1.6            |\n| axi           | 100%     | 102.2k                    | 203.9k                      | 9.8                     | 1.5            |\n| mcp-raw       | 100%     | 179.2k                    | 218.7k                      | 9.4                     | 2.1            |\n\n\u003e opera-compact saves **80%** total tokens vs mcp-raw baseline.\n\nSee the [detailed README](snapshot-agentic-use/README.md) and [results report](snapshot-agentic-use/results/v6/report.md).\n\n---\n\n## Development\n\n```sh\nnpm run build      # Compile TypeScript to dist/\nnpm run dev        # Run CLI directly with tsx\nnpm test           # Run tests with vitest\nnpm run test:watch # Run tests in watch mode\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foperasoftware%2Fopera-browser-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foperasoftware%2Fopera-browser-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foperasoftware%2Fopera-browser-cli/lists"}