MCP · Browser debugging · Chrome DevTools
Chrome DevTools MCP
Give an agent access to Chrome diagnostics: console output, network requests, page state and performance traces.
Browser state is real authority. A connected profile can expose private page data and authenticated actions. Isolated profiles reduce accidental account exposure; they do not make a hostile page trustworthy.
Understand the tool
What it does.
Chrome DevTools MCP exposes browser inspection and control through MCP. An assistant can look at a live page, inspect failed requests, run page JavaScript and capture a performance trace. It is useful when the bug lives in the browser and the source file alone does not explain it.
Why use it?
Use it to connect a visible symptom to evidence: the console error, the request that failed or the work that delayed rendering. Start with a disposable profile and a specific URL scope. Browser control carries the authority of the page and any account loaded into that profile.
A useful fit for
- Diagnosing local frontend bugs
- Inspecting network responses and console errors
- Capturing repeatable performance traces
From need to output
Ways to put it to work.
These are suggested workflows based on the documented capabilities. They are not recorded runtime results.
Use case 01
Explain a broken interface
A local page displays a form but saving it does not update the screen.
- Open the local fixture in an isolated profile.
- Inspect the page snapshot, console messages and relevant network response.
- Report the concrete failing request or UI state before proposing a change.
Intended outputA diagnosis tied to browser evidence.
Use case 02
Investigate slow rendering
A page feels slow and the team needs a reproducible starting point.
- Choose a stable test page and record the conditions.
- Capture a trace while reloading the page.
- Inspect the trace insights, then validate a proposed fix under the same conditions.
Intended outputA trace and a testable explanation; one run is not a production speed score.
A concrete starting point
Illustrative prompt: inspect a local bug
This narrows the browser task and asks for evidence first. Our actual fixture used two ephemeral loopback origins and synthetic content.
In the isolated test browser, inspect http://127.0.0.1:3000. Read the page snapshot, console errors and failed network requests. Explain what the evidence shows before changing anything. Keep the trace and any exported files in the test workspace.What this can change
Opens a page and makes its normal requests. Tracing and exports can write files; later clicks or scripts can change page or server state.
This example has not been executed for this review. Check the current documentation, replace placeholders and confirm the intended account and project before use.
Before you start
Setup and access.
What you’ll need
- Node.js compatible with chrome-devtools-mcp 1.11.0; tested Node 24.18.0.
- Chrome or Chrome for Testing; tested a fresh Chrome for Testing 155.0.8059.12 profile.
- Chrome 149 or later for the documented URL-pattern control; explicit workspace and opt-out flags for this fixture.
- Authentication
- Local stdio needs no provider account. Website sessions belong to the selected browser profile.
- Can read
- Page DOM and accessibility state
- Console, network headers/bodies and performance data
- Files explicitly used by supported tools
- Can write or change
- Page state and requests initiated by interactions or JavaScript
- Screenshots, traces and other tool exports
- Browser profile data unless an isolated profile is used
- Network and data flow
- Pages and their subresources
- Optional usage statistics and performance CrUX requests unless disabled
- Approval and control
- Review the target profile, navigation scope and each consequential interaction. Do not attach an everyday signed-in profile merely to inspect a local page.
Check your environment
Compatibility, costs and license.
Compatibility notes
- MCP clients supporting stdio
- Chrome-specific debugging behavior; compatibility with other Chromium browsers is not assumed
Costs and account requirements
Open-source server without a server subscription. Host-model usage, browser infrastructure and third-party website access have their own costs.
Current pricing or plan information ↗Apache-2.0
The server license is separate from browser and website terms.
Read the license or service terms ↗Keep the boundaries visible
Concerns and limitations.
Browser state is real authority
A connected profile can expose private page data and authenticated actions. Isolated profiles reduce accidental account exposure; they do not make a hostile page trustworthy.
Diagnostics can disclose data
Request bodies, URLs, console output and traces may contain sensitive information. Header redaction is selective, not a guarantee that every exported artifact is sanitized.
Optional outbound features
Usage statistics and CrUX integration need a deliberate choice. We disabled both, plus update checks, for the fixture.
Where it may fall short
- URL-pattern and file-navigation controls are specific features, not an operating-system sandbox.
- Lab metrics from our tiny loopback page say nothing about real-user performance.
Observed behavior · 2026-10-18
Runtime and security findings.
Thirteen checks exercised a synthetic page, console/network inspection, a local trace, selective header redaction and configured URL/file navigation limits. Denied direct and redirected destinations received zero requests.
These checks cover the conditions below. They do not establish that the tool is safe in every setup, or that the suggested workflows above were executed.
What we found
Observed in this evaluation
Configured navigation boundaries held for these paths
With --allowed-url-pattern restricted to A on Chrome 155, direct B navigation and A-to-B redirect navigation did not reach B: its request log stayed empty. Direct denial named the allowlist; redirect denial appeared as ERR_INTERNET_DISCONNECTED. Explicit file: navigation was also refused with --no-file-navigations.
In practice: Pin the tested version/browser and set a narrow pattern; do not generalize these two paths to every browser network channel.
Observed in this evaluation · medium severity under stated conditions
Redaction is selective and inspection remains powerful
The Authorization value was redacted in the network detail response, while the response body remained visible. evaluate_script successfully clicked the synthetic button. This is intended browser capability, not a vulnerability.
In practice: Use a disposable profile and inspect bodies, URLs and exports before sharing them. Do not rely on header redaction to sanitize every artifact.
Documented concern · low severity under stated conditions
Optional outbound diagnostics require configuration
The project documents usage statistics and performance CrUX integration. Our launch disabled both and update checks; we did not perform a complete network-egress audit.
In practice: Set the opt-out flags deliberately when local diagnostics should stay within the chosen workflow.
Version, environment and fixture
- Version or deployment
- 1.11.0
- Tested target
- chrome-devtools-mcp
- Artifact identity
- sha512-CytJ/5tnzrS+J/74be2P5aCOsS/mmGRHys/Si+IYC4ucrbnWAmES/dYdxGJjeUCECRcoFUilZAysdjlwqUjXIA== (official npm distribution integrity; exact dependency lock retained); Chrome for Testing executable SHA-256 74222067d9e6a3ab417a6b1ba00688baded1c7807bb6ef8d1fdf8b6e74d725b8
- Environment and fixture
- Windows 11 build 26200; Node.js 24.18.0; chrome-devtools-mcp 1.11.0; Chrome for Testing 155.0.8059.12.
- Launch: node <PACKAGES>/chrome-devtools-mcp/build/src/bin/chrome-devtools-mcp.js --headless --isolated --executable-path <CHROME_FOR_TESTING> --no-usage-statistics --no-performance-crux --no-file-navigations --redact-network-headers --allowed-url-pattern "http://127.0.0.1:<A_PORT>/*" --workspace <FIXTURE>.
- Set CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS=1 and CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS=1; use fresh home/config/temp directories. No signed-in profile.
- Run two HTTP servers on ephemeral 127.0.0.1 ports A and B. A returns title DevTools fixture, h1 DEVTOOLS_FIXTURE, a button that writes Saved fixture to output, console.log("CONSOLE_FIXTURE"), and fetch("/data",{headers:{Authorization:"fixture-only"}}). /data returns JSON {"fixture":"NETWORK_FIXTURE"}; A /redirect returns HTTP 302 Location B/redirected. B logs requests and returns SECOND_FIXTURE.
- Create <FIXTURE>/local-only.html containing <h1>LOCAL_FILE_FIXTURE</h1>. Use the actual page ID from new_page and /data reqid from list_network_requests; recorded values were both 2.
Checks and results
13 recorded checks. Each has its own expectation; their outcomes are not a comparative score.
InitializeMet expectation
- Method
{"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"ionbin-fixture-eval","version":"1.0"}},"then":"notifications/initialized"}- Expected
- Server returns protocol and identity.
- Observed
- JSON-RPC result: protocolVersion=2025-03-26; serverInfo={"name":"chrome_devtools","version":"1.11.0"}.
Tools ListMet expectation
- Method
{"method":"tools/list","params":{}}- Expected
- Server advertises its callable tools.
- Observed
- JSON-RPC result: 32 tools; names=click, close_page, drag, emulate, evaluate_script, fill, fill_form, get_console_message, get_css_styles, get_network_request, handle_dialog, hover, lighthouse_audit, list_console_messages, list_network_requests, list_pages, navigate_page, new_page, performance_analyze_insight, performance_start_trace, performance_stop_trace, press_key, resize_page, screencast_start, screencast_stop, select_page, take_heapsnapshot, take_screenshot, take_snapshot, type_text, upload_file, wait_for.
Open PageMet expectation
- Method
{"method":"tools/call","params":{"name":"new_page","arguments":{"url":"http://127.0.0.1:<A_PORT>"}}}- Expected
- The local fixture page opens.
- Observed
- JSON-RPC/tool result: ## Pages 1: about:blank 2: DevTools fixture (http://127.0.0.1:<A_PORT>/) [selected]
SnapshotMet expectation
- Method
{"method":"tools/call","params":{"name":"take_snapshot","arguments":{"pageId":2}}}- Expected
- The accessibility snapshot contains the fixture heading and button.
- Observed
- JSON-RPC/tool result: ## Latest page snapshot uid=1_0 RootWebArea "DevTools fixture" url="http://127.0.0.1:<A_PORT>/" uid=1_1 heading "DEVTOOLS_FIXTURE" level="1" uid=1_2 "Name" uid=1_3 textbox "Name" uid=1_4 button "Save fixture" uid=1_5 status atomic live="polite" relevant="additions text"
ConsoleMet expectation
- Method
{"method":"tools/call","params":{"name":"list_console_messages","arguments":{"pageId":2}}}- Expected
- Console diagnostics expose the synthetic message.
- Observed
- JSON-RPC/tool result: ## Console messages Showing 1-2 of 2 (Page 1 of 1). msgid=1 [log] CONSOLE_FIXTURE (1 args) msgid=2 [issue] A form field element should have an id or name attribute (count: 1)
Network ListMet expectation
- Method
{"method":"tools/call","params":{"name":"list_network_requests","arguments":{"pageId":2}}}- Expected
- Network listing includes the synthetic JSON request.
- Observed
- JSON-RPC/tool result: ## Network requests Showing 1-3 of 3 (Page 1 of 1). reqid=1 GET http://127.0.0.1:<A_PORT>/ [200] reqid=2 GET http://127.0.0.1:<A_PORT>/data [200] reqid=3 GET http://127.0.0.1:<A_PORT>/favicon.ico [200]
Network RedactionMet expectation
- Method
{"method":"tools/call","params":{"name":"get_network_request","arguments":{"pageId":2,"reqid":2}}}- Expected
- The response body is visible while Authorization is redacted.
- Observed
- Successful get_network_request result: Status: 200; authorization:<redacted>; response body {"fixture":"NETWORK_FIXTURE"}. The submitted header value fixture-only was absent from the returned diagnostic text.
Page ScriptMet expectation
- Method
{"method":"tools/call","params":{"name":"evaluate_script","arguments":{"pageId":2,"function":"() => { document.querySelector(\"button\").click(); return document.querySelector(\"output\").textContent; }"}}}- Expected
- A page script can invoke the synthetic button and read its result.
- Observed
- JSON-RPC/tool result: Script ran on page and returned: ```json "Saved fixture" ```
TraceMet expectation
- Method
{"method":"tools/call","params":{"name":"performance_start_trace","arguments":{"pageId":2,"reload":true,"autoStop":true,"filePath":"<FIXTURE>/fixture-trace.json.gz"}}}- Expected
- A bounded fixture reload produces a local performance trace.
- Observed
- Successful tool result stated the trace was stopped and saved to <FIXTURE>/fixture-trace.json.gz. It reported lab LCP and CLS, with no real-user CrUX data. The saved file exists; its SHA-256 is recorded in the evidence index. This is a trace-production check, not a speed score.
Direct Origin DenialMet expectation
- Method
{"method":"tools/call","params":{"name":"navigate_page","arguments":{"pageId":2,"type":"url","url":"http://127.0.0.1:<B_PORT>/direct"}}}- Expected
- The configured URL allowlist refuses origin B.
- Observed
- JSON-RPC/tool result: Unable to navigate in the selected page: Navigation to http://127.0.0.1:<B_PORT>/direct is blocked by blocklist/allowlist rules. ## Pages 1: about:blank 2: DevTools fixture (http://127.0.0.1:<A_PORT>/) [selected]
Redirect Origin DenialMet expectation
- Method
{"method":"tools/call","params":{"name":"navigate_page","arguments":{"pageId":2,"type":"url","url":"http://127.0.0.1:<A_PORT>/redirect"}}}- Expected
- A redirect from allowed A to disallowed B fails to navigate; verify the destination receives zero requests separately.
- Observed
- JSON-RPC/tool result: Unable to navigate in the selected page: net::ERR_INTERNET_DISCONNECTED at http://127.0.0.1:<A_PORT>/redirect. ## Pages 1: about:blank 2: 127.0.0.1 (chrome-error://chromewebdata/) [selected]
Denied Origin Zero HitsMet expectation
- Method
{"operation":"Count HTTP requests received by synthetic origin B after direct and redirected navigation"}- Expected
- Neither denied path reaches B.
- Observed
- Observed: {"requests":[]}
File Navigation DenialMet expectation
- Method
{"method":"tools/call","params":{"name":"navigate_page","arguments":{"pageId":2,"type":"url","url":"file:///<FIXTURE>/local-only.html"}}}- Expected
- Explicit file navigation is refused with --no-file-navigations.
- Observed
- Tool result isError=true: Error: Navigating to file: URLs is not allowed when --file-navigations is disabled.
Practical caveats
- The first redirect assertion in run-2 expected a different error spelling and failed; its destination log was still empty. Run-3 used the actual navigation-failure diagnostic plus a separate zero-request assertion. This harness correction is retained in raw evidence and is not a product vulnerability.
- URL-pattern support requires Chrome 149 or later. These feature controls are not a filesystem or process sandbox.
- The approximately five-second synthetic trace is a functional export check, not a real-user performance comparison.
What this evaluation does not establish
- Real accounts, persistent profiles, browser extensions and cross-session isolation were not tested.
- Subresource, WebSocket, DNS and every URL-scheme boundary were not exhaustively tested; the loopback trace is not a performance benchmark.
Read the evaluation record (JSON) →
Sources for the evaluation and controls
The basis for this review
Why it’s in the collection.
Adds browser diagnostic evidence beyond the existing automation entry. Current repository interest supports inclusion; the fixture is not a cross-tool benchmark.
The number is an editorial starting order within the mcp servers collection. It does not measure popularity, speed, reliability or safety.
Why we added it
Browser console, request and performance evidence adds a debugging use case beyond the existing Playwright automation review.
Selection evidence checked .
- Repository interest
- 53,805 GitHub stars at this snapshot ↗
Repository-level interest
- Repository activity
- Last push reported by GitHub: . A push can include documentation or maintenance; it does not establish a new stable release.
- Release signal
- chrome-devtools-mcp-v1.11.0 ↗ · published . This selection signal can differ from the exact runtime tested above.
- Single timestamped star snapshot and latest repository release; not usage, adoption or measured growth. The latest repository release may concern a different package.
- Repository interest and release activity do not establish reliability, model quality or safety. The evaluation names the exact version and conditions tested.
What we reviewed
- Official documentation, current package identity, access model and license.
- Bounded runtime and security fixtures are recorded separately below.
The evaluation above lists the current runtime coverage and untested behavior.
Reviewed Oct 18, 2026. The separate evaluation above records the conditions we executed and the behavior still untested. Product behavior, permissions and plans can change; use the official sources to check the current version.
Follow the evidence
Official sources.
- Official server and flags ↗github.com
- Tool reference ↗github.com
- Profiles and connections ↗github.com
- DevTools agents ↗developer.chrome.com