Dooza Browser
Officialby Dooza-ai
README.md
# Dooza Browser
**One shared, logged-in Chrome for all your AI agents.** Claude Code, Codex, ChatGPT or your own scripts get a real
browser through MCP or plain HTTP: open tabs, read pages, click, type, upload files, run short Playwright scripts,
or hand off a whole web task. Agents share what they learn about each site, and they never steal your mouse or close
your tabs.
We built it to run [Dooza](https://dooza.ai)'s own team of AI agents (sales, SEO, video, ops) on one machine, all
sharing one Chrome that is logged in once. This is that code, cleaned up.
## Why
- **Log in once.** The agents use one Chrome profile. You sign in to Gmail, LinkedIn, Stripe... by hand once; cookies
persist. Agents never see your passwords.
- **Many agents, one browser, no fights.** Each tab belongs to the agent that opened it. Agent windows open in the
background in their own screen area, never as tabs in your window, and never take focus.
- **Fast actions, not click-by-click.** `tab_playwright` runs a short Playwright script on a tab: 10 steps in one tool
call. Models already know Playwright well, so it is quicker and cheaper than one tool call per click.
- **Site memory.** `site_note` saves one-line lessons per site ("the Save button is `#submit-2`", "this site blocks
headless"). They come back automatically every time any agent opens that site.
- **Whole tasks on a cheap model.** `browse(task)` gives the task to [browser-use](https://github.com/browser-use/browser-use)
on any OpenRouter model (or to headless Claude Code), with a judge, a retry on a stronger model, and a stronger
model by default on sensitive sites (inbox, payments).
## Tools
| Tool | What it does |
|---|---|
| `browse(task, url?, model?, owner)` | Whole web task in its own background window; returns text |
| `tab_open(url, owner)` | New background tab you own; returns `tab_id` + saved site notes |
| `tab_read(tab_id, owner, mode)` | `text`, `links`, `inputs` (form fields with ready selectors) or `html` |
| `tab_click` / `tab_type` / `tab_navigate` / `tab_eval` | Step-by-step control |
| `tab_playwright(tab_id, owner, script)` | Python Playwright (async) on that tab; set `result = ...` |
| `tab_upload(tab_id, owner, paths, ...)` | File upload, including buttons that open a native file picker |
| `tab_screenshot` / `tab_list` / `tab_close` | |
| `site_note(site, owner, note?)` | Read or add per-site notes (secrets are refused) |
| `status()` | Chrome version, open tabs, free task slots, OpenRouter spend |
Every tool is also `POST /api/<tool>` with the arguments as JSON.
## Quick start (Linux or macOS)
```bash
git clone https://github.com/Dooza-ai/dooza-browser && cd dooza-browser
python3 -m venv .venv && .venv/bin/pip install -e . # no browser download: it drives your own Chrome
cp config.example.json config.json
# 1. a dedicated Chrome with DevTools on localhost:9222 (sign in to your sites in this window, once)
examples/start-chrome.sh &
# 2. the server (MCP at http://127.0.0.1:8765/mcp)
export OPENROUTER_API_KEY=... # only for browse() with the browser-use engine
.venv/bin/dooza-browser
```
Connect a client:
```bash
claude mcp add --transport http --scope user browser http://127.0.0.1:8765/mcp # Claude Code
# Codex: ~/.codex/config.toml -> [mcp_servers.browser] url = "http://127.0.0.1:8765/mcp"
curl -s localhost:8765/api/tab_open -H 'Content-Type: application/json' -d '{"url":"https://example.com","owner":"me"}'
```
For Claude Code, copy `skill/SKILL.md` to `~/.claude/skills/dooza-browser/SKILL.md` so agents know when to use which tool.
On a headless server, run Chrome on a virtual display wide enough for both areas (`Xvfb :99 -screen 0 2880x900x24`);
your own window sits at x 0-1440, agent windows open at x >= 1440 (`agent_window` in config.json). A systemd unit is
in `examples/`.
## Configuration (`config.json`)
| Key | Meaning |
|---|---|
| `engine` | `browser-use` (OpenRouter models) or `claude` (Claude Code CLI drives the tab tools; uses your Claude login) |
| `models.default / sensitive / strong` | OpenRouter model ids: normal sites / `sensitive_domains` / retry |
| `sensitive_domains` | URL substrings that get the `sensitive` model |
| `max_concurrent_tasks`, `max_tasks_per_owner`, `max_steps`, `task_timeout_s` | `browse()` limits |
| `tab_idle_close_s`, `max_tabs_per_owner` | Forgotten tabs are closed; a 4th tab closes your oldest |
| `agent_window` | Where agent windows open (`left`, `width`, `height`) |
| `reap_orphans` | `true` also closes unowned windows in the agent area. Only for a Chrome dedicated to agents |
| `upload_roots` | Folders uploads may come from (`{owner}` = agent name). Files that look like secrets are always refused |
| `playwright_sandbox` | Optional `{"user": "pwrun", "python": "/opt/pwrun/venv/bin/python", "runner": "/opt/pwrun/pw_runner.py"}`: run scripts as a user that can't read your files (needs a sudoers rule) |
| `api_hints` | `{"url substring": "use the X API instead"}`, shown to agents when they open that site |
Environment: `DOOZA_BROWSER_CONFIG` (default `./config.json`), `DOOZA_BROWSER_HOME` (logs, screenshots, site notes,
optional `credentials.env`; default `~/.dooza-browser`), `OPENROUTER_API_KEY`.
`credentials.env` (`NAME=value` lines) is passed to browser-use as `sensitive_data`: the model only sees `NAME` and the
value is filled in at typing time.
## Safety
- The server listens on 127.0.0.1 only. Anyone who can reach it controls your logged-in browser: don't expose it.
- Page content is data, never instructions; tool descriptions and the browse prompt say so, but prompt injection is
a real risk for any browser agent. Give the agent Chrome only the logins your agents need.
- `tab_eval` and `tab_playwright` run code you send in the page or on your machine. Use the sandbox user on shared
machines.
- Optional `python -m dooza_browser.captcha <tab>` solves reCAPTCHA/hCaptcha/Turnstile through 2Captcha (paid,
`TWOCAPTCHA_API_KEY`). Use it only where the site's terms allow automation.
## Credits
Built on [browser-use](https://github.com/browser-use/browser-use), [FastMCP](https://github.com/jlowin/fastmcp) and
[Playwright](https://playwright.dev). Ideas from Aside's write-up on browser agents (Playwright actions, site memory).
MIT licensed. Made by [Dooza](https://dooza.ai): AI agents that work as your team.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues