Enables running Playwright tests in a remote VS Code environment (such as GitHub Codespaces) while launching and driving the actual browser process on your local machine.
This extension is a UI wrapper around the tunneling/runtime library @rushstack/playwright-browser-tunnel. It starts/stops the local browser host process and forwards Playwright's WebSocket traffic between the remote test runner and your local browser.
Before running your Playwright tests in a remote environment, you must first start the browser tunnel:
- Open the VS Code Command Palette (
Ctrl+Shift+PorCmd+Shift+Pon macOS) - Search for and run "Playwright: Start Playwright Browser Tunnel"
- The tunnel will begin polling for connections from your remote environment
- Now you can run your Playwright tests in the remote workspace
To stop the tunnel, open the Command Palette and run "Playwright: Stop Playwright Browser Tunnel".
This extension requires VS Code's terminal shell integration to be enabled. Ensure the following setting is enabled in your VS Code settings:
"terminal.integrated.shellIntegration.enabled": trueThis is typically enabled by default, but if you have explicitly disabled it, the extension will not work correctly.
If you want the browser tunnel to start automatically when VS Code opens, you can add the following to your workspace settings (.vscode/settings.json):
{
"playwright-local-browser-server.autoStart": true
}Security note: Auto-start is disabled by default because the tunnel allows a remote environment to launch browser processes on your local machine. Only enable auto-start for workspaces you trust.
- Remote side (Codespace): your Playwright test fixture starts a WebSocket tunnel server on a well-known port (default
56767) and a small local HTTP endpoint used by the Playwright client. - Local side (your VS Code UI machine): this extension starts a
PlaywrightTunnelinpoll-connectionmode and connects to the forwarded tunnel port. - After a handshake (browser type, launch options, Playwright version), the extension installs the requested Playwright/browser as needed, launches a local
browserServer, and begins bidirectional forwarding.
For this extension to work, your Playwright tests must use a custom fixture that starts the tunnel server on the remote side.
Use tunneledBrowser() from @rushstack/playwright-browser-tunnel inside your fixture’s browser override (so that the Playwright client in the remote environment connects through the tunnel).
Reference implementation: apps/playwright-browser-tunnel/tests/testFixture.ts
Example:
import { test as base } from '@playwright/test';
import { tunneledBrowser } from '@rushstack/playwright-browser-tunnel';
export const test = base.extend({
browser: [
async ({ browserName, launchOptions, channel, headless }, use) => {
await using tunnel = await tunneledBrowser(browserName, {
channel,
headless,
...launchOptions
});
await use(tunnel.browser);
},
{ scope: 'worker' }
]
});To help remote test code detect whether this extension is installed/active, the extension writes a marker file named .playwright-local-browser-server-extension-installed.txt into the remote environment’s os.tmpdir() when VS Code is connected to a remote workspace.
On the test (remote) side, you can call extensionIsInstalled() from @rushstack/playwright-browser-tunnel, which simply checks for that marker file:
import { extensionIsInstalled } from '@rushstack/playwright-browser-tunnel';
if (!(await extensionIsInstalled())) {
throw new Error(
'Playwright Local Browser Server VS Code extension not detected. Install/enable it and ensure VS Code is connected to the remote workspace.'
);
}sequenceDiagram
participant PT as Playwright Tests
participant BF as Browser Fixture
participant TS as Tunnel Server (WebSocket)
participant HS as HTTP Server
participant VSC as VS Code Extension
participant BS as Browser Server
participant LB as Local Browser
Note over PT,LB: Context: Enables local browser testing for remote VS Code environments (e.g., Codespaces)
PT->>BF: Trigger custom browser fixture
par Fixture Setup
BF->>HS: Launch localhost HTTP server
BF->>TS: Launch WebSocket tunnel server (well-known port)
end
BF->>HS: browser.connect('http://localhost:<port>? browser=chromium&launchOptions={}')
loop Polling
VSC->>TS: Poll for connection (well-known port)
end
TS-->>VSC: WebSocket connection established
BF->>VSC: Send handshake (browser type, launchOptions, Playwright version)
VSC->>VSC: Install requested Playwright version
VSC->>VSC: Install requested browser
VSC->>BS: Launch browserServer via Playwright API
BS->>LB: Start local browser instance
VSC->>BS: Create WebSocket client connection
VSC->>TS: Send acknowledgement (ready to go)
par Setup Forwarding
Note over BF,TS: Fixture: PT ↔ Tunnel Server
Note over VSC,BS: Extension: Tunnel Server ↔ Browser Server
end
BF->>BF: Flush buffered messages from test
rect rgb(200, 230, 200)
Note over PT,LB: Transparent bidirectional communication established
PT->>BF: Playwright commands
BF->>TS: Forward to tunnel
TS->>VSC: Forward to extension
VSC->>BS: Forward to browser server
BS->>LB: Execute in local browser
LB-->>BS: Response
BS-->>VSC: Forward response
VSC-->>TS: Forward to tunnel
TS-->>BF: Forward to fixture
BF-->>PT: Return to test
end
Note over PT,LB: 🎉 Profit! Local browser available to remote tests transparently
As an alternative to the browser tunnel, this extension also supports MCP Tunnel mode. Instead of launching a browser server and forwarding WebSocket traffic, it runs a local MCP server (e.g. @playwright/mcp) on your machine and proxies MCP protocol messages to/from the codespace.
[MCP Client (Cursor/Claude Code)] --> stdio --> [mcp-codespace-proxy.mjs] --> TCP :56768
(codespace) (codespace) |
VS Code port forwarding
|
[McpTunnel in extension] --> TCP :56768 --> [@playwright/mcp process] --> local browser
(local machine) (local machine)
1. Start MCP Tunnel in VS Code
Open the Command Palette and run "Playwright: Start MCP Tunnel", or use the status bar menu.
2. Copy the proxy script to your codespace
Copy mcp-codespace-proxy.mjs (included with this extension) to your codespace. This is a standalone Node.js script with zero external dependencies — it only uses built-in net and readline modules.
3. Configure your MCP client on the codespace
Point your MCP client to the proxy script. For example, in Claude Code (.claude/settings.json):
{
"mcpServers": {
"playwright": {
"command": "node",
"args": ["/path/to/mcp-codespace-proxy.mjs", "56768"]
}
}
}The port must match the playwright-local-browser-server.mcpTunnelPort setting (default: 56768).
4. Use MCP tools from your codespace
The MCP client will communicate through the proxy to the locally-running @playwright/mcp server, which drives a real browser on your local machine.
sequenceDiagram
participant MC as MCP Client (Codespace)
participant MP as mcp-codespace-proxy.mjs
participant PF as VS Code Port Forwarding
participant EXT as VS Code Extension (Local)
participant MCP as @playwright/mcp (Local)
participant LB as Local Browser
Note over MC,LB: MCP Tunnel Mode: Local MCP server proxied to codespace
MP->>MP: Listen on TCP port (56768)
loop Polling
EXT->>PF: Connect to localhost:56768
PF->>MP: Forward TCP connection
end
MP-->>EXT: TCP connection established
EXT->>MCP: Spawn @playwright/mcp (stdio)
rect rgb(200, 230, 200)
Note over MC,LB: Transparent bidirectional MCP communication
MC->>MP: MCP request (stdin)
MP->>PF: Forward via TCP
PF->>EXT: Forward to extension
EXT->>MCP: Write to MCP stdin
MCP->>LB: Execute browser action
LB-->>MCP: Result
MCP-->>EXT: MCP response (stdout)
EXT-->>PF: Forward via TCP
PF-->>MP: Forward to proxy
MP-->>MC: MCP response (stdout)
end
This extension contributes the following commands:
- Playwright: Start Playwright Browser Tunnel (
playwright-local-browser-server.start) - Playwright: Stop Playwright Browser Tunnel (
playwright-local-browser-server.stop) - Playwright: Start MCP Tunnel (
playwright-local-browser-server.startMcp) - Playwright: Stop MCP Tunnel (
playwright-local-browser-server.stopMcp) - Playwright Local Browser Server: Manage Launch Options Allowlist (
playwright-local-browser-server.manageAllowlist) - Playwright Local Browser Server: Show Log (
playwright-local-browser-server.showLog) - Playwright Local Browser Server: Show Settings (
playwright-local-browser-server.showSettings) - Playwright Local Browser Server: Show Tunnel Menu (
playwright-local-browser-server.showMenu) — status bar menu
playwright-local-browser-server.autoStart(default:false) — automatically starts the tunnel when the extension activates.playwright-local-browser-server.promptBeforeLaunch(default:true) — show a confirmation prompt before launching the browser server with the requested launch options. This helps protect against potentially malicious launch options from compromised environments.playwright-local-browser-server.tunnelPort(default:56767) — port used by the remote tunnel server.playwright-local-browser-server.mcpTunnelPort(default:56768) — port for the MCP tunnel. Must match the port used bymcp-codespace-proxy.mjson the codespace side.playwright-local-browser-server.mcpCommand(default:npx @playwright/mcp) — command to start the local MCP server. The MCP server must use stdio transport.
- The browser tunnel connects to
ws://127.0.0.1:56767on the local machine. In Codespaces, make sure the remote port is forwarded so it is reachable aslocalhostfrom your VS Code UI environment. - The MCP tunnel connects to
127.0.0.1:56768by default. The codespace proxy listens on this port and VS Code automatically forwards it. - For the underlying API and examples, see
@rushstack/playwright-browser-tunnel.