# Chrome DevTools MCP Permissions & Controls, Explained

How Chrome DevTools MCP's profile model, attach modes, category flags, and URL patterns actually work — what --browser-url and --autoConnect mean for your real Chrome, and where the native model ends.

# The Chrome DevTools MCP control model, explained

Chrome DevTools MCP is Google's browser server — first-party under the ChromeDevTools org, [~49.5k stars](https://github.com/ChromeDevTools/chrome-devtools-mcp), [v1.7.0 as of August 10, 2026](https://github.com/ChromeDevTools/chrome-devtools-mcp/releases), and one of the fastest-growing servers in the ecosystem since its 1.0 in May. Where [Playwright MCP](/mcp-controls/playwright) 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](https://github.com/ChromeDevTools/chrome-devtools-mcp) 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](/mcp-controls); for what a control layer adds on top, [the coverage matrix](/coverage).*

## What's at stake on this surface

Everything on [the Playwright page](/mcp-controls/playwright) 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](https://github.com/ChromeDevTools/chrome-devtools-mcp#disclaimers) 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-url`** connects 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.
- **`--wsEndpoint`** connects to a raw CDP WebSocket (with `--wsHeaders` for auth headers) — the sandboxed-agent-to-outside-Chrome pattern.
- **`--autoConnect`** (Chrome 144+) is the one to understand: after enabling remote debugging via `chrome://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](/mcp-controls/playwright) 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](/blog/sandboxes-and-control-planes). 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](/blog/mcp-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](/what-is-an-agentic-control-plane); on this surface there is nowhere else for them to live.
