browse: support remote browser via BROWSER_WS_ENDPOINT
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
## Problem
When running Claude Code in a container or headless environment (Docker, NAS, CI), `browse` fails because there is no local Chromium available (no display, no GPU). Pages render blank.
Many users already have a Browserless instance (or similar remote browser service) running on their network. Playwright natively supports connecting to remote browsers via WebSocket, but `browse` always calls `chromium.launch()` locally.
## Proposed solution
Support a `BROWSER_WS_ENDPOINT` environment variable in `browser-manager.ts`. When set, `browse` should connect to the remote browser instead of launching a local one:
```ts
// browser-manager.ts, in launch()
if (process.env.BROWSER_WS_ENDPOINT) {
this.browser = await chromium.connect(process.env.BROWSER_WS_ENDPOINT, { timeout: 15000 });
} else {
this.browser = await chromium.launch({ ... });
}
```
This is the same pattern Playwright uses for remote execution. The env var name matches the Playwright convention.
## Use case
- NAS-hosted dev environment (QNAP, Synology) with Browserless v2 running as a container
- CI pipelines where Chromium isn't installed on the runner
- Docker-based Claude Code instances without display/GPU
## Tested with
- Browserless v2 (Chrome 147)
- Playwright protocol endpoint: `ws://host:3000/chromium/playwright?token=xxx`
- Auth via token in query string (Browserless v2 convention)
All existing `browse` commands (goto, snapshot, screenshot, click, fill, console) work through the remote connection without changes.
## Alternatives considered
- Using `connectOverCDP()` — works but Browserless v2 exposes Playwright protocol natively at `/chromium/playwright`, which is more compatible
- Patching `browser-manager.ts` locally — works but gets overwritten on gstack upgrade
Contributor guide
Assessment
This issue has not been assessed yet.