NEWScrapingAnt MCP for Claude Code, Cursor & Windsurf — try it free →
Skip to main content

Playwright MCP Proxy Setup: --proxy-server, Authentication and Bypass

· 6 min read
Oleg Kulyk
Co-Founder @ ScrapingAnt

Connecting Playwright MCP to Proxy Servers

Updated 2026-10-26

Rewritten around tested setups. The earlier config examples pointed at a third-party proxy host and used a capabilities key, and the page did not show how proxy authentication behaves. The proxy settings below were run on 2026-10-26 with @playwright/mcp 0.0.83 (headless, isolated profile) against a local proxy lab.

Playwright MCP gives an AI assistant a real browser through the Model Context Protocol. To send that browser's traffic through a proxy, pass --proxy-server in the server's arguments. If the proxy needs a username and password, put them in a config file: credentials inside the --proxy-server URL do not work.

The short answer: --proxy-server​

Add the flag to the args of the Playwright MCP entry in your client's MCP config. This is the mcpServers shape used by Claude Desktop, Cursor and similar clients; VS Code puts the same entry under servers:

{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--proxy-server", "http://127.0.0.1:8901"]
}
}
}

The value can be http://host:port or socks5://host:port. To check it, the lab started Playwright MCP 0.0.83 with the same flag (plus --headless --isolated), asked it to open http://httpbin.org/headers, and read the page. The lab's proxies add an X-Lab-Proxy header to plain-HTTP requests, so the echoed headers show which proxy the browser used:

$ node cases/navigate.mjs http://httpbin.org/headers --proxy-server http://127.0.0.1:8901
X-Lab-Proxy: proxy-a-8901

Proxy authentication: use a config file​

Most paid proxies need a username and password. Chromium does not take them from the proxy URL, so this fails:

$ node cases/navigate.mjs http://httpbin.org/headers --proxy-server http://lab:p%40ss%23w0rd@127.0.0.1:8899
net::ERR_INVALID_AUTH_CREDENTIALS

Put the proxy in a config file instead. browser.launchOptions is passed to Playwright's launch call, so proxy takes the same server, username, password and bypass fields as in Playwright itself:

{
"browser": {
"launchOptions": {
"proxy": {
"server": "http://127.0.0.1:8899",
"username": "lab",
"password": "p@ss#w0rd"
}
}
}
}

Save it as proxy-auth.json and start the server with --config:

{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--config", "/absolute/path/to/proxy-auth.json"]
}
}
}
$ node cases/navigate.mjs http://httpbin.org/headers --config configs/proxy-auth.json
X-Lab-Proxy: auth-proxy-8899

The password goes in as plain text, with no URL encoding. With a wrong password the navigation does not fail with an error: the page the assistant reads is the proxy's refusal.

$ node cases/navigate.mjs http://httpbin.org/headers --config configs/proxy-auth-wrong.json
Proxy Authentication Required

If an assistant reports a page that says "Proxy Authentication Required", check the credentials in the config file. Keep the file out of version control, since the password is in it.

ScrapingAnt API

Skip the proxy setup: a hosted MCP server​

If the browser is only there to read pages, ScrapingAnt's MCP server gives your assistant the pages directly. Each tool call takes browser, proxy_type and proxy_country, and ScrapingAnt fetches the page with its own browser and proxies, so the assistant can read a page through a residential IP in any country on the documented list with no proxy credentials in your config. There is a free plan to start.

{
"mcpServers": {
"scrapingant": {
"url": "https://api.scrapingant.com/mcp",
"transport": "streamableHttp",
"headers": { "x-api-key": "YOUR_API_KEY" }
}
}
}

The same connection from the MCP TypeScript SDK, calling the tool the way an assistant would:

$ node cases/scrapingant_mcp.mjs
tools: get_web_page_html, get_web_page_markdown, get_web_page_text
exit: JP Ina

The client config above is the one the MCP server docs give for Claude Desktop, Cline and Windsurf; they also list VS Code, Cursor and Claude Code. The run is get_web_page_text on https://ipinfo.io/json with browser: false, proxy_type: "residential" and proxy_country: "JP", run on 2026-10-26 (the script prints country and city, not the IP).

Send some hosts direct with --proxy-bypass​

--proxy-bypass takes a comma-separated list of domains that skip the proxy, for example internal hosts or localhost services the assistant tests against:

$ node cases/navigate.mjs http://httpbin.org/headers --proxy-server http://127.0.0.1:8901 --proxy-bypass httpbin.org
no X-Lab-Proxy header (direct)

In a config file, the same list goes in proxy.bypass.

Set the proxy with environment variables​

Both flags have environment variables: PLAYWRIGHT_MCP_PROXY_SERVER and PLAYWRIGHT_MCP_PROXY_BYPASS. A stdio MCP server does not inherit your whole shell environment (the MCP SDK's stdio transport passes on only a few system variables), so set them in the server's env block:

{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"],
"env": { "PLAYWRIGHT_MCP_PROXY_SERVER": "http://127.0.0.1:8901" }
}
}
}
$ env PLAYWRIGHT_MCP_PROXY_SERVER=http://127.0.0.1:8901 node cases/navigate.mjs http://httpbin.org/headers
X-Lab-Proxy: proxy-a-8901

The same proxy in a Playwright script​

Outside MCP, the setting is identical: pass proxy to launch(), with credentials in their own fields.

import { chromium } from 'playwright';

const browser = await chromium.launch({
proxy: { server: 'http://127.0.0.1:8899', username: 'lab', password: 'p@ss#w0rd' },
});
const page = await browser.newPage();
const response = await page.goto('http://httpbin.org/headers');
const headers = JSON.parse(await page.innerText('body')).headers;
console.log(response.status(), 'X-Lab-Proxy:', headers['X-Lab-Proxy']);
await browser.close();
200 X-Lab-Proxy: auth-proxy-8899

For per-context proxies and the Python API, see how to use a proxy in Playwright; for a pool of proxies, see proxy rotation in Playwright.

Troubleshooting​

What the assistant reportsUsual cause
net::ERR_INVALID_AUTH_CREDENTIALSCredentials inside the --proxy-server URL; move them to a config file
A page saying "Proxy Authentication Required"Wrong username or password in the config file
net::ERR_PROXY_CONNECTION_FAILEDWrong proxy host or port, or the proxy is down
Pages load but not through the proxyThe host matches --proxy-bypass, or an environment variable was set in your shell instead of the client's env block

Examples tested on 2026-10-26 with Node.js 22.20.0, @playwright/mcp 0.0.83 (headless), playwright 1.64.1 and @modelcontextprotocol/sdk 1.32.2. Code: scrapingant-examples/examples/playwright-mcp-server-proxy.

This article was drafted with AI assistance from a tested evidence packet and reviewed by the named author, who is responsible for the code, measurements and corrections.

Give your AI agent the live web

The ScrapingAnt MCP server lets Claude, Cursor and other MCP clients read any page as clean Markdown.