Skip to content
← Back to blog
Playwright and browser automation

How to connect Playwright MCP to Chrome through Remote Debugging

8 min read

Written by: Jonathan Reis on

Playwright MCP was connected to Edge on localhost:9222 while Chrome exposed Remote Debugging on a dynamic port. The path to a working connection required separating the browser, port, extension, and MCP endpoint.

OpenGraph preview image for this article. How to connect Playwright MCP to Chrome through Remote Debugging

The Playwright does not control “Chrome” merely because Chrome is installed on the machine. It controls a browser that has exposed a Chrome DevTools Protocol (CDP) session and whose endpoint has been configured in the automation client.

That distinction surfaced while configuring OpenCode to use the @playwright/mcp server and list the tabs open in Chrome. The tool tried to connect to ws://localhost:9222, received 403 Forbidden, and the first suspicion was the wrong browser. Edge was using port 9222; Chrome was open, but it was not exposed at that endpoint.

The goal was not to write an isolated E2E test. It was to give an agent controlled access to a real Chrome session, without blindly navigating an Edge window or launching a disposable browser copy. That changes the diagnosis: the session, its profiles, and its tabs already exist, and the work is connecting the MCP client to the intended instance.

What has to line up

There are four independent pieces in this flow:

  • The browser that is running: Chrome, Edge, or Chromium.
  • Remote Debugging, which creates a CDP control surface.
  • The port and WebSocket endpoint exposed by the browser.
  • Playwright MCP, which must point at that endpoint.

An extension may help authorize or integrate an agent, but it does not automatically turn one Chrome-based browser session into another. Installing the same extension in two browsers also does not make MCP switch between them.

Check the port before changing Chrome

The first step was to find who owned 9222 instead of assuming it belonged to Chrome:

lsof -nP -iTCP:9222

The main process was Microsoft Edge. The Playwright MCP command line also showed the configured endpoint:

--cdp-endpoint=ws://localhost:9222/devtools/browser/...

That explained the behavior: Playwright was trying to talk to the browser associated with port 9222, not to any browser open on the desktop.

Why curl can be misleading

With traditional CDP setups, these endpoints often respond:

curl http://127.0.0.1:9222/json/version
curl http://127.0.0.1:9222/json/list

But Remote Debugging started by Chrome’s integration can return 404 for those paths and still work for the expected client. The decisive test is not just whether an HTTP endpoint responds. It is whether the client can connect through the protocol and list the available contexts or tabs.

Enable Chrome Remote Debugging

In Chrome, open:

chrome://inspect/#remote-debugging

Turn on Allow remote debugging for this browser instance. The warning is explicit: an authorized external client can read cookies, saved data, and site content, and navigate to any URL. This is not a harmless developer preference; it grants full browser control. The page also links to Chrome DevTools MCP, which explains Chrome’s maintained connection model.

After enabling it, Chrome displayed:

Server running at: 127.0.0.1:59807

The easy-to-miss detail is the port. Chrome did not need to use 9222; it selected 59807. That port may change between sessions, so do not hard-code it without checking the value currently shown by the browser or integration.

Change the Playwright MCP endpoint

While MCP was still configured for 9222, the next attempt failed with:

connect ECONNREFUSED ::1:9222

That is different from the initial 403 Forbidden. The 403 meant there was a server at the port but it rejected that connection. ECONNREFUSED meant there was no accessible server at the address resolved for localhost:9222.

MCP had to be pointed at the Chrome session, using the port Chrome reported. The exact command depends on how MCP was launched, but the concept is always the same:

npx @playwright/mcp@latest \
  --cdp-endpoint=http://127.0.0.1:59807

In an extension-based integration or Chrome DevTools MCP flow, the Learn about connecting to Chrome DevTools MCP link may provide the endpoint and connection procedure. The operational point is to update the client that was still attached to Edge; installing the Chrome extension by itself does not change an already-running MCP session. OpenCode only discovers servers declared in its MCP configuration: installing @playwright/mcp does not automatically register Chrome as a tool available to the agent.

Configure the server in the MCP client

When the MCP client uses local servers declared in JSON, the configuration looks like this:

"playwright-chrome": {
  "command": [
    "/opt/homebrew/bin/npx",
    "-y",
    "@playwright/mcp@latest",
    "--cdp-endpoint=ws://localhost:59807/devtools/browser/<browser-session-id>",
    "--cdp-timeout=60000",
    "--output-dir=/tmp/playwright-mcp",
    "--output-mode=stdout"
  ],
  "enabled": false,
  "type": "local"
}

