Driving Google Chrome via Playwright MCP From WSL
Here’s how to make Playwright MCP drive the Chrome profile you’re already signed into on Windows, from WSL, through the extension relay.
Prerequisites
- Playwright extension
installed in the Chrome profile that
chrome.exeopens by default. - The token from the extension’s status page.
- Mirrored networking. The relay binds a random port on loopback inside WSL and
puts that address in the connect URL it opens, the extension resolves that
127.0.0.1against Windows’ loopback. Under NAT the VM has its own loopback behind a virtual adapter, so the address points at the host’s loopback where nothing is listening. Mirrored mode attaches WSL to the host’s interfaces, so both sides share one loopback.
Edit C:\Users\<you>\.wslconfig and add the lines below.
[wsl2]
networkingMode=mirrored
wsl --shutdown and start WSL again.
Running It
PLAYWRIGHT_MCP_EXTENSION_TOKEN=<token> \
PLAYWRIGHT_MCP_USER_DATA_DIR='C:\Users\<you>\AppData\Local\Google\Chrome\User Data' \
playwright-mcp --extension \
--executable-path "/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
--extensionselects the extension branch, without it you get the persistent profile branch and a Linux Chromium.--executable-pathpoints atchrome.exe, WSL executes.exefiles directly, so the connect tab opens in Windows. Without it Playwright launches its own Linux Chromium, where the extension doesn’t exist.PLAYWRIGHT_MCP_USER_DATA_DIRhas to be the profile path Chrome is already running with, Chrome matches its singleton lock on the user data directory and forwards the connect URL to that instance. A different path starts a new browser without the extension, and you getERR_BLOCKED_BY_CLIENT.PLAYWRIGHT_MCP_EXTENSION_TOKENthe relay only waits for a connection when a token is set, and the extension rejects a mismatched one. Without it you wait 30 seconds for “did not connect”.
The default channel is already chrome, so bare --extension is enough. Don’t
add --cdp-endpoint, --port, --host, --user-data-dir, --isolated,
--browser, --profile-dir-name or --no-sandbox, the last one only applies to
the Linux chromium channel anyway.
A chrome-extension://<id>/connect.html?... tab opens in Chrome and it says
“Playwright Extension started debugging this browser”, from there the tools
operate on that profile.
Tool Calls
- Fire them in order and wait for each response, navigate, wait for the
navigation response,
browser_wait_forfor a few seconds, thenbrowser_evaluate. Firing them together gets youExecution context was destroyedorNo open pages available. - The relay binds port
0and generates a random UUID path on every start, so a new connect tab opens each run. - The token is per install, reinstalling the extension changes it.
Client Configuration
The server speaks MCP over stdio, point your client at the command above.
- Command:
playwright-mcp - Arguments:
--extensionand--executable-path "/mnt/c/Program Files/Google/Chrome/Application/chrome.exe" - Environment:
PLAYWRIGHT_MCP_USER_DATA_DIRandPLAYWRIGHT_MCP_EXTENSION_TOKEN
For example, this is how it looks in OpenCode’s opencode.json, with the token
read from the environment:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"servers": {
"playwright": {
"type": "local",
"command": [
"playwright-mcp",
"--extension",
"--executable-path", "/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
],
"environment": {
"PLAYWRIGHT_MCP_USER_DATA_DIR": "C:\\Users\\<you>\\AppData\\Local\\Google\\Chrome\\User Data",
"PLAYWRIGHT_MCP_EXTENSION_TOKEN": "{env:PLAYWRIGHT_MCP_EXTENSION_TOKEN}"
}
}
}
}
}