Content
<p align="center">
<img src="extension/icons/icon-128.png" alt="BrowserMCP" width="96" height="96">
</p>
<h1 align="center">BrowserMCP</h1>
<p align="center">
<strong>Remote control browser tabs via the Model Context Protocol</strong>
</p>
<p align="center">
<a href="#-features"><img src="https://img.shields.io/badge/tools-40-6366f1" alt="40 Tools"></a>
<a href="#-resources"><img src="https://img.shields.io/badge/resources-6-22c55e" alt="6 Resources"></a>
<a href="#-prompts"><img src="https://img.shields.io/badge/prompts-5-f59e0b" alt="5 Prompts"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-64748b" alt="MIT License"></a>
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D18-339933" alt="Node >=18"></a>
<a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-1.0-8b5cf6" alt="MCP 1.0"></a>
</p>
<p align="center">
<a href="#-quick-start">Quick Start</a> •
<a href="#-tools">Tools</a> •
<a href="#-resources">Resources</a> •
<a href="#-prompts">Prompts</a> •
<a href="#-project-structure">Structure</a> •
<a href="#-configuration">Configuration</a> •
<a href="#-security">Security</a>
</p>
---
BrowserMCP exposes **40 Chrome automation tools**, **6 resources**, and **5 prompts** over SSE transport — ready for any MCP client (Claude, opencode, Cursor, custom agents). Navigate pages, extract content, fill forms, take screenshots, and more, all through the browser extension.
## Architecture
```
┌──────────────┐ SSE :3101 ┌──────────────────┐
│ MCP Client │◄──────────────────►│ Node MCP Server │
│ (Claude, │ │ index.js + src/ │
│ opencode) │ └────────┬─────────┘
└──────────────┘ │
WS :3100
│
┌────────────▼─────────┐
│ Chrome Extension │
│ Service Worker │
│ Popup UI │
└──────────────────────┘
```
| Layer | Tech | Port | Role |
|-------|------|------|------|
| **MCP Server** | Node.js + `@modelcontextprotocol/sdk` | `3101` | Tool/resource/prompt registration, validation, error boundaries |
| **WebSocket Bridge** | `ws` | `3100` | Message relay between MCP server and extension |
| **Chrome Extension** | Manifest V3, Extension APIs | — | Executes CDP commands (navigate, click, screenshot, etc.) |
## Features
- **40 tools** — tab management, page content, interaction, JS execution, visual, element query, utility
- **6 resources** — live tab list, page text/HTML/title/links, screenshots
- **5 prompts** — scrape, fill forms, debug, summarize, extract data
- **SSE transport** — standard MCP protocol, works with any MCP client
- **Tab scope** — restrict operations to all tabs or a selected subset
- **Permission toggle** — enable/disable individual tools from the popup
- **Graceful shutdown** — SIGTERM/SIGINT drains pending requests before exit
- **Error boundaries** — typed error categories (`[ValidationError]`, `[ConnectionError]`, `[AccessError]`)
- **DI pattern** — bridge injected into handlers, easy to unit test
## Quick Start
### 1. Install
```bash
git clone <your-repo-url>
cd BrowserMCP-Extentions
npm install
```
### 2. Start the Server
```bash
npm start
```
```
[MCP] HTTP server on port 3101 (SSE transport)
```
### 3. Load the Extension
1. Open `chrome://extensions`
2. Enable **Developer mode** (top-right)
3. Click **Load unpacked** → select the `extension/` directory
4. The extension connects to `ws://127.0.0.1:3100` automatically
### 4. Configure Your MCP Client
```json
{
"mcpServers": {
"browser": {
"type": "sse",
"url": "http://localhost:3101/mcp"
}
}
}
```
Health check:
```bash
curl http://localhost:3101/health
```
```json
{ "ok": true, "connected": true }
```
### 5. Verify
Open the extension popup — you should see **Online** with a green badge. Run a tool:
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_tabs",
"arguments": {}
}
}
```
## Tools
<details>
<summary><strong>Tab Management</strong> (7 tools)</summary>
| Tool | Description |
|------|-------------|
| `list_tabs` | List all open tabs |
| `get_active_tab` | Get the currently active tab |
| `navigate` | Navigate to a URL |
| `create_tab` | Open a new tab |
| `close_tab` | Close a tab by ID |
| `switch_to_tab` | Switch focus to a tab |
| `reload_tab` | Reload a tab |
</details>
<details>
<summary><strong>Page Content</strong> (9 tools)</summary>
| Tool | Description |
|------|-------------|
| `get_page_text` | Get page text content |
| `get_page_html` | Get full page HTML |
| `get_page_title` | Get document title |
| `get_selected_text` | Get user's text selection |
| `get_links` | Extract all links |
| `get_images` | Extract all images |
| `get_forms` | List form fields |
| `get_meta_tags` | Extract meta tags |
| `get_page_dimensions` | Page scroll/viewport size |
</details>
<details>
<summary><strong>Interaction</strong> (10 tools)</summary>
| Tool | Description |
|------|-------------|
| `click` | Click element by CSS selector |
| `fill` | Set input value |
| `select_option` | Select dropdown option |
| `hover` | Hover over element |
| `focus` | Focus element |
| `press_key` | Dispatch keyboard event |
| `scroll` | Scroll to x,y position |
| `scroll_to_element` | Scroll element into view |
| `scroll_to_bottom` | Scroll to page bottom |
| `scroll_to_top` | Scroll to page top |
</details>
<details>
<summary><strong>JS & Data</strong> (4 tools)</summary>
| Tool | Description |
|------|-------------|
| `execute_js` | Run arbitrary JavaScript |
| `get_cookies` | Get page cookies |
| `get_local_storage` | Get localStorage contents |
| `get_session_storage` | Get sessionStorage contents |
</details>
<details>
<summary><strong>Visual</strong> (3 tools)</summary>
| Tool | Description |
|------|-------------|
| `screenshot` | Capture visible tab as PNG |
| `highlight_element` | Flash highlight on element |
| `inject_css` | Inject custom CSS into page |
</details>
<details>
<summary><strong>Element Query</strong> (6 tools)</summary>
| Tool | Description |
|------|-------------|
| `get_element_text` | Get element text content |
| `get_element_html` | Get element outer HTML |
| `get_element_rect` | Get element bounding rect |
| `get_element_attribute` | Read element attribute |
| `set_element_attribute` | Write element attribute |
| `get_elements_count` | Count matching elements |
</details>
<details>
<summary><strong>Utility</strong> (1 tool)</summary>
| Tool | Description |
|------|-------------|
| `wait` | Wait for N milliseconds |
</details>
## Resources
| URI | Schema | Description |
|-----|--------|-------------|
| `chrome://tabs` | `text/plain` | Live tab list as JSON |
| `chrome://page/text` | `text/plain` | Current page text content |
| `chrome://page/html` | `text/plain` | Current page HTML |
| `chrome://page/title` | `text/plain` | Page title |
| `chrome://page/links` | `text/plain` | All page links as JSON |
| `chrome://page/screenshot` | `text/plain` | Base64-encoded PNG screenshot |
> Resources return plain text — the MCP client renders it appropriately.
## Prompts
| Prompt | Input | Output |
|--------|-------|--------|
| `scrape_page` | selector? | Extraction agent: get text, links, images → formatted summary |
| `fill_form` | selector, values | Fill agent: find form fields, fill values, submit |
| `debug_page` | — | Diagnostic agent: title, URL, meta tags, console state, forms |
| `summarize_page` | — | Summary agent: extract and condense page content |
| `extract_data` | schema | Extraction agent: pull structured data matching the schema |
## Extension Popup
The Chrome extension popup provides full control over the MCP server:
- **Connection status** — green/grey/red badge indicator
- **Server URL** — configurable WebSocket endpoint
- **Tab info** — current tab title, URL, favicon
- **Scope toggle** — `All` tabs or `Selected` subset
- **Search** — filter 40 tools by name (debounced)
- **Collapsible categories** — 7 groups with tool counts
- **Bulk actions** — Enable All, Disable All, Expand All, Collapse
## Project Structure
```
BrowserMCP-Extentions/
├── index.js # Entry point: HTTP + SSE, DI wiring
├── package.json
│
├── src/
│ ├── bridge.js # WS factory, permission state, pending queue
│ ├── tools.js # 40 tool definitions + validateArgs + error boundary
│ ├── resources.js # 6 resource handlers + error boundary
│ ├── prompts.js # 5 prompt templates
│ ├── lifecycle.js # Graceful shutdown (SIGTERM/SIGINT)
│ └── config.js # Port and timeout constants
│
├── extension/
│ ├── manifest.json # Manifest V3
│ ├── background.js # Service worker: WS bridge, 40 tool implementations
│ ├── content.js # Content script
│ ├── popup.html # Modern popup UI
│ ├── popup.js # Popup logic
│ └── icons/ # Extension icons (16, 48, 128)
│
├── scripts/
│ └── generate-icons.cjs # Icon generation (sharp)
│
└── README.md
```
## Configuration
All constants in `src/config.js`:
| Variable | Default | Description |
|----------|---------|-------------|
| `EXT_WS_PORT` | `3100` | WebSocket port for extension bridge |
| `HTTP_PORT` | `3101` | HTTP port for SSE transport |
| `EXT_TIMEOUT` | `60000` | Extension response timeout (ms) |
## Security
- **Local only** — the extension runs in your local browser; no remote access
- **Tab Scope** — `selected` mode limits which tabs tools can operate on
- **Permission sync** — tool enable/disable state synced from popup → server via `update_allowlist`
- **Input validation** — every tool validates required arguments before execution
- **Error boundaries** — failures categorised as `[ValidationError]`, `[ConnectionError]`, or `[AccessError]`
- **Graceful shutdown** — SIGTERM/SIGINT rejects pending promises, cleans up all connections
## Development
```bash
# Syntax check
node --check index.js
node --check src/*.js
node --check extension/popup.js
# Regenerate icons
node scripts/generate-icons.cjs
# Requirements
# Node.js >= 18
# Chrome (for extension)
```
## License
MIT
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available