The --cdp-endpoint value differs from the earlier http://127.0.0.1:59807 example: here the client receives the full WebSocket URL, including the browser session identifier. Do not invent or blindly reuse that identifier. Copy the endpoint provided by Chrome DevTools MCP or by the mechanism that started the session. enabled: false is also deliberate: some clients keep the server registered but require explicit activation before starting a process that will have full control of the browser. If your client uses a different convention, enable the server through its own configuration.

The /opt/homebrew/bin/npx path is specific to a Homebrew installation on Apple Silicon. On another machine, find the path with command -v npx and replace only the executable. The /tmp/playwright-mcp directory stores server output; it does not connect the browser. The connection is determined by --cdp-endpoint. The Playwright MCP documentation lists the server options and is the right reference when the package version changes.

Confirm the connection in the right browser

After changing the Playwright endpoint, the tab listing identified Chrome:

Extensions - Playwright Extension
chrome://extensions/?id=mmlmfjhmonkocbjadbfplnigmagldckm

Inspect with Chrome Developer Tools
chrome://inspect/#remote-debugging

YouTube
https://www.youtube.com/

This confirmation is more useful than looking at the port alone. It proves that the client reached the intended session, that the browser answered through the protocol, and that the available tabs belong to the expected Chrome instance.

What the extension does, and what it does not do

Edge had an extension called Playwright Extension, whose description said that it connects the browser to AI agents through Playwright MCP. That made the extension a reasonable suspect, but the later evidence pointed elsewhere: edge://inspect/#remote-debugging reported that Remote Debugging was enabled and that the server was listening on 9222.

The useful separation is:

  • Remote Debugging exposes the browser’s CDP surface.
  • MCP uses that surface to control pages.
  • The extension may participate in authorization or an agent-specific workflow.
  • The extension should not be treated as synonymous with “the browser is listening on 9222”.

To investigate an extension, disable it, close every browser window, launch the browser again, and check which process owns the port. If the main browser process still listens, the source is startup configuration, browser policy, or the Remote Debugging mechanism rather than that extension.

Security: keep the server local

Chrome reported 127.0.0.1, which limits the listener to the local machine. Even so, any process that can reach the endpoint may control the browser with the privileges of the open session. That includes authenticated sites and data available in the profile.

Use Remote Debugging only with trusted clients, do not share the endpoint, do not expose the port to the network, and avoid testing with a profile that contains data the agent does not need. A separate automation profile reduces the blast radius but does not remove the control granted to the client.

The complete flow

To repeat the diagnosis without mixing Edge, Chrome, and MCP:

1. Open chrome://inspect/#remote-debugging in Chrome.
2. Enable Remote Debugging and note the displayed port.
3. Confirm that the process and endpoint belong to Chrome.
4. Update Playwright MCP's --cdp-endpoint for that session.
5. Restart MCP if it keeps the previous endpoint in memory.
6. List the tabs and confirm a chrome:// URL or a page you recognize.

If you see 403, investigate the allowed origin and whether the client matches that endpoint. If you see ECONNREFUSED, investigate the host, port, browser lifetime, and whether the server was stopped. Do not treat the two errors as variations of the same failure.

The port belongs to the session, not the installed browser

One practical consequence is that updating Chrome, installing the extension, or opening a new window does not guarantee that the old port remains valid. The server may stop when the browser instance closes, or the next launch may receive another port. Development scripts should therefore discover the endpoint at session start or consume the configuration supplied by MCP instead of assuming that 59807 is permanent. Chrome and Edge can also run at the same time, as long as each browser exposes a different port and each client keeps a clear association with its intended browser.

Checklist

  • Remote Debugging is enabled in the browser you intend to control.
  • The port came from the current session, not from another browser.
  • MCP was restarted or reconfigured with the correct endpoint.
  • The tab listing confirms the expected browser.
  • The endpoint is bound to 127.0.0.1 and the client is trusted.
  • The automation profile contains no more data than the workflow needs.

The fix was not the extension. It was stopping the assumption that OpenCode connects to “the computer” and following the concrete chain: OpenCode, MCP server, browser, CDP, port, and endpoint. Once that chain is explicit, 403, 404, and ECONNREFUSED stop looking like random messages.

Related postHow to build a VS Code extension: I read the OpenCode one and wrote my own10 min readWritten by: Jonathan Reis on