borz

n8n community node for borz (control Chrome via CDP over HTTP).

Package Information

Downloads: 3 weekly / 148 monthly
Latest Version: 0.3.0
Author: leolin310148

Documentation

n8n-nodes-borz

n8n community node for borz.
Drive a real Chromium instance from an n8n workflow by talking to a running
borz server over its /v1/* HTTP API.

Renamed from @leolin310148/n8n-nodes-bb-browser. Existing workflows
continue to work — internal node and credential identifiers are unchanged.
See RENAME_PLAN.md for the full migration story.

Shape

  • Declarative node (one file, pure routing) — every operation is a 1:1 map to a
    /v1/* endpoint, so new server endpoints can be added with a few lines.
  • One credential type (borz API): base URL + optional bearer token.
    Credentials test hits /healthz.
  • Script resource gives two escape hatches:
    • Execute JavaScript — raw /v1/eval pass-through.
    • Run Inline Adapter — paste an arrow function + JSON args; the node wraps it
      as (fn)(args) (same convention as borz's on-disk site adapters) before
      sending to /v1/eval.

Resources / Operations

Resource Operations
Page Open URL, Snapshot, Screenshot, Refresh, Back, Forward, Close Page, Scroll, Wait
Element Click, Fill, Type, Hover, Check, Uncheck, Select Option
Input Press Key, Key Event, Mouse Event, Read Clipboard
Observation Get Attribute, Fetch, Network Requests, Console Messages, JavaScript Errors
Tab List, New, Select, Close
Site List, Info, Run
Script Execute JavaScript, Run Inline Adapter
Daemon Health, Status, Doctor, Shutdown

Every operation maps 1:1 to a /v1/* (or /healthz, /status, /shutdown)
endpoint on the borz server. The raw /command escape hatch is
intentionally omitted — use Script → Execute JavaScript or Run Inline Adapter
for one-offs.

Every action that mutates the page (Open, Back, Forward, Refresh, Scroll, all
Element ops, Press Key, Execute JavaScript, Run Inline Adapter) accepts the
shared Wait For (CSS selector) and Timeout (ms) fields — the daemon
polls document.querySelector(waitFor) after the action until it resolves or
the timeout elapses. Page → Snapshot has a Mode field with a Text (reader mode) option for an LLM-friendly visible-text dump (no refs).

Build & install locally

cd borz-n8n-node
npm install
npm run build

# Link into an n8n custom nodes dir
mkdir -p ~/.n8n/custom
npm link
cd ~/.n8n/custom
npm link @leolin310148/n8n-nodes-borz

# Start (or restart) n8n
n8n start

Then in n8n: Credentials → New → borz API, set your base URL
(e.g. http://127.0.0.1:19824) and token if required. Add a borz node
to a workflow.

Typical flow

  1. Page → Open URL https://example.com

  2. Page → Snapshot (interactive + compact) — gives you ref numbers

  3. Element → Fill with ref and text from step 2 via expressions

  4. Element → Click the submit ref

  5. Script → Execute JavaScript to pull a value out, or
    Script → Run Inline Adapter for a self-contained scraper:

    async ({ query }) => {
      const el = [...document.querySelectorAll('h3')].find(h => h.textContent.includes(query));
      return el?.closest('a')?.href ?? null;
    }
    

Design notes

  • Auth header is only attached when the token is non-empty, so the same credential
    works against a loopback server (no token) and a remote one (token required).
  • tab is a shared field on Page/Element/Input/Observation/Script ops, mapping
    to the optional tab? field the server accepts on those /v1/* endpoints.
    Site → Run exposes its own Target Tab field.
  • Run Inline Adapter uses routing.send.preSend to build the body — the only
    place this node needs imperative logic. Everything else is pure routing JSON.
  • No persisted adapter upload endpoint yet. If you add one server-side
    (e.g. POST /v1/sites), a new Adapter resource with Create/List/Run/Delete
    ops drops in cleanly alongside the existing four resources.

Discussion