browser-control-mcp-server
# browser-control-mcp-server
MCP server that gives AI agents full browser control — navigate to any website, click, type, scroll, take screenshots, inspect DOM, and read console logs.
Works with **any MCP-compatible client**: Claude, Cursor, Windsurf, Cline, and more.
## Features
- **Navigate** to any URL — public sites, localhost, web apps
- **Screenshot** pages and get visual feedback as PNG images
- **Click** buttons, links, menus, dropdowns by CSS selector
- **Type** into inputs, search bars, textareas, password fields
- **Scroll** in any direction by pixel amount
- **Read DOM** — get full HTML source for structural analysis
- **Console logs** — read JS errors, warnings, and debug output
- **Custom viewports** — test at desktop (1920x1080), tablet (768x1024), or mobile (375x812)
- **Session persistence** — cookies, login state, history maintained across calls
- **Two modes**: headless Puppeteer (background) or real Chrome browser (via CDP connect)
- **Anti-bot bypass** — spoofed user agent, no webdriver flag
## Quick Start
### 1. Install
```bash
npm install -g browser-control-mcp-server
```
That's it. The installer **automatically configures** `browser-control` in all detected AI clients on your system — no manual setup needed.
**Supported clients (auto-configured on install):**
Claude Desktop · Claude Code · Cursor · Windsurf · VS Code (Copilot/Cline) · Zed · Continue · OpenCode · Cody
Works on **macOS, Windows, and Linux**.
After install you'll see something like:
```
[browser-control-mcp] Configuring AI clients...
✓ Claude Desktop configured
✓ Cursor configured
— Windsurf not found (skipped)
[browser-control-mcp] Done. Restart your AI client to activate browser-control.
```
Just **restart your AI client** and the browser tools are ready.
---
### Manual Configuration (if needed)
If auto-setup didn't catch your client, add this to your MCP config manually:
```json
{
"mcpServers": {
"browser-control": {
"command": "npx",
"args": ["browser-control-mcp-server"]
}
}
}
```
### 2. Use It
Tell your AI agent:
> "Open https://example.com and take a screenshot"
> "Fill out the contact form on my site and submit it"
> "Check my website on mobile viewport and show me how it looks"
The agent will use the browser tools automatically.
## Tools
| Tool | Description |
|------|-------------|
| `browser_select_mode` | Choose headless or Chrome extension mode |
| `browser_status` | Check connection status and active sessions |
| `browser_navigate` | Open any URL with optional viewport size |
| `browser_screenshot` | Capture page as PNG image |
| `browser_click` | Click element by CSS selector |
| `browser_type` | Type text into input fields |
| `browser_scroll` | Scroll page by pixel amount |
| `browser_get_url` | Get current page URL |
| `browser_get_dom` | Get HTML (or plain text), optionally scoped to a selector |
| `browser_console_logs` | Read JS console output |
| `browser_snapshot` | Compact accessibility-tree view, cheaper than a full DOM dump |
| `browser_extract` | Extract visible text or an attribute, without raw HTML |
| `browser_keyboard` | Press keys and key combinations |
| `browser_hover` | Hover over an element |
| `browser_select_option` | Select from a native `<select>` dropdown |
| `browser_wait_for` | Wait for an element, text, or timeout |
| `browser_handle_dialog` | Accept or dismiss alert/confirm/prompt dialogs |
| `browser_file_upload` | Upload files to a file input |
| `browser_drag_drop` | Drag and drop between elements |
| `browser_tabs` | List, open, switch, or close tabs |
| `browser_navigate_back` | Go back to the previous page |
| `browser_execute` | Run arbitrary JavaScript in the page |
| `browser_cookies` | Get, set, delete, or clear cookies |
| `browser_storage` | Get, set, or clear localStorage/sessionStorage |
| `browser_pdf` | Render the current page to a PDF file |
| `browser_network` | List captured requests or block by resource type (headless only) |
| `browser_downloads` | Configure a download directory and list downloaded files |
| `browser_stats` | Cheap page-size pre-check before calling `browser_get_dom` |
| `browser_macro` | Save a named sequence of tool calls, replay it later |
| `browser_auth` | Set/clear HTTP Basic/Digest Auth credentials |
| `browser_emulate` | Device presets, dark mode, timezone, geolocation, permissions, network/CPU throttling |
| `browser_frames` | List iframes; target one with `frameIndex` on click/type/get_dom |
| `browser_form_fill` | Fill multiple form fields (inputs, selects, checkboxes) in one call |
| `browser_reload` | Reload the page, with an optional cache-bypassing hard refresh |
| `browser_navigate_forward` | Go forward (counterpart to `browser_navigate_back`) |
| `browser_page_errors` | Read uncaught JS exceptions, distinct from console logs |
| `browser_clipboard` | Read/write the system clipboard (auto-grants permission) |
| `browser_get_element` | Full detail on one element: attributes, bounding box, styles |
| `browser_find` | Search for elements by text/role, no CSS selector needed |
| `browser_profiles` | List/delete named persistent Chrome profiles |
## Browser Modes
### Headless Mode (Default)
Opens an invisible background browser using Puppeteer. No setup required.
- Default viewport: 1024x768
- Custom viewport: pass `width` and `height` to `browser_navigate`
- Anti-bot detection bypass included
- Sessions identified by `sessionId` — pass to all subsequent calls
### Connect Mode (Optional)
Controls your real running Chrome browser via the Chrome DevTools Protocol (CDP). No extension required.
**Setup:**
Launch Chrome with the remote debugging port enabled:
```bash
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
# Linux
google-chrome --remote-debugging-port=9222
# Windows
chrome.exe --remote-debugging-port=9222
```
Then set connect mode in your AI agent:
```
browser_select_mode({ mode: "connect" })
```
The server connects to your running Chrome instance and controls it directly — no extension install needed.
## Examples
### Check a website
```
browser_navigate({ url: "https://example.com" })
browser_screenshot()
```
### Test mobile layout
```
browser_navigate({ url: "https://example.com", width: 375, height: 812 })
browser_screenshot()
```
### Fill and submit a form
```
browser_navigate({ url: "https://example.com/contact" })
browser_type({ selector: "input[name=email]", text: "user@example.com" })
browser_type({ selector: "textarea[name=message]", text: "Hello!" })
browser_click({ selector: "button[type=submit]" })
browser_screenshot()
```
### Login to a site
```
browser_navigate({ url: "https://example.com/login" })
browser_type({ selector: "#username", text: "myuser" })
browser_type({ selector: "#password", text: "mypass" })
browser_click({ selector: "#login-btn" })
browser_screenshot()
```
### Debug JavaScript errors
```
browser_navigate({ url: "https://example.com" })
browser_console_logs()
```
## Tool Parameters
### browser_navigate
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `url` | string | Yes | — | URL to navigate to |
| `width` | number | No | 1024 | Viewport width in pixels (headless only) |
| `height` | number | No | 768 | Viewport height in pixels (headless only) |
| `sessionId` | string | No | — | Reuse existing headless session |
| `mode` | string | No | — | `"extension"` or `"headless"` |
### browser_click
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `selector` | string | Yes | CSS selector (e.g. `"#btn"`, `"button[type=submit]"`, `".nav-link"`) |
| `sessionId` | string | No | Headless session ID |
| `mode` | string | No | `"extension"` or `"headless"` |
### browser_type
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `selector` | string | Yes | CSS selector of input element |
| `text` | string | Yes | Text to type |
| `sessionId` | string | No | Headless session ID |
| `mode` | string | No | `"extension"` or `"headless"` |
### browser_scroll
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `x` | number | No | 0 | Horizontal scroll (positive=right) |
| `y` | number | No | 0 | Vertical scroll (positive=down) |
| `sessionId` | string | No | — | Headless session ID |
| `mode` | string | No | — | `"extension"` or `"headless"` |
### browser_screenshot, browser_get_url, browser_get_dom, browser_console_logs
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sessionId` | string | No | Headless session ID |
| `mode` | string | No | `"extension"` or `"headless"` |
### browser_select_mode
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `mode` | string | No | `"extension"` or `"headless"` — sets session default |
### browser_status
No parameters.
## Viewport Presets
| Device | Width | Height |
|--------|-------|--------|
| Mobile (iPhone) | 375 | 812 |
| Mobile (Android) | 360 | 800 |
| Tablet (iPad) | 768 | 1024 |
| Laptop | 1366 | 768 |
| Desktop | 1920 | 1080 |
| 4K | 3840 | 2160 |
## Requirements
- Node.js >= 18.0.0
- Chrome/Chromium (auto-downloaded by Puppeteer for headless mode)
- Chrome browser + extension (for extension mode only)
## Development
```bash
git clone https://github.com/yogesh-joshi-0333/browser-control-mcp-server.git
cd browser-control-mcp-server
npm install
npm run build
npm test
```
## License
[MIT](LICENSE) — [Yogesh Joshi](https://devyogesh.com)
TDQS
Scored across 40 tools
Several inspection tools (browser_get_dom, browser_snapshot, browser_extract, browser_get_element, browser_find, browser_stats) all retrieve page content with subtle differences, making misselection likely. Interaction and navigation tools are mostly distinct, but the large surface adds ambiguity. Descriptions help, but the overlap is still notable.
All 40 tools use the browser_ prefix with snake_case verb/noun naming (e.g., browser_navigate, browser_click, browser_get_dom). There are no deviations in case or structure. The pattern is highly predictable throughout.
40 tools is well above the 15-tool guideline and feels excessive for a browser control server. While the domain is broad, many capabilities could be consolidated (e.g., the inspection tools). The large count forces agents to navigate a heavy menu for common actions.
The surface covers navigation, interaction, inspection, network, storage, cookies, emulation, dialogs, uploads/downloads, tabs, frames, and more, with no obvious major gaps. A minor missing piece is an explicit session-close tool, though closing all tabs is a workaround. Overall coverage is strong.