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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions