The Chrome DevTools MCP control model, explained
Chrome DevTools MCP is Google’s browser server — first-party under the ChromeDevTools org, ~49.5k stars, v1.7.0 as of August 10, 2026, and one of the fastest-growing servers in the ecosystem since its 1.0 in May. Where Playwright MCP wraps a browser in an automation framework, this one hands the agent the DevTools protocol itself: 57 tools spanning input automation, performance tracing, network inspection, heap snapshots, script evaluation — and two attach modes that can point all of it at a Chrome you’re actually using. This page is the reference: what ships, exactly how each mechanism behaves, and where the model ends. Source: the official README and its configuration and concepts sections.
This page covers the server’s own controls. For the cross-server picture, see the MCP server controls comparison; for what a control layer adds on top, the coverage matrix.
What’s at stake on this surface
Everything on the Playwright page applies here — the browser is simultaneously the untrusted-content reader and the action surface, so every page is a potential injection payload delivered to the model holding click, fill, and submit. Three things are sharper on this server. evaluate_script is a core tool, not a gated capability: arbitrary JS in whatever session the page holds. The network tools (list_network_requests, get_network_request) read requests including headers — on a logged-in session, that’s tokens and cookies in flight, offered as tool output. And the attach modes are the differentiator: this server has a supported, documented path to driving your Chrome — the real profile, every open window — which Playwright MCP does not ship. Google’s disclaimer states the deal plainly: the server “exposes content of the browser instance to the MCP clients,” which can “inspect, debug, and modify” it, and you should “avoid sharing sensitive or personal information that you don’t want to share with MCP clients.”
The profile model: a better default than Playwright’s, with the same persistence trap
No token, no scopes — as with every browser server, the profile is the credential. The default is genuinely the right call: the server launches its own Chrome with a dedicated user-data-dir ($HOME/.cache/chrome-devtools-mcp/chrome-profile), not your real one. Your sessions are not in the room. But the dedicated profile “is not cleared between runs and is reused for subsequent runs” — anything the agent logs into is still logged in next session, for whatever prompt-injected task comes along later. The fix is the same flag as Playwright’s: --isolated uses a temporary user-data-dir “automatically cleaned up after the browser is closed.” There is no --storage-state equivalent — injecting exactly one prepared session isn’t expressible; the choice is persistent-by-accumulation or amnesiac.
Attach modes: the supported path to your real Chrome
This is the section that separates the two browser servers. Three ways in:
--browser-urlconnects to a Chrome already running with a remote debugging port. Chrome itself imposes the one real guardrail here: it “requires you to use a non-default user data directory” to enable the port, so this path can’t silently open your daily profile.--wsEndpointconnects to a raw CDP WebSocket (with--wsHeadersfor auth headers) — the sandboxed-agent-to-outside-Chrome pattern.--autoConnect(Chrome 144+) is the one to understand: after enabling remote debugging viachrome://inspect/#remote-debugging, the server attaches to your running Chrome — “the MCP server will connect to the default profile” and “has access to all open windows for the selected profile.” A permission dialog in Chrome gates the attach; clicking Allow grants control. That is your real browser: your Gmail tab, your bank tab, your password-manager extension, offered to the tool surface above.
The README’s warning about the debugging port deserves quoting because it is the whole threat model in two sentences: “Any application on your machine can connect to this port and control the browser,” and “Make sure that you are not browsing any sensitive websites while the debugging port is open.” That advice — don’t browse anything sensitive while attached — is the vendor telling you the control model for attach mode is you, remembering.
Category flags and –slim: subtraction, with the core welded on
Tool filtering exists and is finer than Playwright’s: --categoryNetwork, --categoryPerformance, --categoryEmulation (on by default; set false to remove those groups from the surface) and --categoryExtensions, --categoryPwa, --categoryExperimentalWebmcp, --categoryExperimentalThirdParty (off by default). Turning --categoryNetwork off is worth singling out — it removes the headers-in-flight reading surface entirely. But the shape is the familiar one: launch-time subtraction at the edges. The input-automation core (click, drag, fill, fill_form, upload_file, handle_dialog) and the debugging group that contains evaluate_script are not categories you can unselect. --slim collapses the surface to three tools — and the three are navigation, screenshots, and script execution: even the minimal posture keeps arbitrary JS. There is no read-only mode, and no combination of flags produces one.
URL patterns and header redaction: guardrails, in-process
Two controls Playwright MCP users will wish their server stated this clearly: --blockedUrlPattern blocks navigation to matching URLs (and “silently detaches from targets with blocked URLs upon connection” — silence being a choice worth noticing), and --allowedUrlPattern inverts it to an allowlist, requiring Chrome 149+. --redactNetworkHeaders redacts sensitive headers from network tool output — a real mitigation for the tokens-in-flight problem, off by default. All three run inside the process the agent drives, configured in the client’s MCP config file; treat them exactly as the Playwright origin flags taught us to treat in-process filters — declared guardrails worth setting, not boundaries. The boundary versions are --proxyServer with enforcement outside the process, and containment below the process. One adjacent default is good: file-writing tools are limited to the OS temp directory unless the client grants MCP roots — --allowUnrestrictedPaths lifts it, “only when connecting a trusted local client.”
What doesn’t exist
No read-only mode, as above. No approval mechanism — nothing can hold fill_form on a checkout page or evaluate_script in an attached session for a human; the Chrome permission dialog on --autoConnect approves the connection, once, not any call after it. No per-call policy — nothing distinguishes evaluating an expression from exfiltrating document.cookie; both are evaluate_script. And no audit: no operator-queryable record of which tools fired with what arguments exists anywhere in the server — --logFile is for debugging the server, not accounting for the agent. What is recorded by default is telemetry to Google (“usage statistics” are on unless you pass --no-usage-statistics, and performance tools may send trace URLs to the CrUX API unless --no-performance-crux). The audit gap in its purest form: the vendor gets a record of the server; the operator gets no record of the agent.
Where the native model ends
The closing page of this series, and the pattern is at its cleanest:
- The strongest controls are Chrome’s, not the server’s. The non-default-profile requirement for the debug port and the Allow dialog on attach are enforced by the browser. Everything the server adds — categories, URL patterns, redaction — is launch-time flags in a config file, running in-process.
- Nothing is per-call, nothing can be held, nothing is recorded for the operator. The deepest tool on the surface,
evaluate_script, survives every subtraction including--slim. - Attach mode dissolves the one good default. The dedicated-profile design is real protection right up until
--autoConnect, at which point the surface is your actual browser and the operative control is a sentence in the README asking you not to browse anything sensitive.
The practical posture: never attach to a daily-driver Chrome — if a task needs a real session, put exactly that session in a separate Chrome and attach to it; --isolated for everything unattended; default-on categories you don’t need turned off; URL patterns and --redactNetworkHeaders set as declared guardrails with a proxy or container as the real one; telemetry off if that matters to you. This series ends where it was always going to: the newest, fastest-growing class of MCP server — the one that drives a browser, the one closest to your logged-in life — ships with the least native control. The per-call decision, the approval path, and the record the operator never gets natively belong in a layer the agent can’t edit; on this surface there is nowhere else for them to live.