Browser Devtools MCP
About
A Playwright-based MCP server that exposes a live browser as a traceable, inspectable, debuggable and controllable execution environment for AI agents.
Details
- Author
- serkan-ozal
- Downloads
- 590
- Categories
- Developer Tools, Automation, Other, AI
Jump to
- Visual inspection via screenshots, ARIA snapshots, HTML extraction
- DOM and code-level debugging with element inspection
- Browser automation: navigation, clicking, form filling, scrolling
- Execution monitoring with console messages and HTTP request tracking
- Figma design comparison with similarity scoring
- OpenTelemetry integration for distributed tracing
Setting up with Highlight
This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:
- Download and install Highlight from highlightai.com/download
- Navigate to the plugins tab and select "Add Custom Plugin"
-
Configure the plugin with the settings below
Plugin Name
Browser Devtools MCPCommand (node, npx, python, etc.)Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.
- Enable "Start Automatically" if you want the plugin to start when Highlight launches
From the repository
Run the server directly with npx -y browser-devtools-mcp without manual installation. Configure your MCP client (VS Code, Claude, Cursor, etc.) with the command npx -y browser-devtools-mcp. Supports both stdio and streamable-http transports, configurable via CLI arguments --transport and --port.
a11y_take-aria-snapshot
ARIA snapshot of the page or a scoped element. Returns a tree with refs (e1, e2, ...) and a refs map. Use refs in interaction tools: selector "e1" or "@e1" to click/fill that element. Output includes URL, title, and YAML tree. Refs are valid until next snapshot or navigation. interactiveOnly: only interactive elements get refs; omit for content roles (headings, etc.) too. cursorInteractive: true adds refs for clickable elements without ARIA (e.g. div with cursor:pointer/onclick). Use with a11y_take-ax-tree-snapshot for full UI analysis.
a11y_take-ax-tree-snapshot
Combines Chromium AX tree with runtime visual diagnostics (bounding box, visibility, viewport). Use to detect: elements with role/name but hidden or off-screen; layout/geometry issues; overlap/occlusion (enable checkOcclusion). When investigating UI/layout or when clicks fail on seemingly visible elements, set checkOcclusion:true—it uses elementFromPoint() at center+corners to find what is actually on top. boundingBox is from getBoundingClientRect() (viewport coords; layout box only). selectorHint is best-effort (data-testid/data-selector/id). Use with a11y_take-aria-snapshot for full UI analysis.
content_get-as-html
Gets the HTML content of the current page. By default, all <script> tags are removed from the output unless "removeScripts" is explicitly set to "false".
content_get-as-text
Gets the visible text content of the current page.
content_save-as-pdf
Saves the current page as a PDF file.
content_start-recording
Starts video recording of the browser page. Recording captures all page interactions until content_stop-recording is called. Uses Playwright's native screencast API — works in all modes (headless, headed, persistent, CDP attach). Only supported on Chromium-based browsers.
content_stop-recording
Stops video recording of the browser page and saves the video file. Must be called after content_start-recording. The video is saved as a WebM file.
content_take-screenshot
Takes a screenshot of the current page or a specific element. Do NOT use for page structure—use ARIA/AX snapshots instead. Use only for visual verification (design check, visual bug, contrast, layout). Screenshot is saved to disk; use includeBase64 only when the file cannot be read from the returned path (e.g. remote, container).
debug_status
Returns the current debugging status including: - Whether debugging is enabled - Source map status - Exceptionpoint state - Count of tracepoints, logpoints, and watches - Snapshot statistics
debug_resolve-source-location
Resolves a generated/bundled code location to its original source via source maps. Useful for translating minified stack traces or bundle line numbers to original TypeScript/JavaScript source. Requires a page with debugging context (debugging is auto-enabled on first use). Input: generated script URL, line, column (1-based). Output: original source path, line, column when a source map is available.
debug_put-tracepoint
Puts a non-blocking tracepoint at the specified location. When hit, a snapshot of the call stack and local variables is captured automatically without pausing execution. The urlPattern matches script URLs. Special characters are auto-escaped. Examples: - "app.js" matches scripts containing "app.js" - "bundle.min.js" matches scripts containing "bundle.min.js" DO NOT escape characters yourself (e.g., don't use "app\.js"). Returns resolvedLocations: number of scripts where the tracepoint was set. If 0, the pattern didn't match any loaded scripts.
debug_remove-probe
Removes a tracepoint, logpoint, or watch expression by ID. `type`: `tracepoint`, `logpoint`, or `watch`. `id`: the probe or watch ID (from list-probes).
debug_list-probes
Lists tracepoints, logpoints, and/or watch expressions. Optional `types`: array of `tracepoint`, `logpoint`, `watch`. If omitted or empty, returns all.
debug_clear-probes
Removes tracepoints, logpoints, and/or watch expressions. Optional `types`: array of `tracepoint`, `logpoint`, `watches`. If omitted or empty, clears all.
debug_put-logpoint
Puts a logpoint at the specified location. When the logpoint is hit, the logExpression is evaluated and the result is captured in the snapshot's logResult field. Logpoints are lightweight - they only capture the log expression result, NOT call stack or watch expressions. Use tracepoints for full debug context. urlPattern matches script URLs (e.g., "app.js"). Auto-escaped, do not add backslashes. logExpression: a single JavaScript expression (e.g. "user.name", "JSON.stringify({ a, b })", or "{ discountAmount, finalAmount, n }"). Object literals are supported; for maximum compatibility prefer a single variable or JSON.stringify(...). Returns resolvedLocations: 0 means pattern didn't match any loaded scripts.
debug_put-exceptionpoint
Sets the exception tracepoint state: - "none": Don't capture on exceptions - "uncaught": Capture only on uncaught exceptions - "all": Capture on all exceptions (caught and uncaught) When an exception occurs, a snapshot is captured with exception details.
debug_get-probe-snapshots
Retrieves snapshots captured by tracepoints, logpoints, and/or exceptionpoints. Optional `types`: array of `tracepoint`, `logpoint`, `exceptionpoint`. If omitted or empty, returns all. Response fields: `tracepointSnapshots`, `logpointSnapshots`, `exceptionpointSnapshots`. Optional `probeId` filters tracepoint or logpoint snapshots; `fromSequence` and `limit` apply per type. Output trimming: by default only the top 5 call stack frames are returned, only `local` scope(s) are included, and variables per scope are capped at 20. Override with maxCallStackDepth, includeScopes, maxVariablesPerScope.
debug_clear-probe-snapshots
Clears snapshots captured by tracepoints, logpoints, and/or exceptionpoints. Optional `types`: array of `tracepoint`, `logpoint`, `exceptionpoint`. If omitted or empty, clears all. Optional `probeId`: clear only snapshots for this probe (for tracepoint/logpoint).
debug_add-watch
Adds a watch expression to be evaluated at every breakpoint hit. Watch expression results are included in the snapshot's watchResults field. Examples: - "user.name" - "this.state" - "items.length" - "JSON.stringify(config)" Watch expressions are evaluated in the context of the paused frame.
interaction_click
Clicks an element. Accepts selector or ref (e.g. e1, @e1). Set waitForNavigation: true when the click opens a new page — waits for navigation then for network idle so snapshot/screenshot see full content.
interaction_drag
Drags an element to a target location. Accepts CSS selectors or refs (e.g. e1, @e1) from the last ARIA snapshot.
interaction_fill
Fills out an input field. Accepts a CSS selector or a ref from the last ARIA snapshot (e.g. e1, @e1).
interaction_hover
Hovers an element on the page. Accepts a CSS selector or a ref from the last ARIA snapshot (e.g. e1, @e1).
interaction_press-key
Presses a keyboard key with optional "hold" and auto-repeat behavior. Key facts: - keyboard.press(key, { delay }) does NOT trigger OS-style auto-repeat. - Some UI behaviors (especially scrolling) require repeated keydown events. - Use repeat=true + holdMs to approximate real keyboard holding. Execution logic: - If selector is provided, the element is focused first. - If holdMs is omitted or repeat=false: → a single keyboard.press() is executed. - If holdMs is provided AND repeat=true: → keyboard.press() is called repeatedly until holdMs elapses.
interaction_resize-viewport
Resizes the PAGE VIEWPORT using Playwright viewport emulation (page.setViewportSize). This affects: - window.innerWidth / window.innerHeight - CSS media queries (responsive layouts) - Layout, rendering and screenshots Notes: - This does NOT resize the OS-level browser window. - Runtime switching to viewport=null (binding to real window size) is not supported by Playwright. If you need real window-driven responsive behavior, start the BrowserContext with viewport: null and use the window resize tool instead.
interaction_resize-window
Resizes the REAL BROWSER WINDOW (OS-level window) for the current page using Chrome DevTools Protocol (CDP). This tool works best on Chromium-based browsers (Chromium/Chrome/Edge). It is especially useful in headful sessions when you run with viewport emulation disabled (viewport: null), so the page layout follows the OS window size. Important: - If Playwright viewport emulation is enabled (viewport is NOT null), resizing the OS window may not change page layout. - On non-Chromium browsers (Firefox/WebKit), CDP is not available and this tool will fail.
interaction_select
Select an option in a dropdown. Accepts a CSS selector or a ref from the last ARIA snapshot (e.g. e1, @e1).
interaction_scroll
Scrolls the page viewport or a specific scrollable element. Modes: - 'by': Scrolls by a relative delta (dx/dy) from the current scroll position. - 'to': Scrolls to an absolute scroll position (x/y). - 'top': Scrolls to the very top. - 'bottom': Scrolls to the very bottom. - 'left': Scrolls to the far left. - 'right': Scrolls to the far right. Use this tool to: - Reveal content below the fold - Jump to the top/bottom without knowing exact positions - Bring elements into view before clicking - Inspect lazy-loaded content that appears on scroll
navigation_go-back-or-forward
Navigates to the previous or next page in history. - `direction: "back"` — previous page in history. - `direction: "forward"` — next page in history. In case of multiple redirects, the navigation will resolve with the response of the last redirect. If cannot go back/forward, returns empty response. By default (includeSnapshot: true), an ARIA snapshot with refs is returned. Use `snapshotOptions` for `interactiveOnly` (default false) and `cursorInteractive` (default false), same as a11y_take-aria-snapshot. When `includeScreenshot: true`, the screenshot is always saved to disk; `screenshotFilePath` is returned. By default `outputPath` is the OS temp dir and `name` is "screenshot" (same as content_take-screenshot). Use `screenshotOptions.includeBase64: true` only when the file cannot be read from the returned path (e.g. remote, container).
navigation_go-to
Navigates to the given URL. **NOTE**: The tool either throws an error or returns a main resource response. The only exceptions are navigation to `about:blank` or navigation to the same URL with a different hash, which would succeed and return empty response. **By default** (`includeSnapshot: true`), an ARIA snapshot with refs is taken after navigation and returned in `output` and `refs`; you can use refs (e1, e2, ...) in interaction tools without calling a11y_take-aria-snapshot separately. Use `snapshotOptions` for `interactiveOnly` (default false) and `cursorInteractive` (default false). Set `includeSnapshot: false` to get only url/status/ok. When `includeScreenshot: true`, the screenshot is always saved to disk; `screenshotFilePath` is returned. By default `outputPath` is the OS temp dir and `name` is "screenshot" (same as content_take-screenshot). Use `screenshotOptions.includeBase64: true` only when the file cannot be read from the returned path (e.g. remote, container).
navigation_reload
Reloads the current page. In case of multiple redirects, the navigation resolves with the response of the last redirect. If the reload does not produce a response, returns empty response. By default (includeSnapshot: true), an ARIA snapshot with refs is returned. Use `snapshotOptions` for `interactiveOnly` (default false) and `cursorInteractive` (default false), same as a11y_take-aria-snapshot. When `includeScreenshot: true`, the screenshot is saved to disk; `screenshotFilePath` is returned. Default path/name: OS temp dir and "screenshot" (same as content_take-screenshot). Use `screenshotOptions.includeBase64: true` only when the file cannot be read from the path.
o11y_get-console-messages
Retrieves console messages/logs from the browser with filtering options.
o11y_get-http-requests
Retrieves HTTP requests from the browser with filtering options.
o11y_get-trace-context
Gets the OpenTelemetry trace context (trace id and tracestate) from the live browser page when OTEL is enabled.
o11y_get-web-vitals
Collects Web Vitals (LCP, INP, CLS, TTFB, FCP) with Google thresholds and recommendations. Call after navigation or user actions; use waitMs for more stable LCP/CLS/INP. Some metrics may be unavailable depending on browser and interactions.
o11y_new-trace-id
Generates new OpenTelemetry compatible trace id and sets it to the current session.
o11y_set-trace-context
Sets or clears the OpenTelemetry trace context. Empty traceId clears the MCP-pinned trace id (new browser traces get random ids). Empty traceState clears tracestate. Non-empty traceState must be valid W3C tracestate (comma-separated key=value list).
react_get-component-for-element
Finds React component(s) for a DOM element via React Fiber (best-effort). Give selector or (x,y); we resolve the element, find __reactFiber$ on it or ancestors, then build the component stack from the host fiber that owns that node. Fiber is not a public API—results vary by dev/prod build; names can be displayName, wrappers, or minified. wrappersDetected/wrapperFrames help with memo/forwardRef/context. If hostMapping.strategy is ancestor-fallback, use a more specific selector or deeper node for better accuracy.
react_get-element-for-component
Maps a React component instance to the DOM elements it renders (DOM footprint) by traversing the Fiber graph. Prefer an anchor (anchorSelector or anchorX/anchorY) to target the instance; optionally add a query (componentName, fileNameHint, lineNumber) to search Fiber. With both, we rank candidates and pick the best match near the anchor. React DevTools hook gives reliable root discovery (getFiberRoots); without it we fall back to DOM scan for __reactFiber$ (best-effort). For more reliable roots in a persistent browser, install the React Developer Tools Chrome extension. Debug source is best-effort and may be missing in some builds.
scenario-add
Adds a new scenario. A scenario is a reusable JS script (like execute) that can call tools via callTool(). Scenarios are stored on disk under the scenarios.json file (project-level by default, or global with scope="global").
scenario-update
Updates an existing scenario's description and/or script.
scenario-delete
Deletes a scenario by name.
scenario-list
Lists all available scenarios. When scope is omitted, returns scenarios from both project and global scopes (project overrides global for same name).
scenario-search
Searches scenarios by query across both project and global scopes. Uses configurable search strategy (SEARCH_STRATEGY or SCENARIO_SEARCH_STRATEGY env var). Returns matching scenarios ranked by relevance.
stub_clear
Clears stubs installed. - If stubId is provided, clears only that stub. - If stubId is omitted, clears all stubs for the current session/context.
stub_intercept-http-request
Installs a request interceptor stub that can modify outgoing requests before they are sent. Use cases: - A/B testing / feature flags (inject headers) - Security testing (inject malformed headers / payload) - Edge cases (special characters, large payload) - Auth simulation (add API keys / tokens in headers) Notes: - pattern is a glob matched against the full request URL (picomatch). - This modifies requests; it does not change responses. - times limits how many times the interceptor applies (-1 means infinite).
stub_list
Lists currently installed stubs for the active browser context/session. Useful to debug why certain calls are being mocked/intercepted.
stub_mock-http-response
Installs a response stub for matching requests using glob patterns (picomatch). Use cases: - Offline testing (return 200 with local JSON) - Error scenarios (force 500/404 or abort with timedout) - Edge cases (empty data / huge payload / special characters) - Flaky API testing (chance < 1.0) - Performance testing (delayMs) Notes: - pattern is a glob matched against the full request URL. - stubs are evaluated in insertion order; first match wins. - times limits how many times the stub applies (-1 means infinite).
sync_wait-for-network-idle
Waits until the page is network-idle: in-flight requests <= maxConnections for at least idleTimeMs (server-side tracking, no page globals). Use before SPAs, screenshots, or AX snapshots for stable results. With long-polling, increase maxConnections or use shorter idleTimeMs.
execute
Batch-execute multiple tool calls in a single request via custom JavaScript. Reduces round-trips and token usage. **IMPORTANT** - The code is already run inside an async function. Pass only the body (statements). Do NOT wrap in `async function() { ... }` or `async () => { ... }` — that causes a syntax error. Write `await callTool(...); return x;` directly. **IMPORTANT:** - `page` (Playwright Page) is available in the VM — use it for navigation or `page.evaluate()`. - Prefer interaction tools with refs (e1, e2 from a11y_take-aria-snapshot); use raw Playwright only as last resort. - `document`/`window` are not in the VM — use `page.evaluate(() => { ... })` to run code in the browser. - Use `waitForNavigation: true` on interaction_click when the click navigates. - After navigation, do not continue with refs from the previous page — take fresh refs with a11y_take-aria-snapshot first. Bindings: - await callTool(name, input, returnOutput?): async — always use with await. Returns the tool output for in-code use. returnOutput=true also includes it in the response toolOutputs array; false (default) omits it. Throws on failure — execution stops at the first error; partial toolOutputs/logs are still returned. On failure, failedTool in the response identifies which tool caused the error. Max 50 callTool invocations per execution. - console.log/warn/error: captured in the response logs array. - sleep(ms): async delay. Built-ins: Math, JSON, Date, RegExp, Number, String, Boolean, Array, Object, Promise, Map, Set, WeakMap, WeakSet, Symbol, Proxy, Reflect, URL, URLSearchParams, TextEncoder/Decoder, structuredClone, crypto.randomUUID(), AbortController, setTimeout/clearTimeout. NOT available: require, import, process, fs, Buffer, fetch. **Example** — fill form, submit (with navigation wait), then snapshot and screenshot: await callTool('interaction_fill', { selector: 'e3', value: 'user@test.com' }); await callTool('interaction_fill', { selector: 'e5', value: 'secret123' }); await callTool('interaction_click', { selector: 'e7', waitForNavigation: true }); // Or with page.locator: await page.locator('button').click(); // Or with page.evaluate: await page.evaluate(() => document.querySelector('button').click()); await callTool('a11y_take-aria-snapshot', {}, true); await callTool('content_take-screenshot', {}, true);
scenario-run
Runs a saved scenario by name. Looks up the scenario in project scope first, then global. The scenario's JS script runs in the same sandbox as execute: callTool(), console, sleep are available. Scenarios can compose other scenarios via callTool('scenario-run', { name: '...' }). Max recursion depth: 5.
Claude Desktop / Cursor
Paste into your MCP client config file to install this server.
{
"mcpServers": {
"browser devtools mcp": {
"browser-devtools": {
"command": "npx",
"args": [
"-y",
"browser-devtools-mcp"
]
}
}
}
}
McpServers
{
"browser-devtools": {
"command": "npx",
"args": [
"-y",
"browser-devtools-mcp"
]
}
}
<p align="center">
<br>
<strong style="font-size: 2em;">Browser DevTools MCP</strong>
</p>
<p align="center">
<a href="https://github.com/serkan-ozal/browser-devtools-mcp/actions/workflows/build.yml"></a>
<a href="https://www.npmjs.com/package/browser-devtools-mcp"></a>
<a href="https://github.com/serkan-ozal/browser-devtools-mcp/blob/main/LICENSE"></a>
</p>
<p align="center">
A powerful <a href="https://modelcontextprotocol.io">Model Context Protocol (MCP)</a> server that provides AI coding assistants with comprehensive browser automation and debugging capabilities using Playwright. This server enables both <strong>execution-level debugging</strong> (logs, network requests) and <strong>visual debugging</strong> (screenshots, ARIA snapshots) to help AI assistants understand and interact with web pages effectively.
</p>
Overview
Browser DevTools MCP exposes a Playwright-powered browser runtime to AI agents, enabling deep, bidirectional debugging and interaction with live web pages. It supports both visual understanding and code-level inspection of browser state, making it ideal for AI-driven exploration, diagnosis, and automation.
Key Capabilities
- Visual Inspection: Screenshots, ARIA snapshots, HTML/text extraction, PDF generation
- Design Comparison: Compare live page UI against Figma designs with similarity scoring
- DOM & Code-Level Debugging: Element inspection, computed styles, accessibility data
- Browser Automation: Navigation, input, clicking, scrolling, viewport control
- Execution Monitoring: Console message capture, HTTP request/response tracking
- OpenTelemetry Integration: Automatic trace injection into web pages, UI trace collection, and backend trace correlation via trace context propagation
- JavaScript Execution: Execute code in browser page context or in Node.js VM sandbox on the server
- Session Management: Long-lived, session-based debugging with automatic cleanup
- Multiple Transport Modes: Supports both stdio and HTTP transports
Features
Content Tools
- Screenshots: Capture full page or specific elements (PNG/JPEG) with image data - HTML/Text Extraction: Get page content with filtering, cleaning, and minification options - PDF Export: Save pages as PDF documents with customizable format and marginsInteraction Tools
- Click: Click elements by CSS selector - Fill: Fill form inputs - Hover: Hover over elements - Press Key: Simulate keyboard input - Select: Select dropdown options - Drag: Drag and drop operations - Scroll: Scroll the page viewport or specific scrollable elements with multiple modes (by, to, top, bottom, left, right) - Resize Viewport: Resize the page viewport using Playwright viewport emulation - Resize Window: Resize the real browser window (OS-level) using Chrome DevTools ProtocolNavigation Tools
- Go To: Navigate to URLs with configurable wait strategies - Go Back: Navigate backward in history - Go Forward: Navigate forward in historyRun Tools
- JS in Browser: Execute JavaScript code inside the active browser page (page context with access to window, document, DOM, and Web APIs) - JS in Sandbox: Execute JavaScript code in a Node.js VM sandbox on the MCP server (with access to Playwright Page, console logging, and safe built-ins)Observability (O11Y) Tools
- Console Messages: Capture and filter browser console logs with advanced filtering (level, search, timestamp, sequence number) - HTTP Requests: Monitor network traffic with detailed request/response data, filtering by resource type, status code, and more - Web Vitals: Collect Core Web Vitals (LCP, INP, CLS) and supporting metrics (TTFB, FCP) with ratings and recommendations based on Google's thresholds - OpenTelemetry Tracing: Automatic trace injection into web pages, UI trace collection (document load, fetch, XMLHttpRequest, user interactions), and trace context propagation for backend correlation - Trace ID Management: Get, set, and generate OpenTelemetry compatible trace IDs for distributed tracing across API callsSynchronization Tools
- Wait for Network Idle: Wait until the page reaches a network-idle condition based on in-flight request count, useful for SPA pages and before taking screenshotsAccessibility (A11Y) Tools
- ARIA Snapshots: Capture semantic structure and accessibility roles in YAML format - AX Tree Snapshots: Combine Chromium's Accessibility tree with runtime visual diagnostics (bounding boxes, visibility, occlusion detection, computed styles)Stub Tools
- Intercept HTTP Request: Intercept and modify outgoing HTTP requests (headers, body, method) using glob patterns - Mock HTTP Response: Mock HTTP responses (fulfill with custom status/headers/body or abort) with configurable delay, times limit, and probability (flaky testing) - List Stubs: List all currently installed stubs for the active browser context - Clear Stubs: Remove one or all installed stubsFigma Tools
- Compare Page with Design: Compare the current page UI against a Figma design snapshot and return a combined similarity score using multiple signals (MSSIM, image embedding, text embedding)React Tools
- Get Component for Element: Find React component(s) associated with a DOM element using React Fiber (best-effort) - Get Element for Component: Map a React component instance to the DOM elements it renders by traversing the React Fiber graphImportant Requirements for React Tools:
- Persistent Browser Context: React tools work best with persistent browser context enabled (BROWSER_PERSISTENT_ENABLE=true)
- React DevTools Extension: For optimal reliability, manually install the "React Developer Tools" Chrome extension in the browser profile. The MCP server does NOT automatically install the extension.
- Chrome Web Store: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
- The extension enables reliable root discovery and component search via __REACT_DEVTOOLS_GLOBAL_HOOK__
- Without the extension, tools fall back to scanning DOM for __reactFiber$ pointers (best-effort, less reliable)
Prerequisites
- Node.js 18+
- An AI assistant (with MCP client) like Cursor, Claude (Desktop or Code), VS Code, Windsurf, etc.
Quick Start
This MCP server (using STDIO or Streamable HTTP transport) can be added to any MCP Client
like VS Code, Claude, Cursor, Windsurf, GitHub Copilot via the browser-devtools-mcp NPM package.
No manual installation required! The server can be run directly using npx, which automatically downloads and runs the package.
CLI Arguments
Browser DevTools MCP server supports the following CLI arguments for configuration:
- --transport <stdio|streamable-http> - Configures the transport protocol (defaults to stdio).
- --port <number> – Configures the port number to listen on when using streamable-http transport (defaults to 3000).
Install as AI Agent Skill
Install browser automation capabilities as a skill for AI coding agents (Claude Code, Cursor, Windsurf, etc.) using the skills.sh ecosystem:
npx skills add serkan-ozal/browser-devtools-mcp
This installs the CLI skill that enables AI agents to automate browsers for web testing, screenshots, form filling, accessibility audits, performance analysis, and more. See the CLI Skills Documentation for details.
MCP Client Configuration
Claude Desktop
…
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.


