Skip to content

fix(mcp): reconnect to the browser after disconnect - #41966

Merged
Yury Semikhatsky (yury-s) merged 4 commits into
microsoft:mainfrom
yury-s:fix-41874
Aug 3, 2026
Merged

fix(mcp): reconnect to the browser after disconnect#41966
Yury Semikhatsky (yury-s) merged 4 commits into
microsoft:mainfrom
yury-s:fix-41874

Conversation

@yury-s

Copy link
Copy Markdown
Member

Summary

  • Recreate the MCP backend when its browser disconnected between tool calls, so the next call transparently reconnects: --extension reopens connect.html (silent with token bypass), cdp mode reconnects to the endpoint, persistent/isolated modes relaunch the browser.
  • Stop the single-shot extension relay and its http server once the browser connection drops.
  • Relaunch a crashed shared browser (--isolated/--shared-browser-context with multiple HTTP clients) instead of caching the dead one until all clients disconnect.

Fixes #41874

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Comment thread tests/mcp/cdp.spec.ts
});
});

test('transparently reconnects when the remote browser is restarted', async ({ cdpServer, startClient, server }) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a good thing? What if that's some completely unrelated browser? Do we have any evidence this is a useful scenario?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what has been asked for the extension. We discussed it offline ad decided to make it transpantly reconnect if the remote connection is lost for whatever reason. It especially makes sense when you connect from and mcp client over stdio which doesn't restart the server if it fails and would require manual intervention. When the server is reconnected the agent will see that the state has changed (due to a user action, crash, update or what not) and adapt.

Comment thread tests/mcp/http.spec.ts
});

test('http transport isolated closes the browser despite an earlier failed backend creation', async ({ serverEndpoint, server }, testInfo) => {
// A failed backend creation must not leak the client count, otherwise the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this comment mean?

@yury-s Yury Semikhatsky (yury-s) Jul 24, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a bug in program.ts, see new clientCount--; in the catch block. But I agree the comment does not make sense out of that context. Will remove.

Comment thread tests/mcp/http.spec.ts
});
});

test('http transport isolated multiclient relaunches a crashed shared browser', async ({ serverEndpoint, server }, testInfo) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a common scenario - with a crashed browser? I think this is more common when the user closes the browser window manually (for whatever reason) - do we want to relaunch it in this case?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I believe this makes sense as it is the mcp server that launched the browser. The same logic as above.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Dispose the backend when its browser disconnects between tool calls, so
that the next call transparently creates a fresh one: --extension
reopens connect.html, cdp mode reconnects to the endpoint,
persistent/isolated modes relaunch the browser. Drop the cached shared
browser when it disconnects and balance the client count when backend
creation fails. Stop the single-shot extension relay and its http
server once the browser connection drops.

Fixes: microsoft#41874
Drop the 'disposed' event and the disposeCallback parameter: the server
resets its backend on 'disconnected', and program.ts tracks the
context/browser teardown itself to tell a dead browser from a
deliberate close.
@github-actions

Copy link
Copy Markdown
Contributor

Test results for "MCP"

3 failed
❌ [firefox] › mcp/cli-core.spec.ts:179 › dialog-dismiss @mcp-windows-latest-firefox
❌ [firefox] › mcp/dashboard.spec.ts:108 › should activate session when show is called with -s @mcp-windows-latest-firefox
❌ [msedge] › mcp/cli-core.spec.ts:168 › dialog-accept @mcp-windows-latest-msedge

7845 passed, 1278 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

Hi, I'm the Playwright bot and I took a look at the CI failures on the latest run.

🟢 CI is clear — all three failures are pre-existing flakes

The three failures live in mcp/cli-core.spec.ts (dialog-dismiss, dialog-accept) and mcp/dashboard.spec.ts (session activation) — files this PR doesn't touch. Each one flips verdict on SHAs the PR can't be responsible for, so none is a regression.

Details

Overall: no failure is attributable to this PR. The diff is confined to the MCP backend reconnect path (browserBackend.ts, cdpRelay.ts, extensionContextFactory.ts, program.ts, server.ts) plus the launch/cdp/http/extension tests. The plain dialog-click and dashboard session-activation flows that failed never exercise a disconnect/reconnect.

Pre-existing flake / infra

Triaged by the Playwright bot - agent run

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, but Dima has questions in the tests.

Yury Semikhatsky (yury-s) added a commit to microsoft/playwright-mcp that referenced this pull request Aug 6, 2026
## What's New

### Tool Improvements

- **`browser_take_screenshot` — WebP format** — New `type` option to
pick the image format (`png`, `jpeg` or `webp`); when unset, the format
is inferred from the filename extension
([#41152](microsoft/playwright#41152))
- **`--codegen` — more languages** — Code generation now supports
`python`, `java` and `csharp` in addition to `typescript`
([#42106](microsoft/playwright#42106))
- **Configurable settle delay** — New `--timeout-settle` flag (and
`timeouts.settle` config option) to control how long to wait after each
action for triggered work (navigations, requests) to settle, defaults to
500ms ([#41924](microsoft/playwright#41924))

## Fixes

- Aria snapshot capture is skipped when the response discards it
([#41923](microsoft/playwright#41923))
- New `--snapshot-boxes` flag (and `snapshot.boxes` config option) to
enable bounding boxes in snapshots globally — previously this was only
available per command
([#42102](microsoft/playwright#42102))
- Reconnect to the browser after a disconnect
([#41966](microsoft/playwright#41966))
- Report malformed JSON config instead of silently falling back to INI
parsing ([#41909](microsoft/playwright#41909))
- Clear the dialog modal state when a dialog is closed out of band
([#42032](microsoft/playwright#42032))
- Detect downloads via the download event instead of guessing from
`net::ERR_ABORTED` navigation errors
([#41933](microsoft/playwright#41933))
- Surface the missing executable path when a browser isn't installed
([#41941](microsoft/playwright#41941))
- Escape user input in codegen output
([#41962](microsoft/playwright#41962))
- Removed the stale `--output-mode` CLI option
([#41833](microsoft/playwright#41833))

### Browser Extension

- Validate `Host` and `Origin` headers on CDP relay WebSocket upgrades
([#42103](microsoft/playwright#42103))
- Launch the Chrome profile that has the extension installed
([#41939](microsoft/playwright#41939))
- Pass `noDefaults` for extension CDP connections
([#42119](microsoft/playwright#42119))
- Mention `PLAYWRIGHT_MCP_EXECUTABLE_PATH` in the error shown when the
browser executable is not found
([#42122](microsoft/playwright#42122))
- Removed support for extension protocol v1
([#41857](microsoft/playwright#41857))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: --extension mode: relay does not reconnect to browser extension after disconnect

3 participants