fix(mcp): refuse browser_close when the browser context is shared - #42495
Conversation
browser_close disposes the backend, but with a shared browser no 'disconnected' event fires, so the server kept handing out the disposed backend. Let the server ask the backend whether it disposed itself after each tool call and drop the cached one if so. Also detach the backend listeners from the browser context on dispose so they do not accumulate on a long-lived shared context. This replaces the approach from microsoft#42365 (reverted in microsoft#42492), which made dispose() emit the 'disconnected' event on explicit disposal. Fixes: microsoft#42363
With --shared-browser-context the context belongs to all connected clients, so one client closing it only pretend-closed: the backend was disposed while every page stayed open and the next call silently rebuilt it. Return an error to browser_close instead.
With browser_close refused on a shared context, every remaining close path closes the context or the browser, so the existing 'disconnected' event already clears the cached backend.
This comment has been minimized.
This comment has been minimized.
9e3157b
into
microsoft:main
Test results for "MCP"2 failed 8273 passed, 1371 skipped Merge workflow run. |
🟢 CI is clear — both failures are pre-existing flakesHi, I'm the Playwright bot and I took a first look at the failing CI on this PR. Both failures are in DetailsOverall: no failure reaches the PR's change. Both are known low-rate flakes. Pre-existing flake / infra
Neither test touches Triaged by the Playwright bot - agent run |
## What's New ### 🎉 New Tools - **`browser_webmcp_list` / `browser_webmcp_call`** — List and call the tools a page registers through the [WebMCP](https://webmachinelearning.github.io/webmcp/) API, letting the page do the work instead of driving its UI. When a page has WebMCP tools, the page status reports how many are available ([#42613](microsoft/playwright#42613)). WebMCP is experimental, see [WebMCP in Chrome](https://developer.chrome.com/docs/ai/webmcp) for how to enable it. ### Other Changes - New `--profile-dir-name <name>` option (env `PLAYWRIGHT_MCP_PROFILE_DIR_NAME`) selects the Chrome profile to connect to in extension mode when the extension is installed in several profiles, for example `"Profile 1"` ([#42527](microsoft/playwright#42527)) - Headless browsers launched by the server are now closed after one hour without tool calls; the next tool call launches a new one. Use `--idle-timeout <ms>` (config `timeouts.idle`, env `PLAYWRIGHT_MCP_IDLE_TIMEOUT`) to change the timeout, `0` disables it. Headed and attached browsers are not closed unless a timeout is set explicitly ([#42663](microsoft/playwright#42663), [#42676](microsoft/playwright#42676)) - `--image-responses` accepts `only`: a response that carries an image consists of the image parts alone, without the text part ([#42672](microsoft/playwright#42672)) ## Bug Fixes - `browser_close` returns an error when the browser context is shared (`--shared-browser-context`) instead of breaking the calling client's session. This supersedes the v0.0.80 change that dropped the backend after `browser_close` ([#42495](microsoft/playwright#42495)) - With `--shared-browser-context`, `browser_start_recording` / `browser_stop_recording` (opt-in via `--caps=devtools`) keep each client's recording separate instead of delivering one client's recorded actions to another ([#42622](microsoft/playwright#42622), [#42627](microsoft/playwright#42627)) - The file access check follows symlinks, so a symlink inside the workspace can no longer be used to read or write files outside the allowed roots ([#42628](microsoft/playwright#42628)) - Explicitly named output files in a nested directory (e.g. `sub/shot.png`) no longer fail with `ENOENT`; `browser_file_upload` and `browser_drop` resolve relative paths against the workspace root ([#42540](microsoft/playwright#42540)) - In extension mode with `PLAYWRIGHT_MCP_EXTENSION_TOKEN` set, a connection that never completes (e.g. the token belongs to another Chrome profile) now fails after 30 seconds with a hint instead of hanging the tool call forever ([#42525](microsoft/playwright#42525)) - Disable the Chromium sandbox by default on Linux for the bundled Chromium build, which lacks the setuid sandbox helper ([#42490](microsoft/playwright#42490))
Summary
--shared-browser-contextthe context belongs to all connected clients.browser_closeused to dispose the calling client's backend while every page stayed open, and the next call from that client reused the disposed backend and failed with aTypeErroruntil restart.browser_closenow returns an error when the browser context is shared; the client's session keeps working and the browser closes when the sessions end.Fixes #42363