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 | |
|---|---|---|---|
| pydoll_browser_mcp-0.2.1.tar.gz | 42.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydoll_browser_mcp-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
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
|