Integrations / Automation libraries / Puppeteer

Puppeteer, connected to a real profile.

puppeteer.launch starts a fresh browser that forgets everything and looks automated. Connect Puppeteer to a running Browz profile instead: it keeps its cookies, has its own fingerprint and proxy, and your page code does not change.

Terminalnpm install puppeteer-core @browz/sdk

Setup

Set it up.

  1. Install Browz and open it

    Download Browz and leave it open.

  2. Install the packages

    puppeteer-core has no bundled browser, which is what you want here.

    Terminalnpm install puppeteer-core @browz/sdk
  3. Start a profile and connect

    defaultViewport: null keeps the profile’s real window size; Puppeteer’s default 800×600 would not match the screen the profile reports.

    run.mjsimport puppeteer from 'puppeteer-core'; import { Browz, localCredentials } from '@browz/sdk'; const browz = new Browz(await localCredentials()); const { id } = await browz.profiles.create({ name: 'puppeteer-demo' }); const session = await browz.browser.start(id); const browser = await puppeteer.connect(session.wsEndpoint ? { browserWSEndpoint: session.wsEndpoint, defaultViewport: null } : { browserURL: session.cdpEndpoint, defaultViewport: null }); try { const [page] = await browser.pages(); await page.goto('https://example.com'); console.log(await page.title()); } finally { await browser.disconnect(); // not close(): that would kill the browser behind Browz await browz.browser.stop(id); }

Options from Puppeteer connect.

Example

A screenshot from a profile you already use.

Find a profile by name, attach to it even if it is open on your screen, and leave it running if it was.

inbox.mjsimport puppeteer from 'puppeteer-core'; import { Browz, localCredentials } from '@browz/sdk'; const browz = new Browz(await localCredentials()); const profile = (await browz.profiles.list()).find((p) => p.name === 'Support inbox'); const session = await browz.browser.start(profile.id, { reuse: true }); const browser = await puppeteer.connect({ browserURL: session.cdpEndpoint, defaultViewport: null }); const page = await browser.newPage(); await page.goto('https://example.com'); await page.screenshot({ path: 'inbox.png' }); await page.close(); await browser.disconnect(); if (!session.alreadyRunning) await browz.browser.stop(profile.id);

Good to know

Notes and tips.

  • Never call puppeteer.launch() for a Browz profile: that starts a stock browser with automation flags and none of the profile’s fingerprint, proxy or cookies. Attach to the one Browz started.
  • Attach to the browser Browz started; never let the library launch its own. A library-launched browser is a stock one with none of the profile’s fingerprint, proxy or cookies.
  • A person completes sign-ins, 2FA codes and CAPTCHAs in the profile’s window; your script can wait for the page that follows. Browz never solves or bypasses CAPTCHAs.
  • Automate only where each site’s terms allow it. Our acceptable use policy applies to scripts the same as to people.
  • The local API, CDP and the SDKs are on every plan, Free included (5 profiles), and are not metered.

FAQ

Puppeteer and Browz.

browserWSEndpoint or browserURL?

Either. browserWSEndpoint takes the ws:// URL Browz returns as wsEndpoint; browserURL takes the http:// cdpEndpoint and looks the socket up itself.

Can I use puppeteer instead of puppeteer-core?

Yes, but it downloads a browser you will not use. puppeteer-core is the same API without it.

How many profiles can I drive at once?

As many as your computer runs comfortably and your plan has profiles: Free has 5. Each needs its own connect().

Get started

Download Browz. Every task, its own browser.

Then, on macOS or Linux, put the MCP server on your PATHcurl -fsSL https://gobrowz.com/agents/install.sh | sh

For Mac, Windows and Linux. Free for 5 profiles. Paid plans from $4.99 a month, with a 14-day refund on your first payment.