内容
<p align="center">
<img src="assets/logo.png" width="180" alt="LiveMCP logo" />
</p>
<h1 align="center">LiveMCP</h1>
<p align="center">
为 AI 提供直接访问您真实浏览器的能力 — 打开标签页、Cookie、会话状态等。
</p>
<p align="center">
<a href="https://www.npmjs.com/package/livemcp"><img src="https://img.shields.io/npm/v/livemcp?label=npm" alt="npm 版本" /></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT 许可证" /></a>
<a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-compatible-green" alt="MCP 兼容" /></a>
</p>
<p align="center">
<a href="#快速入门">快速入门</a> ·
<a href="#MCP 工具参考">工具</a> ·
<a href="#标签页定位">标签页定位</a> ·
<a href="#架构">架构</a> ·
<a href="#远程 / 虚拟机设置">远程 / 虚拟机</a> ·
<a href="#配置">配置</a> ·
<a href="#贡献">贡献</a>
</p>
---
LiveMCP 是一个 [MCP](https://modelcontextprotocol.io) 服务器 + 浏览器扩展程序,它将您**现有的浏览器配置文件**暴露给任何 MCP 客户端(Claude Code、Cursor、Zed 等)。
与基于 Playwright 的自动化工具不同,LiveMCP:
- 在您**已经使用的浏览器**上运行 — 您的登录会话、Cookie 和打开的标签页都是可访问的。
- **不**启动单独的浏览器进程。
- 支持**多个同时运行的 AI 会话**,通过一个中心守护进程共享一个浏览器连接。
---
## 快速入门
### 1. 安装 Chrome 扩展程序
**从发布版本(推荐)**
1. 从 [最新发布版本](https://github.com/DeepakSilaych/chrome-mcp/releases/latest) 下载 `extension.zip`。
2. 解压它。
3. 进入 `chrome://extensions`,启用 **开发者模式**,点击 **加载解压**,然后选择解压后的文件夹。
**从源代码**
```bash
git clone https://github.com/DeepakSilaych/chrome-mcp.git
cd chrome-mcp
npm install && npm run build
# 然后加载解压 → 选择 extension/ 文件夹
```
### 2. 启动中心守护进程
中心守护进程是一个小型、常驻的守护进程。它持有与扩展程序的单个 WebSocket 连接,并跨所有 AI 会话复用请求。启动它一次并保持运行。
```bash
npx livemcp-hub
```
您应该看到:
```
[livemcp-hub] WebSocket : ws://127.0.0.1:17691
[livemcp-hub] Ready — waiting for extension and sessions
```
### 3. 添加到您的 MCP 客户端
**Claude Code** (`~/.claude.json`):
```json
{
"mcpServers": {
"livemcp": {
"command": "npx",
"args": ["-y", "livemcp"]
}
}
}
```
**Cursor** (`.cursor/mcp.json` 或全局设置):
```json
{
"mcpServers": {
"livemcp": {
"command": "npx",
"args": ["-y", "livemcp"]
}
}
}
```
### 4. 连接 Chrome
点击 LiveMCP 扩展程序图标 → **连接**。中心守护进程终端打印 `Chrome extension connected`。
您可以打开任意多个 AI 聊天窗口 — 每个聊天窗口都通过同一个中心守护进程获得自己的会话,且不会发生端口冲突。
---
## MCP 工具参考
所有在标签页上运行的工具都接受三个可选的标签页定位参数。有关详细信息,请参见 [标签页定位](#标签页定位)。
### 快照
| 工具 | 描述 |
|------|-------------|
| `get_page_snapshot` | **复合工具** — 返回视觉截图 + 可交互元素(输入框、按钮、链接及其 CSS 选择器)+ 页面标题 + URL/标题,全部在一个调用中。将其用作观察页面的默认方式。 |
### 标签页
| 工具 | 参数 | 描述 |
|------|--------|-------------|
| `list_tabs` | — | 列出所有打开的标签页,包含 id、标题、URL 和活动状态。 |
| `get_active_tab` | — | 获取当前聚焦的标签页。 |
| `switch_tab` | `tabId` | 通过数字 id 聚焦标签页。 |
| `close_tab` | `tabId` | 关闭标签页。 |
| `create_tab` | `url?` | 打开新标签页,可选导航到 URL。 |
### 内容
| 工具 | 参数 | 描述 |
|------|--------|-------------|
| `get_page_content` | `format?` | 读取页面内容,格式为 `"text"`(默认)、`"html"` 或 `"markdown"`。 |
| `get_selected_text` | — | 返回标签页中当前文本选择的内容。 |
### 截图
| 工具 | 参数 | 描述 |
|------|--------|-------------|
| `take_screenshot` | — | 捕获可见视口为 PNG base64 数据 URL。 |
### 导航
| 工具 | 参数 | 描述 |
|------|--------|-------------|
| `navigate_to` | `url` | 导航标签页到 URL(直接执行)。 |
| `navigate_and_wait` | `url`, `waitFor?`, `timeout?` | 导航并阻塞,直到 `status=complete`。可选等待 CSS 选择器在加载后出现。 |
| `go_back` | — | 历史记录后退。 |
| `go_forward` | — | 历史记录前进。 |
| `reload_tab` | — | 重新加载标签页。 |
### 交互
| 工具 | 参数 | 描述 |
|------|--------|-------------|
| `click_element` | `selector` | 点击匹配 CSS 选择器的第一个元素。 |
| `click_and_wait` | `selector`, `waitForNavigation?`, `waitFor?`, `timeout?` | 点击并等待 — 既可以等待完整页面导航(`waitForNavigation: true`),也可以等待 CSS 选择器出现(`waitFor: ".result"`)。 |
| `type_text` | `selector`, `text`, `clear?` | 在输入框中输入文本。设置 `clear: true` 以先清除内容。 |
| `fill_form` | `fields`, `submit?` | 在一次调用中填充多个字段。每个字段为 `{ selector, value }`。支持 `<input>`、`<textarea>`、`<select>`、复选框(`"true"`/`"false"`)、单选按钮和 `contentEditable`。传递 `submit: true` 以提交表单。 |
| `scroll_page` | `direction`, `amount?` | 按 `"up"`、`"down"`、`"left"` 或 `"right"` 滚动 `amount` 个像素(默认为 400)。 |
### 网络捕获
| 工具 | 参数 | 描述 |
|------|--------|-------------|
| `start_network_capture` | — | 通过 Chrome DevTools Protocol 开始记录 HTTP 请求。 |
| `stop_network_capture` | — | 停止记录。 |
| `get_captured_requests` | — | 返回自上一次 `start_network_capture` 以来捕获的所有请求。 |
> **注意:** 网络和控制台捕获使用 `chrome.debugger`。每个标签页只能有一个调试器会话 — 如果发生冲突错误,请关闭 DevTools 或停止其他捕获。
### 控制台捕获
| 工具 | 参数 | 描述 |
|------|--------|-------------|
| `start_console_capture` | — | 开始记录 `console.*` 输出。 |
| `stop_console_capture` | — | 停止记录。 |
| `get_console_logs` | — | 返回所有捕获的日志条目。 |
### 存储
| 工具 | 参数 | 描述 |
|------|--------|-------------|
| `get_cookies` | `url` | 返回 URL 的所有 Cookie。 |
| `get_local_storage` | — | 转储标签页源的 `localStorage` 键值对。 |
---
## 标签页定位
每个在标签页上运行的工具都接受三个可选参数来标识要使用的标签页:
| 参数 | 类型 | 描述 |
|-------|------|-------------|
| `tabId` | `number` | 精确的 Chrome 标签页 ID。脆弱 — ID 在新标签页打开时可能会更改。 |
| `tabUrl` | `string` | 标签页 URL 的子字符串匹配(不区分大小写)。 |
| `tabTitle` | `string` | 标签页标题的子字符串匹配(不区分大小写)。 |
**解析顺序:** `tabId` → `tabUrl` → `tabTitle` → 当前活动标签页。
### 示例
```
# 始终定位到 GitHub 标签页,无论哪个标签页处于焦点
get_page_snapshot tabUrl="github.com"
# 通过标题定位到 Linear 标签页
navigate_and_wait url="..." tabTitle="Linear"
# 在特定标签页上填充登录表单
fill_form fields=[...] submit=true tabUrl="app.example.com/login"
# 如果未指定,则使用活动标签页
take_screenshot
```
使用 `tabUrl` 或 `tabTitle` 意味着您的指令保持正确,即使用户打开新标签页、切换窗口或 Chrome 重新分配数字 ID。
---
## 架构
```
┌─────────────────────────────────────────────────┐
│ 您的 Chrome 浏览器 │
│ ┌─────────────────────────────────────────┐ │
│ │ LiveMCP 扩展程序(Manifest V3) │ │
│ │ • 接收来自中心守护进程的请求 │ │
│ │ • 执行 chrome.* API 调用 │ │
│ │ • 将结果返回给中心守护进程 │ │
│ └──────────────┬──────────────────────────┘ │
└─────────────────│───────────────────────────────┘
│ WebSocket ws://127.0.0.1:17691
│
┌─────────────────▼───────────────────────────────┐
│ livemcp-hub (启动一次,保持运行) │
│ • 持有与扩展程序的单个 WebSocket 连接 │
│ • 通过 Unix 域套接字将请求路由到会话 │
│ • 通过会话 ID 将响应路由回去 │
└──────────┬──────────────────┬───────────────────┘
│ Unix 套接字 │ Unix 套接字
│ │
┌──────────▼────┐ ┌─────────▼──────┐
│ MCP 会话 1 │ │ MCP 会话 2 │ ← 由 Claude Code 启动
│ (stdio/npx) │ │ (stdio/npx) │ 每个聊天窗口一个
└───────────────┘ └────────────────┘
```
**三层:**
1. **Chrome 扩展程序** — 在 Chrome 中运行,调用 `chrome.*` API,通过 WebSocket 与中心守护进程连接。
2. **中心守护进程** (`npx livemcp-hub`) — 唯一绑定端口 17691 的进程。持有浏览器连接,并通过 Unix 域套接字将其分发给会话。
3. **MCP 会话** (`npx livemcp`) — 每个 AI 聊天一个。由 MCP 客户端(Claude Code、Cursor 等)启动和终止。通过 Unix 套接字连接到中心守护进程;聊天结束时自动清理。
**为什么采用这种架构:**
- 无端口冲突 — 只有中心守护进程绑定 17691。
- 无限同时运行的会话 — 每个会话只是一个 Unix 套接字客户端。
- 无僵尸进程 — 会话通过套接字断开检测自动退出。
- 浏览器状态共享 — 所有会话看到相同的标签页、Cookie 和页面状态。
---
## 远程 / 虚拟机设置
在远程 VM 上运行 Claude Code 但 Chrome 在您的笔记本电脑上?使用一个 SSH 隧道:
```bash
# 在您的笔记本电脑上 — 保持此终端打开
ssh -L 17691:localhost:17691 your-vm-hostname
```
```bash
# 在 VM 上 — 启动中心守护进程
npx livemcp-hub
```
笔记本电脑上的 Chrome 扩展程序通过隧道连接到 VM 上的中心守护进程。所有 VM Claude 会话自动共享连接。
---
## 配置
| 环境变量 | 默认值 | 描述 |
|----------------------|---------|-------------|
| `LIVEMCP_PORT` | `17691` | 中心守护进程的 WebSocket 端口。 |
| `LIVEMCP_HUB_SOCK` | `/tmp/livemcp-hub.sock` | 中心守护进程 ↔ 会话 IPC 的 Unix 套接字路径。 |
### 端口自动回退
如果端口 17691 已被占用,中心守护进程会自动尝试 17692、17693 等,并打印:
```
⚠️ 端口 17691 被占用 — 中心守护进程绑定到端口 17692。
打开扩展程序弹窗 → 更改端口为 17692 → 重新连接。
```
---
## 故障排除
| 症状 | 修复方法 |
|---------|-----|
| `livemcp-hub 未运行` | 首先运行 `npx livemcp-hub`,然后重启 MCP 客户端。 |
| "Chrome 扩展程序未连接" | 在扩展程序弹窗中点击 **连接**。检查端口是否与中心守护进程打印的端口匹配。 |
| 工具调用无限期挂起 | 中心守护进程正在运行,但扩展程序断开了连接。 在弹窗中重新点击 **连接**。 |
| 脚本注入在标签页上失败 | `chrome://` 页面、Chrome Web Store 和 PDF 查看器标签页阻止脚本。 使用普通 `https://` 页面。 |
| 网络 / 控制台捕获冲突 | `chrome.debugger` 每个标签页只能有一个会话。 关闭 DevTools 或在启动新会话前调用 `stop_network_capture` / `stop_console_capture`。 |
| 启动时中心守护进程端口被占用 | 中心守护进程自动递增 — 检查打印的端口并更新扩展程序弹窗以匹配。 |
| `waitForNavigation` 超时 | 点击未引起导航。 改用 `waitFor: ".selector"` 等待 DOM 更改。 |
---
## 安全
- LLM 可以读取和与扩展程序可以访问的任何标签页交互。 在使用此功能时,请避免在 Chrome 配置文件中有高敏感性会话(银行管理面板)除非您理解并接受风险。
- 中心守护进程和会话仅绑定到 `127.0.0.1` — 除非您明确隧道化,否则不暴露给网络。
- `/tmp/livemcp-hub.sock` 处的 Unix 套接字对所有以您的用户身份运行的进程都是可访问的。
---
## 贡献
参见 [CONTRIBUTING.md](CONTRIBUTING.md),了解设置说明、添加新工具的分步指南和发布流程。
欢迎提出问题和拉取请求。请在进行大型更改前先打开问题,以便我们讨论方法。
---
## 许可证
[MIT](LICENSE) © Deepak Silaych