# n8n-nodes-browser-cli An [n8n](https://n8n.io) community node, published on npm as [`n8n-nodes-browser-cli`](https://www.npmjs.com/package/n8n-nodes-browser-cli), that controls a **real, visible browser** from your workflows via [browser-cli](https://chromewebstore.google.com/detail/browser-cli/hekaebjhbhhdbmakimmaklbblbmccahp). browser-cli drives a running browser through a native-messaging host and a browser extension — it **cannot be installed inside the n8n container**. So this node speaks the `browser-cli serve` protocol **directly**: a length-framed TCP connection authenticated with an Ed25519 key, with request/response bodies encrypted end-to-end via an ML-KEM-768 (post-quantum) key exchange — the same wire protocol the `browser-cli --remote` client uses. ``` n8n workflow ──TCP (Ed25519 + ML-KEM-768)──▶ browser-cli serve (remote host) ──▶ browser ``` Because the payloads are end-to-end encrypted, the endpoint is safe to expose on an untrusted network without a TLS proxy in front of it. ## Remote setup (on the browser machine) Install browser-cli, register the extension, trust your n8n key, then start `serve` opening exactly the command tiers you need (it is **safe-only by default**): ```bash uv tool install real-browser-cli browser-cli install brave # one-time: register the extension/native host # On the n8n side, generate a client key and print its public key: browser-cli auth keygen -o n8n_key.pem # On the browser machine, trust that public key (optionally scope its policy): browser-cli auth trust --allow-control # Expose the browser. Open only what your workflow needs: browser-cli serve --host 0.0.0.0 --port 8765 \ --authorized-keys ~/.browser_cli/authorized_keys --allow-read-page --allow-control ``` Paste the contents of `n8n_key.pem` into the n8n credential. ## n8n credential — "Browser CLI API" | Field | Description | |-------|-------------| | Host | host of the `serve` endpoint, e.g. `browser-host.example` | | Port | `serve` TCP port (default `8765`) | | Ed25519 Private Key | PKCS8 PEM from `browser-cli auth keygen` (empty only for `--no-auth` loopback) | | Browser Alias | optional `_route` target — required if the endpoint serves multiple browsers | | Use TLS | wrap the connection in TLS (only for a TLS-terminating proxy; the protocol is already encrypted) | | Ignore SSL Issues | when TLS is on, accept a self-signed proxy cert | ## Operations Every operation maps to one raw browser-cli command, each subject to the server policy tier noted below. | Resource | Operation | Command | Server flag needed | |----------|-----------|---------|--------------------| | Tab | List | `tabs.list` | safe (default) | | Tab | Open | `navigate.open` | `--allow-control` | | Tab | Close | `tabs.close` (ids / inactive / duplicates) | `--allow-control` | | Tab | Get HTML | `tabs.html` | `--allow-read-page` | | Page | Get Info | `page.info` | safe (default) | | Page | Extract Text / Links / Images / HTML / Markdown | `extract.*` | `--allow-read-page` | | DOM | Query | `dom.query` | `--allow-read-page` | | DOM | Click / Type | `dom.click` / `dom.type` | `--allow-control` | | DOM | Eval | `dom.eval` | `--allow-dangerous` | | Client | List | `clients.list` | safe (default) | | Command | Execute | any command name + JSON args | per command | | Gateway | Health | pings with `tabs.list` | safe (default) | **Command → Execute** is the escape hatch: any command string the server policy allows (`tabs.query`, `session.save`, `windows.list`, …) with a JSON args object. Use it for anything the typed operations don't cover. > Note: `serve` returns the **raw** command result (no SDK post-processing). > `extract.markdown` therefore returns the page payload as the extension hands it > back, not the CLI's rendered Markdown. For clean text use **Extract Text**. ## Develop / build ```bash cd n8n-nodes-browser-cli npm install # add --ignore-scripts if a transitive native dep # (isolated-vm) fails to compile on your Node version npm test # pure unit tests: command mapping + crypto known-answer vectors npm run build # tsc -> dist/, copies the icon ``` Install the published package in n8n as a [community node](https://docs.n8n.io/integrations/community-nodes/installation/) using the package name `n8n-nodes-browser-cli`, or symlink `dist/` into `~/.n8n/custom` for local testing. ## License PolyForm Noncommercial License 1.0.0 — same as browser-cli.