Run a headless Chromium browser from your nself backend. Scrape pages, take screenshots, and manage persistent browser sessions, all through a simple HTTP API. Designed for use with nself-claw but works standalone too.
nself-browser is part of the ɳClaw bundle and requires Docker runtime. Chromium runs inside a dedicated container. Set your key with nself license set nself_pro_... before installing.
nself license set nself_pro_...
nself plugin install browser
nself build
nself start| Variable | Required | Default | Description |
|---|---|---|---|
PLUGIN_BROWSER_ALLOWLIST | No | all public | Comma-separated domains the browser may visit. Empty = all public domains allowed. |
PLUGIN_BROWSER_DENYLIST | No | RFC1918 | Comma-separated domains the browser must never visit. RFC1918 ranges are always blocked. |
# Allow only specific domains
PLUGIN_BROWSER_ALLOWLIST=example.com,docs.example.com,api.github.com
# Block specific domains (RFC1918 is always blocked regardless)
PLUGIN_BROWSER_DENYLIST=internal.example.com,admin.example.comRFC1918 addresses (10.x.x.x, 192.168.x.x, 172.16-31.x.x) and localhost are always blocked regardless of the allowlist. This prevents SSRF attacks if the browser is exposed via an AI agent or user input.
# Scrape full page text
curl -X POST http://127.0.0.1:3716/browser/scrape \
-H "Content-Type: application/json" \
-d '{
"url": "https://news.ycombinator.com",
"selector": ".titleline > a"
}'# Screenshot returns a PNG
curl "http://127.0.0.1:3716/browser/screenshot?url=https://example.com" \
--output screenshot.png# List active browser sessions
curl http://127.0.0.1:3716/browser/sessions
# Delete a specific session
curl -X DELETE http://127.0.0.1:3716/browser/sessions/session-id-here| Endpoint | Method | Description |
|---|---|---|
/browser/scrape | POST | Load a URL and extract text, links, or matching selectors |
/browser/screenshot | GET | Capture a full-page PNG screenshot of any URL |
/browser/sessions | GET | List active browser sessions |
/browser/sessions/:id | DELETE | Terminate and clean up a browser session |
/screenshots | GET | List recent screenshots stored on disk |
/health | GET | Check plugin health and Chromium status |
{
"url": "https://example.com", // URL to load
"selector": "h1, p", // CSS selector (optional, returns all text if omitted)
"screenshot": false, // also capture a screenshot (default: false)
"wait_for": ".content", // CSS selector to wait for before scraping (optional)
"timeout_ms": 30000 // page load timeout in ms (default: 30000)
}nself-browser stores screenshot metadata and session state in the np_browser schema. Hasura auto-tracks these for GraphQL access.
| Table | Key columns | Purpose |
|---|---|---|
np_browser.screenshots | id, url, file_path, width_px, captured_at, user_id | Record of every screenshot taken, with path on disk |
np_browser.sessions | id, created_at, last_used_at, page_count, status | Active Chromium session handles and their activity |
np_browser.scrape_log | id, url, selector, result_chars, duration_ms, created_at | Audit log of every scrape call — useful for debugging selector failures |
query RecentScreenshots {
np_browser_screenshots(
order_by: { captured_at: desc }
limit: 10
) {
url
file_path
captured_at
}
}nself-browser emits events consumed by nself-mux for rule-based routing.
| Event | Trigger | Payload fields |
|---|---|---|
browser.scrape.success | Scrape completes | url, selector, result_chars, duration_ms |
browser.scrape.error | Page load fails or selector returns nothing | url, selector, error, duration_ms |
browser.screenshot.taken | Screenshot saved | url, file_path, width_px |
browser.ssrf.blocked | RFC1918 or denylist URL attempted | url, blocked_by |
| Service | Price | Key trade-off vs nself-browser |
|---|---|---|
| Browserless.io | $50–$500/mo | Managed cloud, no setup — but data leaves your server and billed per minute |
| Apify | $49–$499/mo | Actor marketplace, pre-built scrapers — but proprietary platform lock-in |
| Playwright Cloud (MS) | Preview / invite | First-party Microsoft tooling — but cloud-hosted, not self-hosted |
| nself-browser | $0.99/mo bundle | Runs on your server — data never leaves, SSRF-guarded, integrates with ɳClaw |
The browser plugin runs Chromium inside Docker. If the container crashes on start, check that your host has at least 512 MB of available RAM and that the --shm-size flag is present in the generated compose file. Run nself build to regenerate it, then nself start.
The page may require JavaScript to render content. The browser plugin already runs JS by default, but some sites use anti-bot detection. Try adding "wait_for": ".content" to your scrape payload to wait for a specific element before extracting text.
If a legitimate domain is being blocked, check that it is not in an RFC1918 range. RFC1918 (10.x.x.x, 192.168.x.x, 172.16-31.x.x) and localhost are always blocked regardless of the allowlist. If you need internal access for testing, use a public DNS name that resolves externally.
A blank PNG usually means the page loaded but returned a zero-height body (e.g. a redirect that Chromium did not follow, or a page that requires login). Scrape first to confirm text content, then take the screenshot.
Run nself hasura metadata apply to re-track the schema after installing or reinstalling the plugin.
nself plugin remove browserPort: 3716 | Bundle: ɳClaw ($0.99/mo) or ɳSelf+ ($3.99/mo) | Requires: Docker runtime | Last Updated: May 2026 | Plugin Version 1.1.0