Skip to main content
Glama
obbbba

MCP-RealBrowser

by obbbba
README.md
# ๐Ÿ–ฅ๏ธ MCP-RealBrowser

> **A persistent browser profile for your AI โ€” log in once, sessions stay forever.**
>
> No more blank browser windows. No more "please copy-paste this page."
> Give your AI a dedicated browser identity, and it remembers everything.

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue)](https://www.typescriptlang.org/)
[![MCP](https://img.shields.io/badge/MCP-1.0-purple)](https://modelcontextprotocol.io/)
[![CI](https://github.com/obbbba/mcp-realbrowser/actions/workflows/ci.yml/badge.svg)](https://github.com/obbbba/mcp-realbrowser/actions/workflows/ci.yml)

---

## Why this exists

Every existing MCP browser tool launches a **fresh, blank browser** that forgets everything when closed:

| Tool | Problem |
|------|---------|
| `@playwright/mcp` | New incognito window, temporary profile โ€” lost on restart |
| `browser-use` | Python-only, doesn't speak MCP |
| `stagehand` | Data extraction focus, not general browsing |

**MCP-RealBrowser** gives your AI a **persistent browser profile** โ€” same directory, same cookies, same sessions across restarts. Log into GitHub, Gmail, Bilibili once, and it stays logged in forever.

---

## What it does

```
You: "Check my unread emails and summarize them"
AI:  navigate(gmail.com) โ†’ snapshot() โ†’ extract() โ†’ reads & summarizes

You: "Find flights to Tokyo next Friday under ยฅ3000"
AI:  navigate(ctrip.com) โ†’ fill("ๅ‡บๅ‘", "ไธŠๆตท") โ†’ fill("ๅˆฐ่พพ", "ไธœไบฌ")
     โ†’ click("ๆœ็ดข") โ†’ extract() โ†’ sorted results

You: "Open my GitHub and tell me how many stars I have"
AI:  navigate(github.com/obbbba) โ†’ snapshot() โ†’ "You have 1 star"
```

---

## Quick start

### 1. Install

```bash
git clone https://github.com/obbbba/mcp-realbrowser.git
cd mcp-realbrowser
npm install
npm run build
```

### 2. Run diagnostics

```bash
node dist/index.js --doctor
```

Checks: Node.js, dependencies, Chrome installed, Chrome running, CDP port open, debug flag enabled.

### 3. Launch your browser with debug port

> The browser uses a **separate persistent profile** โ€” your daily browser isn't affected.

**Windows (Edge โ€” pre-installed on Win11):**
```bat
scripts\launch-edge.bat
```

**Windows (Chrome):**
```bat
scripts\launch-chrome.bat
```

**Mac/Linux:**
```bash
chmod +x scripts/launch-chrome.sh
./scripts/launch-chrome.sh
```

### 4. Choose your mode

#### Mode A: MCP Server (recommended โ€” Claude Code auto-control)

Add to `.claude/settings.json` in your project:

```json
{
  "mcpServers": {
    "realbrowser": {
      "command": "npx",
      "args": ["tsx", "/path/to/mcp-realbrowser/src/index.ts"],
      "env": { "CDP_PORT": "9222" }
    }
  }
}
```

Restart Claude Code. Now you can just talk:
```
> Go to baidu.com and search for "MCP tutorial"
> Open GitHub trending page and find the top TypeScript repo
> Navigate to my Gmail and summarize unread emails
```

#### Mode B: Direct API (for scripts / custom tools)

```ts
import { CDPConnection } from "mcp-realbrowser";

const browser = new CDPConnection();
await browser.connect("http://localhost:9222");

await browser.navigate("github.com");
const snapshot = await browser.snapshot(); // AI sees the page
await browser.click("Sign in");
await browser.type("hello");
const screenshot = await browser.screenshot();

await browser.disconnect(); // Chrome stays open
```

### 5. Verify it works

```bash
npx tsx src/smoke-test.ts
# Expected: test runs pass
```
---

## Tools (20)

| Tool | What it does |
|------|-------------|
| `navigate(url)` | Open any URL in the current tab |
| `snapshot(query?)` | Get interactive elements โ€” filter with `query` to save tokens |
| `click(target)` | Click by CSS selector, text, role, placeholder, or label (6 strategies) |
| `type(text)` | Type into the focused input with human-like delay |
| `press_key(key)` | Press Enter, Tab, Escape, arrows, etc. |
| `screenshot(format?, quality?)` | Take a viewport screenshot (PNG/JPEG, quality 10-100 for JPEG) |
| `extract(maxChars?)` | Get visible text (default 3K chars, max 30K) |
| `scroll(direction, amount?)` | Scroll up/down, returns scroll position |
| `fill(field, value)` | Fill an input by placeholder or label |
| `select_option(target, value)` | Select an option in a `<select>` dropdown |
| `go_back()` | Navigate back in browser history |
| `go_forward()` | Navigate forward in browser history |
| `reload()` | Reload the current page |
| `hover(target)` | Hover over an element (dropdowns, tooltips) |
| `wait_for_text(text, timeout?)` | Wait for text to appear after an action |
| `list_tabs()` | List all open browser tabs with index, URL, and title |
| `select_tab(index)` | Switch to a tab by index |
| `new_tab(url?)` | Open a new browser tab |
| `close_tab(index)` | Close a tab by index |
| `reconnect()` | Reconnect to browser after restart |

### ๐Ÿ’ก Token-saving tips

```
snapshot(query="login")    โ€” only elements matching "login"
extract(maxChars=500)      โ€” small snippets, not full pages
screenshot(format="jpeg", quality=40) โ€” compact visual check
```

---

## Architecture

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     stdio (MCP)     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     CDP (ws)     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Claude Code โ”‚ โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚  MCP-RealBrowser  โ”‚ โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚  Browser profile โ”‚
โ”‚  (AI Agent)  โ”‚   JSON-RPC 2.0     โ”‚  (TypeScript)     โ”‚   DevTools Proto โ”‚  (persistent)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                           โ”‚
                                           โ”‚  chromium.connectOverCDP()
                                           โ”‚  DOM snapshot (interactive elements)
                                           โ”‚  page.screenshot()
                                           โ”‚  page.keyboard.type()
                                           โ–ผ
                                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                    โ”‚   Playwright  โ”‚
                                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

Key design decisions:
- **Persistent profile**: Browser data saved to `%LOCALAPPDATA%\mcp-realbrowser\` โ€” cookies, logins, localStorage survive browser restarts
- **CDP attach (not launch)**: Uses `connectOverCDP` โ€” the browser process lives independently from the MCP server
- **DOM snapshot for vision**: Structured element scan, 250-element limit keeps context manageable
- **Screenshot as fallback**: For visual pages where DOM structure isn't enough
- **Disconnect โ‰  Close**: Shutting down the MCP server never closes your browser
- **--doctor mode**: Diagnose and auto-fix browser/CDP issues before starting the server

---

## Troubleshooting

### "CDP port not accepting connections"

The browser isn't running with the debugging flag.

**Quick fix:**
```bash
# One command to diagnose and auto-fix
node dist/index.js --doctor --fix
```

**Or manually:**
```bash
# 1. Kill stale browser processes
taskkill /F /IM msedge.exe & taskkill /F /IM chrome.exe

# 2. Run the launch script
scripts\launch-edge.bat   # Windows (Edge)
scripts\launch-chrome.bat # Windows (Chrome)
./scripts/launch-chrome.sh # Mac/Linux
```

### Other issues

Run `--doctor` for a full diagnostic report:
```bash
node dist/index.js --doctor
```

### First time? Log in to your sites

The profile is empty on first launch. Log into GitHub, Gmail, Bilibili, etc. once โ€” cookies are saved to `%LOCALAPPDATA%\mcp-realbrowser\browser-profile` and persist forever.

---

## Supported browsers

| Browser | Support | Notes |
|---------|---------|-------|
| Edge | โœ… Full | Pre-installed on Win11, same CDP |
| Chrome | โœ… Full | All platforms |
| Brave | โœ… Full | Chromium-based |
| Arc | โœ… Full | Chromium-based |
| Opera | โœ… Full | Chromium-based |
| 360 / QQ / Sogou | โš ๏ธ Likely | Chromium-based, not tested |

---

## Contributing

Pull requests welcome! Areas you can help:
- **New tools** โ€” want `drag_and_drop` or `select_option`? PR it.
- **Bug fixes** โ€” found an edge case? Fix it.
- **Docs** โ€” better examples, translations, tutorials.
- **Tests** โ€” more coverage for edge cases.

1. Fork it
2. Create your feature branch (`git checkout -b feature/amazing`)
3. Run the smoke test: `npx tsx src/smoke-test.ts` โ€” should be 13/13
4. Commit (`git commit -m 'Add something amazing'`)
5. Push + open a Pull Request

---

## License

MIT ยฉ 2024

---

## Star History

If this is useful, a โญ on GitHub makes a big difference โ€” it tells others the project is worth their time.

---

[ไธญๆ–‡่ฏดๆ˜Ž](#chinese)

### ไธญๆ–‡่ฏดๆ˜Ž

**MCP-RealBrowser** ๆ˜ฏไธ€ไธช MCP ๆœๅŠกๅ™จ๏ผŒไธบ AI ๅŠฉๆ‰‹ๆไพ›**ๆŒไน…ๅŒ–็š„ๆต่งˆๅ™จ่บซไปฝ**ใ€‚็‹ฌ็ซ‹ profile ไธๅฝฑๅ“ไฝ ็š„ๆ—ฅๅธธๆต่งˆๅ™จใ€‚็™ปๅฝ•ไธ€ๆฌก GitHubใ€B ็ซ™ใ€Gmailโ€”โ€”Cookies ๆฐธไน…ไฟๅญ˜ๅˆฐ `%LOCALAPPDATA%\mcp-realbrowser\browser-profile`๏ผŒๅ…ณไบ†ๅ†ๅผ€็™ปๅฝ•ๆ€่ฟ˜ๅœจใ€‚

**ไธŽ็Žฐๆœ‰ๆ–นๆกˆ็š„ๅŒบๅˆซ๏ผš** Playwright MCP ๆฏๆฌกๅฏๅŠจไธดๆ—ถ profile๏ผŒๅ…ณ้—ญๅณ้”€ๆฏใ€‚ๆˆ‘ไปฌ็”จๅ›บๅฎšๆŒไน…็›ฎๅฝ•๏ผŒ็™ปๅฝ•ๆ€่ทจไผš่ฏไฟ็•™ใ€‚

**ไธค็งไฝฟ็”จๆ–นๅผ๏ผš**

**A. MCP Server ๆจกๅผ๏ผˆๆŽจ่๏ผ‰๏ผš**
1. `git clone` โ†’ `npm install` โ†’ `npm run build`
2. `node dist/index.js --doctor --fix` ไธ€้”ฎ่ฏŠๆ–ญๅนถๅฏๅŠจๆต่งˆๅ™จ
3. ๅœจ `.claude/settings.json` ไธญ้…็ฝฎ MCP Server
4. ้‡ๅฏ Claude Code๏ผŒ็›ดๆŽฅ่ฏด่ฏ

**B. ็›ดๆŽฅ API ๆจกๅผ๏ผš**
```ts
import { CDPConnection } from "mcp-realbrowser";
const browser = new CDPConnection();
await browser.connect("http://localhost:9222");
await browser.navigate("github.com");
await browser.click("Sign in");
await browser.disconnect();
```

**้ชŒ่ฏ๏ผš** `npx tsx src/smoke-test.ts`

**20 ไธชๅทฅๅ…ท๏ผš** navigate / snapshot / click / type / press_key / screenshot / extract / scroll / fill / select_option / go_back / go_forward / reload / hover / wait_for_text / list_tabs / select_tab / new_tab / close_tab / reconnect

**ๆ•…้šœๆŽ’้™ค๏ผš** `--doctor --fix` ่‡ชๅŠจๆฃ€ๆต‹ๅนถไฟฎๅคใ€‚ๆ”ฏๆŒ Edge / Chrome / Brave / Arc / Opera / Vivaldi / Chromium๏ผŒ่‡ชๅŠจ่ฏปๅ–็ณป็ปŸ้ป˜่ฎคๆต่งˆๅ™จใ€‚