pydoll-browser-mcp
An MCP server for browser automation built on pydoll (real Chrome/Edge over CDP) with:
- multi-context and multi-tab control,
- per-context proxies (isolated cookies/storage per identity),
- a large tool surface covering navigation, elements, network, storage, devtools,
stealth, HTTP-via-browser and a raw
cdp_sendescape hatch, - screenshot zoom & coordinates (fork addition):
tab_screenshot/element_screenshotacceptregion=[x1,y1,x2,y2](viewport CSS pixels),scale(magnification, e.g. 2.0) andgrid=[cols,rows](a labeled coordinate grid drawn on the returned image, ready to read click targets from). Cropping, zooming and the grid happen on the captured bitmap in Python (Pillow) — the page is never scrolled, restyled or injected into; onlyfull_page=Trueuses CDPcaptureBeyondViewport. The plain viewport shot is capped in width byPYDOLL_MCP_SCREENSHOT_WIDTH(1280, set 0 to disable).
Note: the PyPI distribution is
pydoll-browser-mcp(the olderpydoll-mcpname belongs to an unrelated project). The Python import package ispydoll_mcp.
Install / run (no project files needed)
Once published, run it straight from PyPI with uv:
uvx pydoll-browser-mcp
or with pipx:
pipx run pydoll-browser-mcp
Both download the server + dependencies into an isolated environment and run it over stdio, so nothing is added to the user's project directory. To install it permanently:
uv tool install pydoll-browser-mcp # or: pipx install pydoll-browser-mcp
Development install (this repo)
python -m venv .venv
.venv\Scripts\python -m pip install -e .
.venv\Scripts\python -m pydoll_mcp.server
opencode config
Published (isolated, no project files):
{
"mcp": {
"pydoll": {
"type": "local",
"command": ["uvx", "pydoll-browser-mcp"],
"enabled": true
}
}
}
Local checkout / venv:
{
"mcp": {
"pydoll": {
"type": "local",
"command": ["C:\\path\\to\\pydoll-mcp\\.venv\\Scripts\\python.exe", "-m", "pydoll_mcp.server"],
"environment": { "PYDOLL_MCP_PROFILE": "full", "PYDOLL_MCP_HEADLESS": "true" },
"enabled": true
}
}
}
Profiles
PYDOLL_MCP_PROFILE selects the default tool set: core, balanced (default) or full.
balanced = core + network + storage + meta. full also enables input, stealth, devtools, http.
Configuration (environment)
| Variable | Default | Purpose |
|---|---|---|
PYDOLL_MCP_BROWSER |
chrome |
chrome or edge |
PYDOLL_MCP_HEADLESS |
true |
headless new mode |
PYDOLL_MCP_PROFILE |
balanced |
tool profile |
PYDOLL_MCP_EXECUTABLE_PATH |
explicit browser binary | |
PYDOLL_MCP_USER_DATA_DIR |
persistent profile dir | |
PYDOLL_MCP_OUTPUT_DIR |
~/.pydoll-mcp/output |
screenshots/PDFs/downloads |
PYDOLL_MCP_SCREENSHOT_WIDTH |
1280 |
max CSS width of plain viewport screenshots (0 = native) |
PYDOLL_MCP_SCRIPT_TIMEOUT |
30 |
seconds a script may run before the tab call is aborted (0 = unlimited) |
PYDOLL_MCP_MAX_RESULT_BYTES |
2000000 |
max size of a tool result before it is truncated (0 = unlimited) |
PYDOLL_MCP_MAX_TABS |
25 |
max tabs per browser (0 = unlimited) |
PYDOLL_MCP_MAX_CONTEXTS |
10 |
max contexts per browser (0 = unlimited) |
PYDOLL_MCP_ALLOW_JS |
true |
enable tab_execute_script |
PYDOLL_MCP_ALLOW_CDP |
true |
enable cdp_send |
PYDOLL_MCP_ALLOW_FILE_ACCESS |
true |
allow file inputs/PDF output |
PYDOLL_MCP_ALLOW_UNRESTRICTED_FILE_ACCESS |
false |
disable the file jail |
PYDOLL_MCP_FILE_ROOTS |
output dir + cwd | comma-separated allowed roots |
Proxies
context_create(proxy_server="host:port:user:password") gives that context its own egress IP.
context_create(proxy_server="http://user:pass@host:port") and socks5://host:port also work.
Use proxy_test(proxy_server=...) to verify the egress IP before a run. Note: Chrome does not
support authenticated SOCKS5; use an unauthenticated local forwarder for that case.
Session persistence
Use context_storage_state_export / context_storage_state_import to move cookies + localStorage
between runs or machines. (Chrome profile-dir persistence is unreliable because pydoll force-stops
the process after Browser.close.)
Resilience
Each tab is locked independently, so a hung script or renderer on one tab no longer blocks other
tabs or browsers. Scripts are aborted after PYDOLL_MCP_SCRIPT_TIMEOUT seconds (Chrome terminates
them first when it can) and oversized results are truncated. tab_info reports alive plus an
unresponsive_reason when a tab stops responding, browser_status lists dead_tabs whose CDP
connection dropped, and closing a stuck tab (tab_close) always works.
Development
python -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev]"
Test harnesses (require Chrome; some hit the network / use proxies):
.venv\Scripts\python tests\test_imaging.py # pure screenshot pipeline checks (no browser)
.venv\Scripts\python tests\smoke_live.py # live screenshot tool checks against headless Chrome
.venv\Scripts\python tests\live_check.py # every tool category, local fixture
.venv\Scripts\python tests\deep_check.py # 155 checks, asserts 100% tool coverage
.venv\Scripts\python tests\ultra_check.py # multi-browser, isolated contexts, persistence, stress
.venv\Scripts\python tests\stdio_check.py # real MCP stdio handshake
.venv\Scripts\python tests\proxy_check.py # per-context proxy egress
Publishing
python -m pip install build twine
python -m build
twine check dist/*
twine upload dist/* # prompts for a PyPI API token (username: __token__)
Metadata
Release files for pydoll-browser-mcp 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pydoll_browser_mcp-0.2.1.tar.gz | 42.7 kB | Without provenance | Details for pydoll_browser_mcp-0.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pydoll_browser_mcp-0.2.1-py3-none-any.whl | Python 3 | none | any | Details for pydoll_browser_mcp-0.2.1-py3-none-any.whl |
Total release size: 91.1 kB
Release files / pydoll_browser_mcp-0.2.1.tar.gz
| Download URL | pydoll_browser_mcp-0.2.1.tar.gz |
|---|---|
| Size | 42.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
92f5c12b530064b18c0e37954060fa11f1a8c4767e0701a98ba38fed79e32140
|
|
BLAKE2b-256 checksum How to use checksums |
139412b8bbf3ba5bb95c53342327499a199acf46a3ed2aa5546bac60805fc67e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / pydoll_browser_mcp-0.2.1-py3-none-any.whl
| Download URL | pydoll_browser_mcp-0.2.1-py3-none-any.whl |
|---|---|
| Size | 48.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f4c79aef5c1383ed35f8f4edbea270aeb0330767c7db35ed2108e352178765d7
|
|
BLAKE2b-256 checksum How to use checksums |
c67c0a485ea11bd48bc37a44a2941c39063835cc0f00197079cb9add2ff434e6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for pydoll-browser-mcp 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.