browser-devtools-mcp
v0.0.2
Published
MCP Server for Browser Dev Tools
Maintainers
Readme
Browser DevTools MCP
A powerful Model Context Protocol (MCP) server that provides AI coding assistants with comprehensive browser automation and debugging capabilities using Playwright. This server enables both execution-level debugging (logs, network requests) and visual debugging (screenshots, ARIA snapshots) to help AI assistants understand and interact with web pages effectively.
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
- 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
- JavaScript Evaluation: Execute code in page context
- 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 margins
Interaction 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
- Evaluate: Execute JavaScript in page context
Navigation Tools
- Go To: Navigate to URLs with configurable wait strategies
- Go Back: Navigate backward in history
- Go Forward: Navigate forward in history
Monitoring 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
Accessibility (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)
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 tostdio).--port <number>– Configures the port number to listen on when usingstreamable-httptransport (defaults to3000).
MCP Client Configuration
Claude Desktop
Local Server
Add the following configuration into the claude_desktop_config.json file.
See the Claude Desktop MCP docs for more info.
{
"mcpServers": {
"browser-devtools": {
"command": "npx",
"args": ["-y", "browser-devtools-mcp"]
}
}
}Remote Server (HTTP Transport)
First, start the server with HTTP transport:
npx -y browser-devtools-mcp --transport=streamable-http --port=3000Then, go to Settings > Connectors > Add Custom Connector in Claude Desktop and add the MCP server with:
- Name:
Browser DevTools - Remote MCP server URL: Point to where your server is hosted (e.g.,
http://localhost:3000/mcpif running locally, orhttps://your-server.com/mcpif hosted remotely)
Claude Code
Run the following command. See Claude Code MCP docs for more info.
Local Server
claude mcp add browser-devtools -- npx -y browser-devtools-mcpRemote Server
First, start the server with HTTP transport:
npx -y browser-devtools-mcp --transport=streamable-http --port=3000Then add the MCP server:
claude mcp add --transport http browser-devtools <SERVER_URL>Replace <SERVER_URL> with your server URL (e.g., http://localhost:3000/mcp if running locally, or https://your-server.com/mcp if hosted remotely).
Cursor
Add the following configuration into the ~/.cursor/mcp.json file (or .cursor/mcp.json in your project folder).
See the Cursor MCP docs for more info.
Local Server
{
"mcpServers": {
"browser-devtools": {
"command": "npx",
"args": ["-y", "browser-devtools-mcp"]
}
}
}Remote Server
First, start the server with HTTP transport:
npx -y browser-devtools-mcp --transport=streamable-http --port=3000Then add the configuration:
{
"mcpServers": {
"browser-devtools": {
"url": "<SERVER_URL>"
}
}
}Replace <SERVER_URL> with your server URL (e.g., http://localhost:3000/mcp if running locally, or https://your-server.com/mcp if hosted remotely).
VS Code
Add the following configuration into the .vscode/mcp.json file.
See the VS Code MCP docs for more info.
Local Server
{
"mcp": {
"servers": {
"browser-devtools": {
"type": "stdio",
"command": "npx",
"args": ["-y", "browser-devtools-mcp"]
}
}
}
}Remote Server
First, start the server with HTTP transport:
npx -y browser-devtools-mcp --transport=streamable-http --port=3000Then add the configuration:
{
"mcp": {
"servers": {
"browser-devtools": {
"type": "http",
"url": "<SERVER_URL>"
}
}
}
}Replace <SERVER_URL> with your server URL (e.g., http://localhost:3000/mcp if running locally, or https://your-server.com/mcp if hosted remotely).
Windsurf
Add the following configuration into the ~/.codeium/windsurf/mcp_config.json file.
See the Windsurf MCP docs for more info.
Local Server
{
"mcpServers": {
"browser-devtools": {
"command": "npx",
"args": ["-y", "browser-devtools-mcp"]
}
}
}Remote Server
First, start the server with HTTP transport:
npx -y browser-devtools-mcp --transport=streamable-http --port=3000Then add the configuration:
{
"mcpServers": {
"browser-devtools": {
"serverUrl": "<SERVER_URL>"
}
}
}Replace <SERVER_URL> with your server URL (e.g., http://localhost:3000/mcp if running locally, or https://your-server.com/mcp if hosted remotely).
Copilot Coding Agent
Add the following configuration to the mcpServers section of your Copilot Coding Agent configuration through
Repository > Settings > Copilot > Coding agent > MCP configuration.
See the Copilot Coding Agent MCP docs for more info.
Local Server
{
"mcpServers": {
"browser-devtools": {
"type": "local",
"command": "npx",
"args": ["-y", "browser-devtools-mcp"]
}
}
}Remote Server
First, start the server with HTTP transport:
npx -y browser-devtools-mcp --transport=streamable-http --port=3000Then add the configuration:
{
"mcpServers": {
"browser-devtools": {
"type": "http",
"url": "<SERVER_URL>"
}
}
}Replace <SERVER_URL> with your server URL (e.g., http://localhost:3000/mcp if running locally, or https://your-server.com/mcp if hosted remotely).
Gemini CLI
Add the following configuration into the ~/.gemini/settings.json file.
See the Gemini CLI MCP docs for more info.
Local Server
{
"mcpServers": {
"browser-devtools": {
"command": "npx",
"args": ["-y", "browser-devtools-mcp"]
}
}
}Remote Server
First, start the server with HTTP transport:
npx -y browser-devtools-mcp --transport=streamable-http --port=3000Then add the configuration:
{
"mcpServers": {
"browser-devtools": {
"httpUrl": "<SERVER_URL>"
}
}
}Replace <SERVER_URL> with your server URL (e.g., http://localhost:3000/mcp if running locally, or https://your-server.com/mcp if hosted remotely).
Smithery
Run the following command. You can find your Smithery API key here. See the Smithery CLI docs for more info.
npx -y @smithery/cli install serkan-ozal/browser-devtools-mcp --client <SMITHERY-CLIENT-NAME> --key <SMITHERY-API-KEY>HTTP Transport
To use HTTP transport, start the server with:
npx -y browser-devtools-mcp --transport=streamable-http --port=3000The server exposes the following endpoints:
GET /health- Health checkGET /ping- Ping endpointGET /mcp- MCP protocol infoPOST /mcp- MCP protocol messagesDELETE /mcp- Delete session
Important: When configuring remote MCP servers, use the actual URL where your server is hosted:
- If running locally:
http://localhost:3000/mcp(orhttp://127.0.0.1:3000/mcp) - If hosted remotely:
https://your-server.com/mcp(replace with your actual server URL)
MCP Inspector
Test the server using the MCP Inspector:
# For stdio transport
npx -y @modelcontextprotocol/inspector npx -y browser-devtools-mcp
# For HTTP transport (start server first)
npx -y browser-devtools-mcp --transport=streamable-http --port=3000
# Then in another terminal:
npx -y @modelcontextprotocol/inspector http://localhost:3000/mcp --transport httpConfiguration
The server can be configured using environment variables:
| Variable | Description | Default |
|----------|-------------|---------|
| PORT | Port for HTTP transport | 3000 |
| SESSION_IDLE_SECONDS | Idle session timeout (seconds) | 300 |
| SESSION_IDLE_CHECK_SECONDS | Interval for checking idle sessions (seconds) | 30 |
| SESSION_CLOSE_ON_SOCKET_CLOSE | Close session when socket closes | false |
| CONSOLE_MESSAGES_BUFFER_SIZE | Maximum console messages to buffer | 1000 |
| HTTP_REQUESTS_BUFFER_SIZE | Maximum HTTP requests to buffer | 1000 |
| BROWSER_EXECUTABLE_PATH | Custom browser executable path | (uses Playwright default) |
Available Tools
Content Tools
content_take-screenshot
Takes a screenshot of the current page or a specific element.
Parameters:
outputPath(string, optional): Directory path where screenshot will be saved (default: OS temp directory)name(string, optional): Screenshot name (default: "screenshot")selector(string, optional): CSS selector for element to capturefullPage(boolean, optional): Capture full scrollable page (default: false)type(enum, optional): Image format - "png" or "jpeg" (default: "png")
Returns:
filePath(string): Full path of the saved screenshot fileimage(object): Screenshot image data with mimeType
content_get-as-html
Retrieves the HTML content of the current page or a specific element.
Parameters:
selector(string, optional): CSS selector to limit the HTML content to a specific containerremoveScripts(boolean, optional): Remove all script tags from the HTML (default: true)removeComments(boolean, optional): Remove all HTML comments (default: false)removeStyles(boolean, optional): Remove all style tags from the HTML (default: false)removeMeta(boolean, optional): Remove all meta tags from the HTML (default: false)cleanHtml(boolean, optional): Perform comprehensive HTML cleaning (default: false)minify(boolean, optional): Minify the HTML output (default: false)maxLength(number, optional): Maximum number of characters to return (default: 50000)
Returns:
output(string): The requested HTML content of the page
content_get-as-text
Retrieves the visible text content of the current page or a specific element.
Parameters:
selector(string, optional): CSS selector to limit the text content to a specific containermaxLength(number, optional): Maximum number of characters to return (default: 50000)
Returns:
output(string): The requested text content of the page
content_save-as-pdf
Saves the current page as a PDF document.
Parameters:
outputPath(string, optional): Directory path where PDF will be saved (default: OS temp directory)name(string, optional): PDF name (default: "page")format(enum, optional): Page format - "Letter", "Legal", "Tabloid", "Ledger", "A0" through "A6" (default: "A4")printBackground(boolean, optional): Whether to print background graphics (default: false)margin(object, optional): Page margins with top, right, bottom, left (default: "1cm" for each)
Returns:
filePath(string): Full path of the saved PDF file
Interaction Tools
interaction_click
Clicks an element on the page.
Parameters:
selector(string, required): CSS selector for the element to click
interaction_fill
Fills a form input field.
Parameters:
selector(string, required): CSS selector for the input fieldvalue(string, required): Value to fill
interaction_hover
Hovers over an element.
Parameters:
selector(string, required): CSS selector for the element to hover
interaction_press-key
Simulates keyboard input.
Parameters:
key(string, required): Key to press (e.g., "Enter", "Escape", "Tab")
interaction_select
Selects an option from a dropdown.
Parameters:
selector(string, required): CSS selector for the select elementvalue(string, required): Value to select
interaction_drag
Performs drag and drop operation.
Parameters:
sourceSelector(string, required): CSS selector for the source elementtargetSelector(string, required): CSS selector for the target element
interaction_evaluate
Executes JavaScript in the browser console.
Parameters:
script(string, required): JavaScript code to execute
Returns:
result(any): Result of the JavaScript evaluation
Navigation Tools
navigation_go-to
Navigates to a URL.
Parameters:
url(string, required): URL to navigate to (must include scheme)timeout(number, optional): Maximum operation time in milliseconds (default: 0 - no timeout)waitUntil(enum, optional): When to consider navigation succeeded - "load", "domcontentloaded", "networkidle", or "commit" (default: "load")
Returns:
url(string): Final URL after navigationstatus(number): HTTP status codestatusText(string): HTTP status textok(boolean): Whether navigation was successful (2xx status)
navigation_go-back
Navigates backward in browser history.
navigation_go-forward
Navigates forward in browser history.
Monitoring Tools
monitoring_get-console-messages
Retrieves console messages/logs from the browser with advanced filtering.
Parameters:
type(enum, optional): Filter by message level - "ERROR", "WARNING", "INFO", "DEBUG"search(string, optional): Text to search for in messagestimestamp(number, optional): Start time filter (Unix epoch milliseconds)sequenceNumber(number, optional): Only return messages after this sequence numberlimit(object, optional): Limit resultscount(number): Maximum number of messagesfrom(enum): "start" or "end" (default: "end")
Returns:
messages(array): Array of console messages with type, text, location, timestamp, and sequence number
monitoring_get-http-requests
Retrieves HTTP requests from the browser with detailed filtering.
Parameters:
resourceType(enum, optional): Filter by resource type (e.g., "document", "script", "stylesheet")status(object, optional): Filter by status code rangemin(number): Minimum status codemax(number): Maximum status code
ok(boolean, optional): Filter by success/failure (2xx = success)timestamp(number, optional): Start time filter (Unix epoch milliseconds)sequenceNumber(number, optional): Only return requests after this sequence numberlimit(object, optional): Limit resultscount(number): Maximum number of requestsfrom(enum): "start" or "end" (default: "end")
Returns:
requests(array): Array of HTTP requests with URL, method, headers, body, response, timing, and metadata
Accessibility (A11Y) Tools
a11y_take-aria-snapshot
Captures an ARIA (accessibility) snapshot of the current page or a specific element.
Parameters:
selector(string, optional): CSS selector for element to snapshot
Returns:
output(string): Includes the page URL, title, and a YAML-formatted accessibility tree
Usage:
- Use in combination with
accessibility_take-ax-tree-snapshotfor comprehensive UI analysis - Provides semantic structure and accessibility roles
- Helps identify accessibility issues and page hierarchy problems
accessibility_take-ax-tree-snapshot
Captures a UI-focused snapshot by combining Chromium's Accessibility (AX) tree with runtime visual diagnostics.
Parameters:
roles(array, optional): Optional role allowlist (button, link, textbox, checkbox, radio, combobox, switch, tab, menuitem, dialog, heading, listbox, listitem, option). If omitted, a built-in set of interactive roles is usedincludeStyles(boolean, optional): Whether to include computed CSS styles for each node (default: true)includeRuntimeVisual(boolean, optional): Whether to compute runtime visual information (bounding box, visibility, viewport) (default: true)checkOcclusion(boolean, optional): If true, checks whether each element is visually occluded by another element using elementFromPoint() sampled at multiple points (default: false)onlyVisible(boolean, optional): If true, only visually visible nodes are returned (default: false)onlyInViewport(boolean, optional): If true, only nodes intersecting the viewport are returned (default: false)textPreviewMaxLength(number, optional): Maximum length of the text preview extracted from each element (default: 80)styleProperties(array, optional): List of CSS computed style properties to extract (default: includes display, visibility, opacity, position, z-index, colors, fonts, etc.)
Returns:
url(string): The current page URL at the time the AX snapshot was capturedtitle(string): The document title of the page at the time of the snapshotaxNodeCount(number): Total number of nodes returned by Chromium Accessibility.getFullAXTree before filteringcandidateCount(number): Number of DOM-backed AX nodes that passed role filtering before enrichmentenrichedCount(number): Number of nodes included in the final enriched snapshot outputtruncatedBySafetyCap(boolean): Indicates whether the result set was truncated by an internal safety capnodes(array): List of enriched DOM-backed AX nodes combining accessibility metadata with visual diagnostics, including:axNodeId,parentAxNodeId,childAxNodeIds: Tree structurerole,name,ignored: Accessibility propertiesbackendDOMNodeId,domNodeId,frameId: DOM referenceslocalName,id,className,selectorHint: Element identificationtextPreview: Short preview of rendered text contentstyles: Computed CSS styles (if includeStyles is true)runtime: Visual diagnostics including boundingBox, isVisible, isInViewport, and optional occlusion data
Usage:
- Use to detect UI issues like elements that exist semantically but are visually hidden or off-screen
- Identify wrong layout/geometry, styling issues, and overlap/stacking/occlusion problems
- ALWAYS use
checkOcclusion: truewhen investigating UI/layout problems - Use alongside
a11y_take-aria-snapshottool for complete UI analysis
Architecture
Session Management
The server uses session-based architecture where each MCP client connection gets its own browser context and page. Sessions are automatically cleaned up when:
- The client disconnects
- The session becomes idle (configurable timeout)
- The session is explicitly closed
Browser Support
The server supports multiple browser engines:
- Chromium (default)
- Firefox
- WebKit
Browser instances are shared across sessions for efficiency, but each session has its own isolated browser context.
Buffering & Filtering
Console messages and HTTP requests are buffered in memory with configurable buffer sizes. Both tools support advanced filtering:
- Level-based filtering: Filter by severity/type
- Text search: Search within message/request content
- Time-based filtering: Filter by timestamp
- Incremental retrieval: Use sequence numbers to fetch only new items
- Pagination: Limit results with start/end trimming
Development
Prerequisites
- Node.js 18+
- npm or yarn
Setup
# Clone the repository
git clone https://github.com/serkan-ozal/browser-devtools-mcp.git
cd browser-devtools-mcp
# Install dependencies
npm install
# Build the project
npm run buildScripts
npm run build- Build TypeScript to JavaScriptnpm run start- Start server with stdio transportnpm run start:http- Start server with HTTP transportnpm run watch- Watch mode for developmentnpm run inspector- Run MCP Inspector (stdio)npm run inspector:http- Run MCP Inspector (HTTP)npm run lint:check- Check code formattingnpm run lint:format- Format code
Use Cases
For AI Coding Assistants
This server enables AI assistants to:
- Debug Web Applications: Capture screenshots, inspect DOM, check console errors
- Monitor Network Activity: Track API calls, analyze request/response patterns
- Test User Flows: Automate navigation and interactions
- Visual Verification: Compare visual states, verify UI changes
- Content Extraction: Get HTML/text content with filtering and cleaning options
- Accessibility Analysis: Use ARIA and AX tree snapshots to understand page structure and detect UI issues
- Performance Analysis: Monitor HTTP request timing and failures
Example Workflow
- Navigate to a web page using
navigation_go-to - Take a screenshot with
content_take-screenshotto see the current state - Check console messages with
monitoring_get-console-messagesfor errors - Monitor HTTP requests with
monitoring_get-http-requeststo see API calls - Capture accessibility snapshots with
a11y_take-aria-snapshotandaccessibility_take-ax-tree-snapshotto understand page structure - Interact with elements using
interaction_click,interaction_fill, etc. - Extract content using
content_get-as-htmlorcontent_get-as-text - Save the page as PDF using
content_save-as-pdffor documentation
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details.
Author
Serkan Ozal
- Email: [email protected]
- GitHub: @serkan-ozal
Acknowledgments
- Built with Playwright for browser automation
- Uses Model Context Protocol SDK for MCP implementation
- HTTP transport powered by Hono
