Skip to main content
Glama
yogesh-joshi-0333

browser-control-mcp-server

README.md
# 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 full HTML source |
| `browser_console_logs` | Read JS console output |

## 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)