Chrome DevTools MCP¶
Browser automation, debugging, and element annotation via Chrome DevTools Protocol.
Source: ChromeDevTools/chrome-devtools-mcp
Enabling¶
The server is included in servers.yaml with enabled: false. To activate it permanently:
Or enable for the current session only:
Server Config¶
chrome-devtools:
type: stdio
command: npx
args:
- "-y"
- "chrome-devtools-mcp@latest"
- "--isolated"
- "--viewport=1280x720"
timeout: 120
enabled: true
Options¶
Add to the args array to customise behaviour:
| Option | Description |
|---|---|
--isolated |
Temporary Chrome profile, auto-cleaned on close (default) |
--browserUrl=http://localhost:9222 |
Connect to an existing Chrome instance |
--autoConnect |
Attach to any Chrome with remote debugging enabled |
--headless=true |
Run without a visible browser window |
--viewport=WxH |
Set viewport size (e.g., 1280x720) |
Note
Chrome 136+ requires --user-data-dir when launching with --remote-debugging-port.
Tools¶
- Navigation:
navigate_page,new_page,select_page,close_page,list_pages,wait_for - Interaction:
click,fill,fill_form,press_key,hover,drag,upload_file,handle_dialog - Inspection:
evaluate_script,list_console_messages,list_network_requests,get_network_request,take_screenshot,take_snapshot - Performance:
performance_start_trace,performance_stop_trace,performance_analyze_insight - Viewport:
resize_page,emulate
Element Annotations (chrome_util)¶
The chrome_util pack adds visual annotation tools on top of this server — highlight elements, guide users through workflows, and let users point Claude to elements with Ctrl+I.
See chrome_util reference for the full API.
Usage Patterns¶
- Standard flow:
navigate_page→take_screenshot→click/fill→take_screenshot - Use
take_snapshotfor a text/accessibility view instead of a screenshot - Use
evaluate_scriptfor custom JS — takes afunctionstring:"() => document.title" - Use
list_network_requestsafter navigation to inspect all HTTP traffic - Use remote mode (
--browserUrl) to preserve an existing logged-in session
Verification Checklist¶
Use these checks after enabling the server:
ot.servers(pattern="chrome-devtools", info="full")
ot.packs(pattern="chrome")
ot.tool_info(pattern="chrome_devtools.")
Examples¶
1. Scrape structured data from a page¶
Extract article headings from any web page as a Python list.
chrome_devtools.navigate_page(url="https://en.wikipedia.org/wiki/Anthropic")
chrome_devtools.wait_for(text="Contents")
chrome_devtools.evaluate_script(
function="() => Array.from(document.querySelectorAll('h2')).map(h => h.textContent.trim())"
)
# Returns: ["Contents", "History", "Business structure", "Product", ...]
2. Audit all network requests on a page¶
See every HTTP request a page makes — useful for mapping API endpoints or auditing third-party calls.
chrome_devtools.navigate_page(url="https://myapp.com/dashboard")
chrome_devtools.list_network_requests()
chrome_devtools.evaluate_script(
function="() => performance.getEntriesByType('resource').map(r => ({url: r.name, duration: Math.round(r.duration)}))"
)
3. Detect and read JavaScript console errors¶
Capture any errors thrown during page load — useful for debugging or regression checks.
chrome_devtools.navigate_page(url="https://myapp.com")
chrome_devtools.list_console_messages()
# Look for type="error" entries in the output
4. Emulate a mobile device¶
Test how a page renders on a phone without a physical device.
chrome_devtools.navigate_page(url="https://myapp.com")
chrome_devtools.resize_page(width=390, height=844) # iPhone 14 dimensions
chrome_devtools.take_screenshot()
chrome_devtools.resize_page(width=1280, height=720) # Reset to desktop
5. Multi-tab comparison¶
Open two pages and compare their state — useful for A/B testing or before/after checks.
chrome_devtools.navigate_page(url="https://myapp.com/pricing?plan=free")
chrome_devtools.new_page(url="https://myapp.com/pricing?plan=pro")
chrome_devtools.take_screenshot()
chrome_devtools.select_page(index=1)
chrome_devtools.take_screenshot()
6. Extract all links from a page¶
Collect every anchor href — useful for link audits or crawl preparation.
chrome_devtools.navigate_page(url="https://docs.myapp.com")
chrome_devtools.evaluate_script(
function="() => Array.from(document.querySelectorAll('a[href]')).map(a => a.href).filter(h => h.startsWith('https'))"
)
7. Profile page load performance¶
Measure how long a page takes to load and identify bottlenecks.
chrome_devtools.performance_start_trace()
chrome_devtools.navigate_page(url="https://myapp.com")
chrome_devtools.wait_for(text="Example Domain")
chrome_devtools.performance_stop_trace()
chrome_devtools.performance_analyze_insight()
8. Guide a user through a workflow¶
Visually walk the user through a multi-step process with labelled overlays.
chrome_devtools.navigate_page(url="https://myapp.com/settings")
chrome_util.inject_annotations()
chrome_util.guide_user(
task="Update profile",
steps=[
{"selector": "input[name='display_name']", "label": "1. Edit name"},
{"selector": "input[name='email']", "label": "2. Confirm email"},
{"selector": "button.save", "label": "3. Save", "color": "green"},
],
)
chrome_devtools.take_screenshot()
Common Mistakes to Avoid¶
- Don't interact with elements before the page has loaded — use
wait_forfirst - Don't use
expression=withevaluate_script— the parameter isfunction=and takes a JS function string - Use remote mode (
--browserUrl) when you need to preserve an existing session; isolated mode always starts fresh