Proxy Browser Server
БесплатноНе проверенEnables Claude to browse the web and make GET/POST/PUT requests with a real Chrome TLS/HTTP2 fingerprint to avoid anti-bot detection, supporting persistent cook
Описание
Enables Claude to browse the web and make GET/POST/PUT requests with a real Chrome TLS/HTTP2 fingerprint to avoid anti-bot detection, supporting persistent cookie sessions and optional proxies.
README
An MCP server that lets Claude browse the web and make GET / POST / PUT / PATCH / DELETE / HEAD requests while looking like a real Chrome browser at the network layer — so you don't get anti-bot flagged on sites like AliExpress.
- Real Chrome TLS/HTTP2 fingerprint (via
curl_cffi), not just a spoofed User-Agent - Headless-browser render tier — falls back to a real, undetected Chromium (patchright) that executes JavaScript and passes JS anti-bot challenges (Cloudflare, DataDome, AliExpress)
- Anti-bot challenge detection — flags captcha/punish walls instead of returning the stub as content
- Persistent cookie session — multi-step browsing looks like one continuous browser
- Token-efficient output — HTML is cleaned into markdown by default (raw available)
- Streamed, byte-capped body reads — an oversized/binary response can't blow up memory
- Automatic retries with backoff + jitter (honors
Retry-After) for idempotent methods - Randomized think-time + a hard 1–2 request cap per call — a constant, bursty cadence is itself a bot tell
- Optional upstream proxy — plug in a residential/rotating proxy for IP rotation
- Full verb set with form or JSON bodies
Why not just requests + a Chrome User-Agent?
Because a UA string fools nobody serious. Cloudflare, Akamai, and AliExpress fingerprint
your TLS handshake (JA3/JA4) and HTTP/2 frame ordering — a stock Python HTTP client
is instantly identifiable as a bot no matter what User-Agent header it sends.
This server uses curl_cffi, which drives
libcurl with a real Chrome TLS + HTTP/2 fingerprint. The connection itself looks like
Chrome — verified against tls.peet.ws (JA4 t13d1516h2, Chrome's Akamai HTTP/2
fingerprint, over h2).
Requirements
Python 3.9+ (developed/tested on 3.11, Windows 11)
pip
Claude Code CLI (to consume the MCP server)
Python packages (installed via
requirements.txt):Package Role mcpOfficial MCP Python SDK (FastMCP server) curl_cffiChrome TLS/HTTP2 impersonation engine (bundled libcurl) trafilaturaMain-content extraction → markdown (token-efficient) beautifulsoup4Full-page DOM cleanup markdownifyHTML → markdown conversion
curl_cffi ships its own libcurl build, so there is no external C dependency to install.
Installation
# 1. Clone the repo
git clone https://github.com/nullsection/headless-proxy-mcp.git
cd headless-proxy-mcp
# 2. (recommended) create a virtual environment
python -m venv .venv
.\.venv\Scripts\Activate.ps1 # PowerShell
# source .venv/bin/activate # macOS/Linux
# 3. Install dependencies
python -m pip install -r requirements.txt
Setup — register with Claude Code
# User scope = available in all your projects
claude mcp add -s user proxy-browser -- python C:/path/to/headless-proxy-mcp/proxy_browser_server.py
# Verify
claude mcp get proxy-browser # should show: Status: Connected
Use forward slashes in the path — a backslash path can be mangled by the shell.
To pass configuration (e.g. a proxy), add -e flags:
claude mcp add -s user proxy-browser \
-e PROXY_URL=http://user:pass@host:port \
-e IMPERSONATE=chrome124 \
-- python C:/path/to/headless-proxy-mcp/proxy_browser_server.py
Restart Claude Code after registering so it loads the server.
Usage
Once registered and restarted, just ask Claude in natural language — e.g. "browse aliexpress for usb cables and summarize the top results." Claude selects the right tool automatically.
Tools
| Tool | Description |
|---|---|
browse |
HTTP GET a URL, with an optional headless-browser fallback (render policy). |
render |
Load a URL in a real headless browser (executes JS; passes JS challenges). |
http_post |
HTTP POST with form data or json body. |
http_put |
HTTP PUT with form data or json body. |
http_patch |
HTTP PATCH with form data or json body. |
http_delete |
HTTP DELETE (optional data or json body). |
http_head |
HTTP HEAD — response headers only (liveness / type / redirect). |
session_reset |
Clear cookies / start a fresh browsing identity. |
session_info |
Show impersonation target, proxy, config, and current cookies. |
Retries & idempotency:
browse,http_put,http_delete, andhttp_headare idempotent, so transient429/5xx/network failures are retried automatically with exponential backoff (honoringRetry-After).http_postandhttp_patchare not retried, to avoid duplicate side effects.
Parameters
url— full URL includinghttp://orhttps://.extract— how the body is returned:"auto"(default) — main content as markdown (best for pages)"full"— the whole page converted to markdown"text"— plain text only"raw"— exact HTML / response bytes
headers— optional extra request headers (merged over sane Chrome defaults).proxy— optional per-request proxy URL (overridesPROXY_URLfor that call).timeout— request timeout in seconds (default 30).data/json(POST/PUT only) — form fields or a JSON body (use one).
Configuration
Set via environment variables (or -e flags at registration). See .env.example.
| Variable | Default | Description |
|---|---|---|
IMPERSONATE |
chrome131 |
Chrome build to mimic (e.g. chrome124, chrome131, chrome136). Keep it recent. |
PROXY_URL |
(empty) | Upstream proxy: http://user:pass@host:port or socks5://host:port. Empty = direct. |
MAX_CHARS |
60000 |
Max characters of the extracted body returned to Claude (protects context). |
MAX_RESPONSE_BYTES |
10000000 |
Hard cap on raw bytes read off the wire; body is streamed and reading stops past this. |
PER_HOST_DELAY |
0 |
Minimum seconds between requests to the same host (politeness / anti-flag). |
PER_HOST_JITTER |
0.3 |
Randomize the per-host delay by ±this fraction (0.3 = ±30%) so cadence isn't constant. |
MAX_RETRIES |
2 |
Additional attempts after the first on 429/5xx/network errors (bounded by MAX_REQUESTS_PER_CALL). |
RETRY_BACKOFF |
0.5 |
Base retry backoff in seconds, grown exponentially with jitter. |
MAX_RETRY_WAIT |
30 |
Cap on any single retry sleep, even if Retry-After asks for more. |
REQUEST_JITTER_MIN / REQUEST_JITTER_MAX |
0.5 / 2.0 |
Randomized think-time (s) before every request — fires even on a single hit, so nothing goes out with bot-like zero latency. MAX=0 disables. |
MAX_REQUESTS_PER_CALL |
2 |
Hard ceiling on total HTTP hits per tool call (initial + retries), clamped to 1–2 to stay under anti-bot thresholds. |
RENDER_MODE |
auto |
Browser-fallback policy for browse: auto | never | always. |
RENDER_WAIT_UNTIL |
domcontentloaded |
Load state renders wait for; use networkidle for XHR-driven grids. |
RENDER_HEADLESS |
1 |
0 = headful window (max stealth, needs a display). |
RENDER_CHANNEL |
(bundled) | chrome/msedge to drive the real installed browser (new headless, real GPU). Recommended for hard walls. |
RENDER_USER_DATA_DIR |
(none) | Persistent Chrome profile dir — banks anti-bot cookies + logins across runs (the PerimeterX lever). |
RENDER_EXTRA_ARGS |
(none) | Extra Chromium flags, comma-separated (e.g. --use-angle=d3d11 for real-GPU WebGL on Windows). |
RENDER_LOCALE / RENDER_TIMEZONE / RENDER_VIEWPORT / RENDER_UA |
en-US / America/New_York / 1280x800 / (auto) |
Realistic browser context. UA defaults to the engine's real UA with the HeadlessChrome tell stripped. |
See .env.example for the full render knob list (RENDER_TIMEOUT, RENDER_WAIT_MS, RENDER_MIN_CONTENT_CHARS).
Troubleshooting
Failed to connect— the path was likely mangled by backslashes. Re-add using forward slashes (see setup above), and confirmpythonis on your PATH.- Server connects but a site still blocks you — you're probably being flagged by IP,
not fingerprint. Set
PROXY_URLto a residential/rotating proxy and raisePER_HOST_DELAY. - Page comes back blank / missing content — the site renders via JavaScript.
curl_cffidoes not execute JS (see Limitations). - Response truncated — raise
MAX_CHARS, or request a tighterextractmode.
Headless browser render tier
The HTTP engine mimics Chrome's network identity but can't run JavaScript, so JS-rendered
pages and JS challenge walls defeat it. The optional render tier fixes that by driving a
real, undetected Chromium (patchright,
a patched Playwright drop-in) that executes JS, passes challenges, and hides the automation
tells (navigator.webdriver, the HeadlessChrome UA).
pip install -r requirements-render.txt
patchright install chromium # one-time browser download (or: playwright install chromium)
browse(url, render="auto")(default) — tries fast HTTP first, then transparently escalates to the browser when the page looks challenge-walled or JS-thin and an engine is installed.render="never"= HTTP only;render="always"= browser only.render(url, wait_selector=".product-card", wait_ms=4000)— explicit browser load. Usewait_selector/wait_ms(orRENDER_WAIT_UNTIL=networkidle) for grids that populate via XHR after load.
Verified live: this tier passes AliExpress's
_tmd_/punishcaptcha wall that blocks the HTTP client, and renders the JS product grid.navigator.webdriveris hidden and the UA is cleaned to a real Chrome string.
Getting past hard walls (PerimeterX / DataDome / Facebook)
For aggressive bot managers, the render tier has a persistent-profile + organic-navigation
mode. Verified live getting past Carsales' PerimeterX wall (which 403s a cold session):
RENDER_CHANNEL=chrome+RENDER_USER_DATA_DIR=<dedicated dir>+RENDER_EXTRA_ARGS=--use-angle=d3d11render(url, warm=[...homepage, category...])— step down to the deep page so the anti-bot cookie matures instead of cold-linking.render(url, press=["Escape"])— dismiss Facebook Marketplace's login overlay.
See docs/anti-bot-bypass.md for the full playbook — the wall tiers, the detection-signal table, the exact PerimeterX recipe, pacing/cooldown notes, and when to reach for a managed unblocker instead.
Testing
Unit tests are hermetic — they stub curl_cffi/mcp and mock the browser, so no native
libs, browser, or network are needed. They cover the request/retry loop, the streamed byte cap,
Retry-After handling, challenge detection, extraction dispatch, the tiered render fallback,
and the render engine (including its asyncio-safety) — ~92% line coverage across both modules.
python -m pip install -r requirements-dev.txt
python -m pytest tests/ # fast, offline
python -m coverage run -m pytest tests/ ; python -m coverage report proxy_browser_server.py
Live smoke test (AliExpress)
tests/smoke_aliexpress.py drives the real server against AliExpress — exercising the
full Chrome-impersonation path, retries, byte cap, and HTML→markdown extraction end to end.
Run it from the same env the MCP runs in (needs the runtime deps installed):
python tests/smoke_aliexpress.py # "moza racing steering wheel", cheapest-first
python tests/smoke_aliexpress.py "moza r9 wheelbase" # custom query
python tests/smoke_aliexpress.py --raw "moza ks wheel" # raw HTML instead of markdown
The same check runs under pytest when opted in:
$env:RUN_SMOKE=1 ; python -m pytest tests/test_smoke.py::test_live_aliexpress_moza
AliExpress is heavily JS-rendered and anti-bot defended. The HTTP path gets a real
200but thin/challenge HTML; the render tier passes the wall and returns the full product grid.
Live render test (opt-in)
With the render deps installed, exercise the real browser end to end:
$env:RUN_RENDER=1 ; python -m pytest tests/test_browser_engine.py::test_live_render_executes_js_and_returns_html
Limitations
- JavaScript is handled by the render tier, not the
HTTP engine. Plain
curl_cffican't run JS; install the render deps (patchright + Chromium) and userender="auto"/render="always"for JS-rendered or challenge-walled sites. Without the render deps installed, JS-heavy pages come back thin (and are flagged when it's a known anti-bot wall). - Render tier is heavier. A browser launch costs ~1–3 s and real memory; it only fires on
demand (challenge/thin page in
auto, or explicitrender), not on every request. - IP reputation still matters. Even the browser can be IP-flagged after abuse; for the
most aggressive sites pair with a residential
PROXY_URLand/orRENDER_HEADLESS=0. - Respect Terms of Service and rate limits. This tool is for legitimate automation and research; the built-in per-host throttle, request jitter, and 1–2 request cap keep it polite — don't hammer sites.
Project layout
headless-proxy-mcp/
├── proxy_browser_server.py # the MCP server — HTTP engine, tools, tiered fallback
├── browser_engine.py # headless-browser render engine (patchright/playwright)
├── requirements.txt # runtime dependencies (HTTP engine)
├── requirements-render.txt # optional: headless browser render tier
├── requirements-dev.txt # test dependencies (pytest, coverage)
├── .env.example # configuration reference
├── .gitignore
├── README.md
├── docs/
│ └── anti-bot-bypass.md # playbook: wall tiers, PerimeterX recipe, FB trick
└── tests/
├── conftest.py # stubs curl_cffi/mcp so tests run offline
├── test_proxy_browser.py # hermetic unit tests — HTTP engine + tiered fallback
├── test_browser_engine.py # hermetic unit tests — render engine (mocked browser)
├── smoke_aliexpress.py # live smoke test runner (real network)
└── test_smoke.py # smoke-test unit coverage + opt-in live check
License
MIT (or your preference).
Установка Proxy Browser Server
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/nullsection/headless-proxy-mcpFAQ
Proxy Browser Server MCP бесплатный?
Да, Proxy Browser Server MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Proxy Browser Server?
Нет, Proxy Browser Server работает без API-ключей и переменных окружения.
Proxy Browser Server — hosted или self-hosted?
Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.
Как установить Proxy Browser Server в Claude Desktop, Claude Code или Cursor?
Открой Proxy Browser Server на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Playwright
Browser automation, scraping, screenshots
автор: MicrosoftPuppeteer
Browser automation and web scraping.
автор: modelcontextprotocolopentabs-dev/opentabs
Plugin-based MCP server + Chrome extension that gives AI agents access to web applications through the user's authenticated browser session. 100+ plugins with a
автор: opentabs-devrobhunter/agentdeals
1,500+ developer infrastructure deals, free tiers, and startup programs across 54 categories. Search deals, compare vendors, plan stacks, and track pricing chan
автор: robhunterCompare Proxy Browser Server with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории browse
