Skip to content

[MCP]: Expose noDefaults for --cdp-endpoint connections (also affects @playwright/cli) #41661

Description

@geun9716

--cdp-endpoint connections (used by both @playwright/mcp and @playwright/cli) go through createCDPBrowser() in packages/playwright-core/src/tools/mcp/browserFactory.ts, which calls chromium.connectOverCDP() but never forwards the noDefaults option added in #40185:

const browser = await playwright.chromium.connectOverCDP(config.browser.cdpEndpoint!, {
  headers: config.browser.cdpHeaders,
  timeout: config.browser.cdpTimeout,
  artifactsDir,
});

It's also not exposed anywhere in config.d.ts's browser section, nor as a CLI flag (--cdp-endpoint, --cdp-header, --cdp-timeout are the only related options in either @playwright/mcp or @playwright/cli).

Problem

Connecting to a WebKit-based remote-debugging target that doesn't implement Chromium's full browser-context-management CDP surface (e.g. a smart-TV's embedded web inspector) fails immediately:

Error: Protocol error (Browser.setDownloadBehavior): Browser context management is not supported.

This is the exact class of problem noDefaults was introduced to solve (#40158), and the same underlying error has been reported against other non-Chromium CDP targets before (#36961, #15370). With noDefaults: true passed directly to connectOverCDP, the connection succeeds and all core tools/commands work against the same device.

Repro

  1. Target exposes a CDP-ish endpoint at http://<host>:<port> that returns a valid /json/version response but rejects Browser.setDownloadBehavior on connect.
  2. Run either:
    npx @playwright/mcp@latest --cdp-endpoint http://<host>:<port>
    
    playwright-cli attach --cdp http://<host>:<port>
    
  3. Any tool/command that touches the browser (e.g. browser_snapshot, or the first eval) fails with the error above.

What we verified

  • Patching createCDPBrowser locally to pass noDefaults: true resolves the error completely, against a real device — verified through the actual MCP JSON-RPC protocol (@modelcontextprotocol/sdk stdio client, browser_snapshot and navigation tools) and through @playwright/cli's real attach/eval daemon flow, not just the raw playwright-core API.
  • This holds as long as --isolated is not also used. Isolated mode calls browser.newContext(), which issues Target.createBrowserContext — a genuine context-management CDP call that noDefaults intentionally does not skip (per feat(connectOverCDP): add noDefaults option #40185's design, it only ever applies to the pre-existing default context: browser.contexts()[0]). So --isolated + this target will still fail even with the fix — that's expected, not a regression.
  • @playwright/cli's attach command doesn't call browser.newContext() at all, so it works end-to-end with just the one change.

Proposed fix

Add a browser.cdpNoDefaults (naming open to suggestion — could also just reuse noDefaults verbatim) boolean field to Config, plus a matching --cdp-no-defaults CLI flag, forwarded into createCDPBrowser's connectOverCDP call as noDefaults. Since both @playwright/mcp and @playwright/cli share browserFactory.ts, one change fixes both.

Happy to put together the PR (config field + CLI flag + forwarding + a test under tests/mcp, following the existing noDefaults tests added in #40185) if this direction sounds reasonable — flagging it as an issue first per CONTRIBUTING.md before sending anything.

Versions tested: @playwright/mcp@0.0.77, @playwright/cli@0.1.15, both on playwright-core@1.62.0-alpha-2026-06-29.

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions