Undetectable browser automation for AI agents via the Model Context Protocol.
A self-contained stealth Chrome DevTools MCP server with smart profile management, anti-detection stealth arg filtering, and robust process lifecycle handling. Built on nodriver (CDP-based) for full anti-bot evasion.
- Undetectable by anti-bot systems — Cloudflare, DataDome, PerimeterX, etc.
- Smart profile management — master/snapshot/clone strategy preserves logins across sessions
- Stealth arg filtering — automatically strips 30+ detectable Chrome flags (Puppeteer/Playwright signatures, automation markers)
- Multi-instance support — spawn and manage multiple browsers simultaneously
- Auto-suffix busy profiles —
github-sessionauto-becomesgithub-session-2when occupied - Orphan recovery — safely cleans up leaked browser processes without killing live ones
- Session persistence — cloned profiles carry cookies, logins, and Web Data from master
- Zero idle timeout — browsers stay alive until explicitly closed
- Full CDP access — DOM manipulation, network interception, JavaScript execution, screenshots
{
"mcpServers": {
"stealth-chrome-devtools-mcp": {
"command": "uvx",
"args": [
"--refresh",
"--from",
"git+ssh://git@github.com/DevinoSolutions/stealth-chrome-devtools-mcp.git",
"stealth-chrome-devtools-mcp"
]
}
}
}{
"mcpServers": {
"stealth-chrome-devtools-mcp": {
"command": "uv",
"args": [
"--directory", "/path/to/stealth-chrome-devtools-mcp",
"run", "stealth-chrome-devtools-mcp"
]
}
}
}C:\stealth-mcp-browser-sessions\
master/ # Your primary Chrome profile (logins, cookies, extensions)
master-snapshot/ # Safe copy refreshed while master is closed
sessions/ # Cloned profiles for concurrent use
github-session/
github-session-2/ # Auto-suffixed when github-session is busy
spawn_browser()uses the master profile when available- Before opening master, the server refreshes
master-snapshot - When master is busy, a clone is created from the snapshot
- Clones carry all cookies, logins, and session data
- Stale snapshots are auto-refreshed when auth files change
The server automatically strips Chrome flags that would compromise stealth:
| Category | Examples | Why Stripped |
|---|---|---|
| Automation signals | --enable-automation, --test-type |
Sets navigator.webdriver=true |
| Fingerprint leaks | --disable-gpu, --disable-webgl |
Detectable via WebGL/canvas probes |
| Puppeteer defaults | --disable-backgrounding-occluded-windows |
Bot signature fingerprint |
| Playwright defaults | --password-store=basic, --use-mock-keychain |
Bot signature fingerprint |
Stripped args are reported in spawn_diagnostics.stealth_args_stripped.
On server restart, the process cleanup system:
- Identifies browser processes from previous sessions via
create_timetracking - Only kills processes started before the current server session
- Never kills browsers spawned during the current run
- Safely handles
psutil.AccessDeniedon Windows elevated processes
# Spawn with default master profile
spawn_browser()
# Named session with login persistence
spawn_browser(user_data_dir="github-session")
# Same name while first is open → auto-suffixes to github-session-2
spawn_browser(user_data_dir="github-session")
# Headless with stealth (bad args auto-stripped)
spawn_browser(headless=True, browser_args=["--enable-automation"])
# → stealth_args_stripped: ["--enable-automation stripped: sets navigator.webdriver=true"]| Tool | Description |
|---|---|
spawn_browser |
Launch a new stealth browser instance |
navigate |
Navigate to a URL |
take_screenshot |
Capture page screenshot |
execute_script |
Run JavaScript in page context |
query_elements |
Find DOM elements by CSS selector |
click_element |
Click on an element |
type_text |
Type text into an input |
get_page_content |
Get page HTML content |
list_instances |
List all active browser instances |
close_instance |
Close a specific browser |
list_network_requests |
View intercepted network traffic |
get_cookies / set_cookie |
Manage browser cookies |
# Unit tests only (no Chrome needed)
uv run pytest -m "not integration"
# All tests (needs Chrome installed)
uv run pytest
# Verbose with short tracebacks
uv run pytest -v --tb=short95 tests covering stealth arg filtering, profile resolution, orphan recovery, and full browser integration.
All optional. Defaults work for normal use.
| Variable | Default | Purpose |
|---|---|---|
STEALTH_MCP_BROWSER_SESSION_ROOT |
C:\stealth-mcp-browser-sessions (Win) / ~/.stealth-mcp-browser-sessions (Unix) |
Base folder for profiles |
BROWSER_MASTER_USER_DATA_DIR |
<root>/master |
Master Chrome profile path |
BROWSER_MASTER_SNAPSHOT_DIR |
<root>/master-snapshot |
Snapshot clone source |
BROWSER_PROFILE_CLONE_ROOT |
<root>/sessions |
Folder for profile copies |
BROWSER_PROFILE_REFRESH_DAYS |
7 |
Refresh copies after N days (0 = disable) |
BROWSER_IDLE_TIMEOUT |
0 |
Idle cleanup timeout (0 = disabled) |
STEALTH_CHROME_PROFILE_KEY |
unset | Force a stable clone key |
STEALTH_BROWSER_DEBUG |
false |
Enable debug logging |
- Start the MCP server
- Call
spawn_browser()withoutuser_data_dir - Sign in to your accounts in the browser that opens
- Close it — future sessions use this profile or clone from it
- Python 3.11+
- Chrome, Chromium, or Microsoft Edge
- uv (recommended) or pip
MIT
Built by Devino Solutions