Skip to main content
Glama
Weiktseng

Chrome MCP Bridge

by Weiktseng
README.md
# Chrome MCP Bridge

Part of a **24/7 fully-automated unmanned software development system**. This is a standalone component; the core system is proprietary.

AI-driven browser automation for **real Chrome** — with cookies, login sessions, and extensions intact.

This stdio MCP server lets [Claude Code](https://claude.ai/code) (`claude --print`) control a visible Chrome browser through the Chrome DevTools Protocol. Unlike headless automation, everything happens in a real browser window — government reviewers can watch every action live.

## What It Does

An AI agent can:
- **Navigate** to any URL (government portals, internal systems)
- **Read** page content and accessibility trees
- **Fill forms** automatically (text fields, dropdowns, radio buttons)
- **Click buttons** and submit forms
- **Take screenshots** at every step for audit trails
- **Execute JavaScript** for advanced interactions

All operations use the user's real Chrome profile — existing logins, cookies, and sessions are preserved.

## Requirements

| Requirement | Version |
|-------------|---------|
| Python | 3.10+ |
| Google Chrome | macOS |
| pip packages | `mcp`, `websockets` (installed by setup) |

## Quick Start (Clean Machine)

```bash
# 1. Clone and install
cd chrome-mcp-bridge
bash setup.sh

# 2. Launch Chrome with debugging
./launch_chrome.sh

# 3. Run the demo
python3 scripts/demo.py
```

Screenshots are saved to `demo_output/`.

## Usage with Claude Code

### Option A: One-shot command

```bash
claude --print --mcp-config mcp-config.json \
  "Navigate to google.com and take a screenshot"
```

### Option B: Add to any project

Copy the generated `mcp-config.json` into your project as `.mcp.json`, or add the server block manually:

```json
{
  "mcpServers": {
    "chrome": {
      "command": "python3",
      "args": ["/absolute/path/to/src/chrome_mcp_server.py"],
      "env": { "CHROME_CDP_PORT": "9222" }
    }
  }
}
```

`setup.sh` generates `mcp-config.json` with the correct absolute path automatically.

## Available Tools

| Tool | Description |
|------|-------------|
| `navigate(url)` | Navigate to a URL |
| `screenshot()` | Capture JPEG screenshot |
| `click(coordinate)` | Click at `[x, y]` |
| `type_text(text)` | Type keyboard text |
| `key(keys)` | Press key combo (e.g. `cmd+a`, `Enter`) |
| `scroll(coordinate, direction, amount)` | Scroll at position |
| `hover(coordinate)` | Hover mouse |
| `drag(start, end)` | Drag from `[x1,y1]` to `[x2,y2]` |
| `find(query)` | Find elements by natural language description |
| `form_input(ref, value)` | Fill form field (CSS selector or `x,y`) |
| `read_page(filter)` | Read accessibility tree (`all` / `interactive`) |
| `get_page_text()` | Extract visible page text |
| `javascript(code)` | Execute JS in active tab |
| `read_console()` | Read browser console logs |
| `tabs_context()` | List open tabs |
| `tabs_create(url)` | Open new tab |
| `tabs_close(tab_id)` | Close tab |
| `tabs_switch(tab_id)` | Switch to tab |
| `file_upload(paths)` | Upload files to file input |
| `wait(duration)` | Wait N seconds |

## Architecture

```
claude --print / Claude Code
        | stdio (MCP JSON-RPC)
        v
  chrome_mcp_server.py
        |
        +-- Primary: chrome-native-host socket (Claude extension)
        +-- Fallback: Chrome DevTools Protocol (CDP) via websocket
                |
                v
          Google Chrome (--remote-debugging-port=9222)
```

The server auto-detects which backend is available. CDP mode works without the Claude extension.

## Demo Script

`scripts/demo.py` runs an end-to-end demonstration:

1. Navigates to a form page (httpbin.org)
2. Screenshots the empty form
3. Finds and fills all form fields automatically
4. Screenshots the filled form
5. Submits the form
6. Screenshots and reads the result

```bash
# Chrome must be running with debugging first
./launch_chrome.sh
python3 scripts/demo.py
```

Output screenshots are saved to `demo_output/` for review.

## Troubleshooting

**"Could not connect to Chrome"**
- Ensure Chrome is running with `--remote-debugging-port=9222`
- Verify: `curl http://localhost:9222/json/version`

**Chrome won't start (port in use)**
- Another Chrome instance may hold the port. Close it or use a different port:
  ```bash
  ./launch_chrome.sh 9333
  ```

**Profile/cookies not loading**
- If Chrome is already running normally, it locks the profile. Close Chrome first, then launch via the script.

**setup.sh fails on `pip install`**
- Ensure `pip3` is available: `python3 -m ensurepip --upgrade`
- Or use a virtual environment: `python3 -m venv .venv && source .venv/bin/activate && bash setup.sh`