satura-browser-mcp
OfficialDrives a pool of named, persistent Google Chrome browser instances for agent-driven browser automation, including navigation, tab and session management, element interaction, screenshots, network inspection, and reusable per-site scripts.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
satura-browser-mcp
MCP server for Claude Code that drives a pool of named, persistent Google Chrome browsers.
Each pool browser is a real Google Chrome process with its own profile under
~/.satura-browser/pool/<name>/profile, so logins, cookies and tabs survive between sessions.
One tool,
browser_run: the agent writes JavaScript that runs against the leased Chrome with the Playwright API (page,context,request) plus a few helpers. One call can do a whole step (navigate, fill, click, extract) and return only the data it needs. Playwright isplaywright-core@1.63.0, vendored verbatim atvendor/playwright/playwright-core(nothing is pulled from npm) and attached to Chrome over CDP;src/uses only its public API. The snapshot diff comes from BetterWright, copied intovendor/betterwright/(MIT).Saved scripts per site: working code is saved as a parametrised function under the site's host and offered back in later responses on that site, so a repeated extraction or flow runs the cached code instead of being written again.
Never takes focus: the MCP server launches Chrome without a startup window and opens its window in the background,
newTab()andcontext.newPage()open background tabs (a new foreground tab would restore a minimized window and activate Chrome), andtab(i)only changes the tab the code works on; nothing callsbringToFront. Background tabs still take input, screenshots and dialogs. Onlysatura-browser loginbrings its window forward, since you sign in there.Pool: each MCP session leases one browser exclusively. The lease is released when the session exits; a crashed session's lease is ignored (dead pid).
State is copied once, at creation. A new browser is a copy of an existing profile (default: the most recently used one), plus a one-time copy of cookies from the running source because Chrome writes cookies to disk lazily. After that nothing syncs.
Real Chrome, no automation flags: launched via LaunchServices with
--disable-blink-features=AutomationControlled, sonavigator.webdriveris false and Google sign-in works.Dock: every browser gets its own Dock icon with its name and color (
Browser.setDockTile). The hover label stays "Google Chrome"; it comes from the signed app bundle, and a renamed copy of the bundle would break Keychain access (logins) and could redirect Chrome's auto-updates.
Agent workflow
The server exposes a single tool:
browser_run { code: string, timeout?: seconds (default 60, max 600), changes?: boolean }code is the body of an async function; return gives a value back. Until a browser is chosen,
page throws and the server instructions tell the agent to run return await pool.status(),
show you the browsers, ask which one to open, then run await pool.use(name). A name that does
not exist creates a new browser.
Global | |
| Playwright |
| the pool ( |
| aria snapshot with refs; Locator for a ref |
| visible text of the page or an element as compact markdown (headings, links, lists, tables, form values) |
| screenshot attached to the response (JPEG, CSS pixels) |
| tabs; |
| wait until the tab's network is quiet |
| recorded requests of the tab (document/fetch/xhr by default) and their bodies |
| console messages and page errors of the tab |
| write data to |
| saved per-site scripts (below) |
| object kept between calls (top-level variables are not) |
| output in the response; longer docs ( |
The code runs in a node:vm context that holds only these globals (no require, process or
fs), with a timeout. That keeps a script from breaking the server; it is not a security
boundary, same as Playwright MCP's browser_run_code_unsafe.
Response
Every response is a few short sections, each present only when it has content:
### Browser: the pool picked or created a browser, or relaunched a crashed one.### Error: the message plus the line of the agent's code (or saved script) that threw. Console output and page state up to the error are still reported.### Resultand### Console: the returned value (JSON, arrays one item per line) and logs. Over 20,000 / 8,000 characters, the full text goes to.satura-browser/output/and the response keeps the start and the path.### Events: dialogs answered automatically (alerts andbeforeunloadaccepted, confirms and prompts dismissed, unless the code registered its owndialoghandler), downloads saved to.satura-browser/downloads/, new tabs and popups, new console errors.### Page: the current tab and the other tabs.### Changes: after the network settles, the aria snapshot is compared with the previous one of the same tab (diff from BetterWright) and only the+/-lines are shown. Playwright keeps a ref for as long as its element keeps its role and name, so refs from earlier responses stay valid. A tab seen for the first time, or one that changed almost entirely, is shown in full as### Snapshotwhen it is under 4,000 characters, otherwise only its size is given and the agent callssnap()orread().### Saved scripts for <host>: shown when the current site has saved scripts and this session has not seen that list yet.
ref() fails at once for a ref that is not in the latest snapshot of the tab instead of waiting
for the action timeout. Actions wait up to 10 s, navigations 30 s.
Saved scripts
await scripts.save('orders', async ({ from = 1 }) => {
await page.goto(`https://shop.example/orders?page=${from}`);
return page.locator('tr.order').evaluateAll(rows => rows.map(r => r.innerText));
}, 'Orders table -> row texts; args {from}');
return await scripts.run('orders', { from: 2 });A script is a self-contained
async (args) => resultfunction that runs with the same globals, so scripts can callscripts.runtoo.It is stored under the host of the current tab (
www.dropped) in~/.satura-browser/scripts/<host>/<name>.js, with<name>.jsonholding the description and run statistics.{site: '*'}stores it for any site;scripts.runfalls back to those. Scripts are shared by every pool browser and project.A failing script is reported with the line inside it, counted, and listed as failing until it is saved again under the same name.
satura-browser scripts [SITE]lists them;satura-browser scripts rm SITE NAMEdeletes one.
Every call is also appended to ~/.satura-browser/runs/<date>.jsonl (code, browser, URL, time,
error), which helps when debugging a session or turning a good sequence into a saved script.
Files the tool writes in the project go to .satura-browser/; add it to the project's
.gitignore.
Related MCP server: Chrome MCP Bridge
CLI
satura-browser status every browser: free/busy, running, open tabs
satura-browser create NAME [--from SRC|--empty]
satura-browser rename OLD NEW (free browsers only; closes the window)
satura-browser login [URL] [--name NAME] open a window to sign in by hand
satura-browser stop [NAME...] [--all] [--force]
satura-browser rm NAME [--force]
satura-browser chrome-profiles profiles of your everyday Chrome
satura-browser import-chrome PROFILE [--name NAME]
satura-browser scripts [SITE] saved per-site scripts
satura-browser scripts rm SITE NAME
satura-browser doctorSetup
macOS or Linux with Google Chrome installed, Node.js 20 or newer:
git clone https://github.com/saturadev/satura-browser-mcp.git
cd satura-browser-mcp
npm install && npm run build && npm link
claude mcp add satura-browser -s user -- node "$PWD/dist/server.js"Server flags: --browser NAME pins the session to one browser (no question asked),
--headless. Config: ~/.satura-browser/config.json with chromePath, maxInstances
(default 8), headless, extraArgs. Env: SATURA_BROWSER_HOME, SATURA_BROWSER_NAME,
SATURA_BROWSER_HEADLESS, SATURA_BROWSER_CHROME.
Security: each running browser listens on a random 127.0.0.1 DevTools port; any local process
can drive it, same as Playwright MCP with a persistent profile. browser_run executes the
agent's JavaScript in the server process (see above).
Tests
npm test runs end-to-end tests against real Chrome (headless; SATURA_TEST_HEADED=1 for windows).
Run them after updating vendor/playwright/ too: they check the snapshot and ref format the
tool relies on.
License
MIT, see LICENSE. Third-party code in vendor/ keeps its own license:
vendor/playwright/playwright-core and the modules in vendor/playwright/copied come from
Playwright (Apache-2.0, see vendor/playwright/playwright-core/LICENSE and NOTICE), and
vendor/betterwright comes from BetterWright (MIT, see vendor/betterwright/LICENSE).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Cloud browsers for AI agents: saved logins, residential IPs, live human takeover, 57 browser tools.
Give AI agents a real cloud Chrome: open sessions, navigate, read pages, click, type and screenshot.
Your own browser in the cloud, logged in to your sites, shared by you and your AI.
Cloud browser, web extraction, screenshots, and remote CDP tools for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables browser automation and web interaction control through Playwright, allowing Claude Code to navigate, click, fill forms, take screenshots, and manage sessions.68 npm9MIT
- FlicenseNot gradedqualityDmaintenanceAI-driven browser automation for real Chrome with cookies, login sessions, and extensions intact, enabling Claude Code to control a visible Chrome browser via the Chrome DevTools Protocol.1-
- AlicenseNot gradedqualityDmaintenanceEnables Claude Code to control a browser via Playwright for web scraping, automation, and research, with features like navigation, screenshots, form filling, and PDF export.24 npmMIT
- FlicenseNot gradedqualityCmaintenanceEnables Claude to directly control a persistent, real logged-in Chrome browser via 17 browser tools and 9 trading tools, with natural-language selectors, self-healing element resolution, and risk-limited trading operations.-