Stealth Browser MCP: a nodriver-based MCP server for anti-bot pages
The only browser automation that bypasses anti-bot systems. AI writes network hooks, clones UIs pixel-perfect via simple chat.
At a glance
- What is it?
- Stealth Browser MCP exposes 97 browser-automation tools to MCP clients through real Chrome-family instances and nodriver. It is aimed at engineers whose agents hit Cloudflare challenges, and its MIT licence makes the tool surface cheap to fork, but the README's own caveats matter more than the demo.
- Who is it for?
- Adopt Stealth Browser MCP if you already run an MCP client and need an agent to drive a real Chrome-family browser through anti-bot walls, and if you are comfortable that the README's success claims are explicitly conditional on site, region, browser version and detector version. Do not adopt it if you need a stable, versioned automation API for regression tests, or if you cannot audit a dependency that is pinned to a git commit.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Stealth Browser MCP is for, and who is a bad fit
The project is an MCP server, not a library. It wraps nodriver, which drives a real Chrome-family browser over the Chrome DevTools Protocol, and exposes that browser to an MCP-compatible AI agent as a set of callable tools. The README describes the target as agents that need to "navigate Cloudflare challenges, anti-bot checks, and login walls." So the user is someone whose agent already works, but stalls on a page that fingerprints the browser.
That framing matters, because it tells you who should not use this. If your automation talks to a documented JSON API, an HTTP client is smaller, faster and has no browser to keep alive. If you need deterministic, replayable test runs, a real browser driven by an LLM is the wrong shape: the same prompt can produce different click sequences. And if the pages you scrape are not defended, Playwright or Puppeteer will do the job with a larger ecosystem behind them.
The README's own feature list is unusually honest about the boundary. It says anti-bot resistance "has passed Cloudflare and Queue-It style challenges in testing; results vary by site, region, browser version, and detector version." That is a statement about a moving target, not a guarantee. Treat any stealth tool as a bet that your specific target, from your specific IP, is not currently on the losing side of that race.
How the nodriver and CDP layer actually works
nodriver is the load-bearing dependency. Unlike Selenium-style drivers that speak WebDriver, nodriver talks directly to the browser over CDP, which removes the WebDriver fingerprint that detectors look for. Stealth Browser MCP adds FastMCP 2.11.2 on top so an AI agent can call that browser through the Model Context Protocol.
The tool surface is organised into 11 sections, 97 tools in total, and the README says sections can be disabled to run a "minimal 20-tool core." That modularity is the most practically interesting design decision here. Every tool you leave enabled is another schema the model has to consider, and tool-selection accuracy degrades as the menu grows. A 20-tool core for navigation plus a 97-tool surface for a deep debugging session are genuinely different products.
Two mechanisms are worth understanding before you install. First, the hook system: the README describes "restricted Python hooks" that can "intercept, block, redirect, fulfill, or modify request/response flows." That is request interception implemented on the Python side rather than in page JavaScript, which is why the project can also run pre-document scripts through CDP. Second, element cloning: the README claims "pixel-accurate element cloning" that extracts CSS, DOM structure, events, animations and assets via CDP. The demo directory contains augment-hero-clone.md and augment-hero-recreation.html, which is the repository's own example of that workflow.
One dependency deserves scrutiny. py2js is pulled from a git URL pinned to commit 31a83c7c25a51ab0cc3255f484a2279d26278ec3, not from PyPI. The Dockerfile installs git specifically because of it. That pin is good for reproducibility and bad for supply-chain review: you cannot check a release history for it.
Installing Stealth Browser MCP and registering it with an MCP client
The README's quickstart assumes Python 3.10 or newer and an existing Chrome, Chromium or Microsoft Edge install. Clone the repository, create a virtual environment, and install from requirements.txt:
git clone https://github.com/vibheksoni/stealth-browser-mcp.git
cd stealth-browser-mcp
python -m venv venv
source venv/bin/activate
pip install -r requirements.txtOn Windows the activation line is venv\Scripts\activate instead. After pip finishes you should have fastmcp, nodriver and the rest of the pinned set in that environment; the git-sourced py2js package is the one most likely to fail if you are behind a proxy that blocks GitHub.
The README recommends Claude Code CLI for registration. On macOS or Linux, the command takes a JSON blob describing a stdio server whose command is the venv Python and whose args point at src/server.py:
claude mcp add-json stealth-browser-mcp '{
"type": "stdio",
"command": "/path/to/stealth-browser-mcp/venv/bin/python",
"args": ["/path/to/stealth-browser-mcp/src/server.py"]
}'Replace the placeholder paths with your real clone path; the README explicitly warns about this. For Claude Desktop, Cursor or another client, the same shape goes into an mcpServers block in the client's JSON config:
{
"mcpServers": {
"stealth-browser-mcp": {
"command": "/path/to/stealth-browser-mcp/venv/bin/python",
"args": ["/path/to/stealth-browser-mcp/src/server.py"],
"env": {}
}
}
}There is also a Docker path. The Dockerfile installs google-chrome-stable, runs as a non-root mcpuser, exposes port 8000, and starts HTTP transport with python src/server.py --transport http --host 0.0.0.0. Its healthcheck calls http://localhost:$PORT/mcp and adds an Authorization: Bearer header when STEALTH_BROWSER_MCP_AUTH_TOKEN is set. That environment variable is the only documented authentication control, and the Dockerfile comment says to set it to enable bearer auth. Do not expose the HTTP transport without it.
For a first real use, start with the smallest thing that proves the loop works: ask your agent to navigate to a page you control, then ask it to return the page title. If that fails, the problem is registration, not stealth.
The limitations the README admits, and the ones it does not
The honest caveat is already quoted above: anti-bot results vary by site, region, browser version and detector version. Read that as an operational statement. A workflow that passes today can fail after a Chrome update, and the project cannot promise otherwise, because the opposing side ships changes on its own schedule.
Beyond that, several constraints follow from the architecture. Running a real browser per session costs memory and startup time; nodriver has to launch and attach, and the Docker image carries a full Chrome install. CI environments need xvfb, which the Dockerfile installs, so headless CI is possible but not free.
The trust model is the sharpest edge. The README has a section titled Trust Model and the feature list mentions "CDP execution" for JavaScript, direct CDP commands and pre-document scripts, available "through trusted local MCP clients." That is the correct framing: an MCP server that can run arbitrary CDP commands and inject pre-document scripts is executing code in your browser context on behalf of a model. The README's own wording ties that capability to trusted local clients, which is a boundary worth respecting rather than a formality.
Finally, the repository is small in human terms. There is a CODEOWNERS file, a single named author in pyproject.toml, and a v0.2.5 release dated 2026-02-10 whose title mentions a protocol fix, Edge support and repository cleanup. The last push to master was on 2026-09-07. There is no long release history to lean on, so budget for reading src/ yourself.
Stealth Browser MCP versus Playwright MCP
The README ships a COMPARISON.md and a section titled "Stealth vs Playwright MCP," so the project invites the comparison directly. The difference is not tool count; it is the driver underneath.
Playwright drives browsers through its own protocol layer and is built for testing: deterministic waits, trace files, a stable API, and a large ecosystem of fixtures and reporters. Its stealth story is bolt-on, usually a patched browser build or extra init scripts. Stealth Browser MCP inverts that. It starts from nodriver's CDP-direct connection, which avoids the WebDriver fingerprint by construction, and then layers an MCP tool surface on top. What you give up is the testing ergonomics: no trace viewer, no first-class assertion model, and a much younger codebase.
If your problem is "my agent gets blocked," the stealth-first approach is the one aligned with the problem. If your problem is "my agent's actions need to be reproducible and debuggable," Playwright's model is better suited even if you have to add stealth patches yourself. The two are not interchangeable, and picking based on tool count would be a mistake.
A second alternative is not using an MCP server at all: call nodriver directly from your own Python. You lose the agent integration, but you also lose the 97-tool schema negotiation and the dependency on FastMCP. For a fixed scraping job, that is often the smaller system.
Maintenance, upgrade cost and what the MIT licence does and does not cover
The last push to master was on 2026-09-07, and the only tagged release is v0.2.5 from 2026-02-10. That gap between a February release tag and a September push suggests work continues on master without being tagged, which is common for young projects but means "upgrade to the latest release" is not a meaningful instruction here. You are tracking master or pinning a commit.
The dependency set is tightly pinned: fastmcp==2.11.2, nodriver==0.47.0, pydantic==2.11.7, and others with exact versions. That is good for reproducibility and bad for security patching, because you will not pick up a nodriver fix without editing requirements.txt. The py2js git pin compounds this: there is no version number to compare against.
On licence, the project is MIT, stated in pyproject.toml and the LICENSE file. MIT permits commercial use and modification with attribution and without warranty. It does not give you any assurance about the legality of what you point the browser at. Whether bypassing a particular site's anti-bot control is permitted by that site's terms, or by law in your jurisdiction, is a separate question that the licence does not touch, and the README does not address it. That is a decision for you and, if the stakes are high, for a lawyer.
One more cost: the README carries paid sponsor placements for two proxy providers. Sponsorship does not change the MIT terms, but it does mean the README's proxy recommendations are commercial placements rather than independent evaluations. Evaluate proxies on your own traffic.
Editorial conclusion
Adopt Stealth Browser MCP if you already run an MCP client and need an agent to drive a real Chrome-family browser through anti-bot walls, and if you are comfortable that the README's success claims are explicitly conditional on site, region, browser version and detector version. Do not adopt it if you need a stable, versioned automation API for regression tests, or if you cannot audit a dependency that is pinned to a git commit. Before wiring it into anything you care about, verify three things yourself: that nodriver 0.47.0 and the pinned py2js commit still resolve, that your MCP client accepts the stdio command path you configure, and that the target site's challenge actually clears in your region with your browser build. The README's troubleshooting section is the only place to look when it does not.
Frequently asked questions
What is a stealth browser?
In this project's terms, it is a real Chrome-family browser driven in a way that avoids the fingerprints anti-bot systems look for. Stealth Browser MCP uses nodriver, which connects over the Chrome DevTools Protocol instead of WebDriver, and the README notes results still vary by site, region, browser version and detector version.
What is an MCP browser?
It is a browser exposed to an AI agent through the Model Context Protocol rather than through a script you write. Stealth Browser MCP is an MCP server built on FastMCP that presents 97 browser tools across 11 sections, with a minimal 20-tool core available if you disable sections you do not need.
How do I install the Stealth Browser MCP server?
Clone the repository, create a Python 3.10+ virtual environment, and run pip install -r requirements.txt. Then register src/server.py with your MCP client, either through claude mcp add-json or an mcpServers entry pointing at the venv Python, replacing the example paths with your real clone path.
Does Stealth Browser MCP always bypass Cloudflare?
No. The README states that anti-bot resistance has passed Cloudflare and Queue-It style challenges in testing but that results vary by site, region, browser version and detector version. Treat a successful run as specific to that combination, not as a general guarantee.
Can I run Stealth Browser MCP in Docker?
Yes. The Dockerfile installs google-chrome-stable and xvfb, runs as a non-root user, exposes port 8000, and starts the server with --transport http --host 0.0.0.0. Set STEALTH_BROWSER_MCP_AUTH_TOKEN to enable the bearer auth the healthcheck uses.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vibheksoni-stealth-browser-mcp)