# https://github.com/browser-gateway/browser-gateway 项目说明书

生成时间：2026-06-01 03:29:30 UTC

## 目录

- [快速入门](#getting-started)
- [配置参考](#quick-configuration)
- [系统架构](#architecture-overview)
- [WebSocket 代理机制](#websocket-proxy)
- [会话池与状态持久化](#session-pool)
- [REST API 详解](#rest-api)
- [MCP 服务器](#mcp-server)
- [Webhook 通知系统](#webhook-system)
- [Docker 部署](#docker-deployment)
- [Provider 管理](#provider-management)

<a id='getting-started'></a>

## 快速入门

### 相关页面

相关主题：[配置参考](#quick-configuration), [系统架构](#architecture-overview)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)
- [package.json](https://github.com/browser-gateway/browser-gateway/blob/main/package.json)
- [src/server/rest/scrape.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/scrape.ts)
- [src/server/rest/content.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/content.ts)
- [gateway.example.yml](https://github.com/browser-gateway/browser-gateway/blob/main/gateway.example.yml)
- [web/src/app/(dashboard)/page.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/app/(dashboard)/page.tsx)
</details>

# 快速入门

browser-gateway 是一个可靠、可扩展的浏览器基础设施，为 AI 代理和应用提供统一的浏览器访问能力。本指南将帮助你在 5 分钟内完成安装、配置和基本使用。

## 安装

### 环境要求

| 要求 | 最低版本 |
|------|----------|
| Node.js | 18.x |
| npm/pnpm/yarn | 最新稳定版 |
| Chrome/Chromium | 最新稳定版 |

### 全局安装

```bash
npm install -g browser-gateway
```

安装完成后，验证版本：

```bash
browser-gateway version
# 输出: browser-gateway v0.2.0
```

资料来源：[package.json:3]()

### Docker 部署

```bash
docker run -d \
  --name browser-gateway \
  -p 9500:9500 \
  -v $(pwd)/gateway.yml:/app/gateway.yml \
  browsergateway/browser-gateway:latest
```

## 启动服务

### 默认启动

最简单的启动方式，不配置任何参数：

```bash
browser-gateway serve
```

服务将在 `http://localhost:9500` 启动，默认配置如下：

| 参数 | 默认值 |
|------|--------|
| 端口 | 9500 |
| CDP 端点 | 自动检测 Chrome |
| 并发限制 | 无限制 |

### 自定义配置启动

```bash
browser-gateway serve --config gateway.yml
```

资料来源：[README.md:50-60]()

## 核心使用模式

browser-gateway 支持三种主要使用模式，适用于不同场景：

```mermaid
graph LR
    A[使用场景] --> B[REST API]
    A --> C[WebSocket]
    A --> D[MCP Server]
    
    B --> B1[截图<br/>内容提取<br/>数据抓取]
    C --> C1[browser-use<br/>Playwright<br/>Stagehand]
    D --> D1[Claude Code<br/>Cursor<br/>AI 代理]
```

### 模式一：REST API

最简单的方式，通过 HTTP POST 请求即可完成浏览器操作，无需 WebSocket 连接管理。

#### 截图接口

```bash
curl -X POST http://localhost:9500/v1/screenshot \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}' \
  --output screenshot.png
```

#### 内容提取

支持多种格式：markdown、text、html、readability

```bash
curl -X POST http://localhost:9500/v1/content \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "formats": ["markdown"]
  }'
```

返回结构：

```json
{
  "success": true,
  "data": {
    "url": "https://example.com",
    "statusCode": 200,
    "content": {
      "markdown": "# 页面标题\n\n页面正文内容..."
    },
    "metadata": {
      "title": "页面标题",
      "description": "页面描述",
      "author": "作者",
      "wordCount": 1234
    }
  }
}
```

资料来源：[src/server/rest/content.ts:60-80]()

#### 数据抓取

使用 CSS 选择器精确提取数据：

```bash
curl -X POST http://localhost:9500/v1/scrape \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://news.ycombinator.com",
    "selectors": [
      {"name": "titles", "selector": ".titleline > a"},
      {"name": "scores", "selector": ".score"}
    ]
  }'
```

资料来源：[src/server/rest/scrape.ts:30-50]()

---

### 模式二：WebSocket 代理

适用于需要完全控制浏览器会话的应用，如 Playwright、browser-use、Stagehand。

#### 基本连接

```javascript
import { chromium } from 'playwright';

const browser = await chromium.connect(
  'ws://localhost:9500'
);

const page = await browser.newPage();
await page.goto('https://example.com');
```

#### CDP 自动发现

browser-gateway 提供 `/json/version` 端点，支持主流库的自动发现：

```javascript
// browser-use
const gateway = new BrowserGateway("http://localhost:9500");

// Playwright
const browser = await chromium.connect({
  wsEndpoint: "ws://localhost:9500"
});

// Stagehand
const client = new Stagehand({
  cdpUrl: "http://localhost:9500"
});
```

资料来源：[README.md:25-35]()

---

### 模式三：MCP Server

专为 AI 代理设计，无需手动管理浏览器连接。

#### 启动 MCP 服务

```bash
browser-gateway mcp
```

#### 在 Claude Code 或 Cursor 中配置

编辑配置文件（如 `~/.claude/settings.json` 或 Cursor 的 MCP 配置）：

```json
{
  "mcpServers": {
    "browser-gateway": {
      "command": "npx",
      "args": ["browser-gateway", "mcp"]
    }
  }
}
```

#### 可用工具

| 工具 | 功能 |
|------|------|
| `navigate` | 导航到指定 URL |
| `snapshot` | 获取页面 Markdown 内容 |
| `screenshot` | 截取页面截图 |
| `viewport` | 设置视口大小 |
| `interact` | 执行用户交互（点击、输入等） |
| `evaluate` | 执行 JavaScript 代码 |
| `close` | 关闭当前页面 |
| `status` | 查看连接状态 |

AI 代理可以直接调用这些工具进行网页浏览和数据提取，无需额外配置。

资料来源：[README.md:70-85]()

---

## 配置管理

### 配置文件格式

browser-gateway 使用 YAML 格式配置：

```yaml
# gateway.yml
version: "1"

server:
  port: 9500
  host: "0.0.0.0"

providers:
  - id: local-chrome
    type: chrome
    priority: 1
    maxConcurrent: 5
```

### 提供商配置

#### 本地 Chrome

```yaml
providers:
  - id: local-chrome
    type: chrome
    priority: 1
    # 自动检测 Chrome 安装路径
```

#### Playwright 服务器

```yaml
providers:
  - id: playwright-remote
    type: playwright
    priority: 1
    endpoint: "ws://your-server:3000"
```

#### 云端浏览器服务

```yaml
providers:
  - id: cloud-browser
    type: generic
    priority: 2
    endpoint: "wss://provider.com?token=your-api-key"
```

### 提供商故障转移

配置多个提供商时，gateway 自动进行故障转移：

```yaml
providers:
  - id: primary
    type: chrome
    priority: 1
  - id: fallback
    type: playwright
    endpoint: "ws://fallback-server:3000"
    priority: 2
```

当优先级 1 的提供商不可用时，自动切换到优先级 2。

---

## Web 控制台

browser-gateway 内置 Web 控制台，提供可视化界面管理所有功能：

| 页面 | 功能 |
|------|------|
| **Overview** | 网关健康状态、活动会话数、提供商状态 |
| **Providers** | 添加、编辑、删除、测试浏览器提供商 |
| **Sessions** | 实时查看所有活动连接状态 |
| **Config** | 在线编辑 gateway.yml，支持语法高亮和验证 |

访问地址：`http://localhost:9500/web`

资料来源：[web/src/app/(dashboard)/page.tsx:50-100]()

---

## 常用命令

| 命令 | 功能 |
|------|------|
| `browser-gateway serve` | 启动 REST API 服务器 |
| `browser-gateway serve --config gateway.yml` | 使用配置文件启动 |
| `browser-gateway mcp` | 启动 MCP 服务器 |
| `browser-gateway check` | 测试提供商连接状态 |
| `browser-gateway version` | 显示版本信息 |

---

## 会话保持

v0.1.8+ 支持断开后重新连接到同一浏览器会话，Cookies、localStorage、页面状态完整保留。

```bash
# 初始连接
ws://localhost:9500?sessionId=my-session

# 重新连接（5分钟内）
ws://localhost:9500?sessionId=my-session
```

默认 TTL 为 5 分钟，可通过配置修改。

资料来源：[community_context:v0.1.8]()

---

## 完整示例

### 示例一：Node.js 脚本抓取数据

```javascript
import BrowserGateway from 'browser-gateway';

const gateway = new BrowserGateway('http://localhost:9500');

async function scrapeHackerNews() {
  const result = await gateway.scrape({
    url: 'https://news.ycombinator.com',
    selectors: [
      { name: 'title', selector: '.titleline > a' },
      { name: 'points', selector: '.score' }
    ]
  });
  
  console.log(result.data);
}

scrapeHackerNews();
```

### 示例二：Python + Playwright

```python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.connect("ws://localhost:9500")
    page = browser.new_page()
    page.goto("https://example.com")
    
    title = page.title()
    screenshot = page.screenshot()
    
    browser.close()
```

---

## 下一步

- 查看 [API 文档](./docs/rest-api.md) 了解完整的接口参数
- 阅读 [MCP 文档](./docs/mcp.md) 深入了解 AI 代理集成
- 参考 [Dashboard 指南](./docs/dashboard.md) 学习可视化配置
- 查看 [配置参考](./docs/configuration.md) 获取完整配置选项

---

<a id='quick-configuration'></a>

## 配置参考

### 相关页面

相关主题：[快速入门](#getting-started), [Provider 管理](#provider-management)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/server/config/loader.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/config/loader.ts)
- [src/core/types.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/types.ts)
- [gateway.example.yml](https://github.com/browser-gateway/browser-gateway/blob/main/gateway.example.yml)
- [package.json](https://github.com/browser-gateway/browser-gateway/blob/main/package.json)
- [README.md](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)
</details>

# 配置参考

browser-gateway 采用 YAML 配置文件管理所有运行时参数，支持命令行覆盖和环境变量扩展。配置文件路径可通过 `--config` 参数指定，默认为当前目录下的 `gateway.yml`。

## 配置文件结构

完整配置分为六大模块：服务端口、HTTP 服务器、浏览器提供程序（Providers）、会话池、认证和安全选项。

```yaml
# 基础配置示例
server:
  host: "0.0.0.0"
  port: 9500

http:
  enabled: true
  cors:
    origin: "*"
    credentials: true

providers: []

pool:
  maxConcurrent: 10
  sessionTtl: 300

auth:
  enabled: false
  token: ""

security:
  allowedIps: []
  rateLimit:
    enabled: true
    maxRequests: 1000
    windowMs: 60000

logging:
  level: "info"
  format: "json"
```

## 服务配置

### 服务器基础设置

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `server.host` | string | `"0.0.0.0"` | 监听地址 |
| `server.port` | number | `9500` | 监听端口 |

### HTTP 服务器

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `http.enabled` | boolean | `true` | 是否启用 REST API |
| `http.cors.origin` | string | `"*"` | CORS 允许的源 |
| `http.cors.credentials` | boolean | `true` | 是否允许凭证 |
| `http.prefix` | string | `"/v1"` | API 路由前缀 |

```yaml
server:
  host: "0.0.0.0"
  port: 9500

http:
  enabled: true
  cors:
    origin: "*"
    credentials: true
  prefix: "/v1"
```

## 提供商配置（Providers）

Providers 是浏览器实例的连接定义，支持本地 Chrome 浏览器、云服务或自托管的 Playwright Server。

### 提供商参数

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `id` | string | 是 | 提供商唯一标识符，使用小写字母和连字符 |
| `type` | string | 是 | 类型：`launch`、`connect` 或 `ws` |
| `url` | string | 是 | WebSocket 连接地址 |
| `priority` | number | 否 | 优先级（数值越小优先级越高），默认 `0` |
| `maxConcurrent` | number | 否 | 最大并发连接数 |
| `labels` | string[] | 否 | 标签列表，用于路由匹配 |

### 提供商类型详解

#### launch 类型

启动本地 Chrome 浏览器，自动检测安装路径。

```yaml
providers:
  - id: "local-chrome"
    type: "launch"
    url: "http://localhost:9222"
    priority: 0
    maxConcurrent: 5
    labels: ["local", "fast"]
```

#### connect 类型

连接到已运行的浏览器实例（如 Docker 容器中的 Chrome）。

```yaml
providers:
  - id: "docker-chrome"
    type: "connect"
    url: "ws://chrome-container:9222"
    priority: 1
    maxConcurrent: 10
```

#### ws 类型

连接第三方云浏览器服务。

```yaml
providers:
  - id: "cloud-browser"
    type: "ws"
    url: "wss://provider.com?token=your-api-key"
    priority: 2
    maxConcurrent: 20
    labels: ["cloud"]
```

### 多提供商配置示例

```yaml
providers:
  - id: "local-chrome"
    type: "launch"
    url: "http://localhost:9222"
    priority: 0
    maxConcurrent: 5

  - id: "playwright-server"
    type: "connect"
    url: "ws://localhost:3000"
    priority: 1
    maxConcurrent: 10

  - id: "cloud-provider"
    type: "ws"
    url: "wss://api.provider.com?token=${CLOUD_TOKEN}"
    priority: 2
    maxConcurrent: 50
```

## 会话池配置

会话池（Session Pool）复用浏览器连接以提升性能，支持配置最大并发数和会话生命周期。

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `pool.maxConcurrent` | number | `10` | 全局最大并发会话数 |
| `pool.sessionTtl` | number | `300` | 会话存活时间（秒），默认 5 分钟 |
| `pool.idleTimeout` | number | `60` | 空闲连接超时时间 |

```yaml
pool:
  maxConcurrent: 10
  sessionTtl: 300
  idleTimeout: 60
```

### 会话复用流程

```mermaid
graph TD
    A[新请求] --> B{会话池有空闲连接?}
    B -->|是| C[复用已有连接]
    B -->|否| D{达到最大并发?}
    D -->|否| E[创建新浏览器页面]
    D -->|是| F[等待空闲连接]
    C --> G[执行操作]
    E --> G
    F --> G
    G --> H{请求完成}
    H --> I[连接返回池中]
    I --> J[TTL 计时]
    J --> K{超时?}
    K -->|是| L[释放连接]
    K -->|否| B
```

### 会话重连

断开连接后可使用 `?sessionId=` 查询参数重新连接到同一浏览器会话，保留 Cookies、localStorage 和页面状态。

```bash
# 重连会话
wscat "ws://localhost:9500/v1/connect?sessionId=abc123"
```

## 认证与安全

### 认证配置

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `auth.enabled` | boolean | `false` | 是否启用认证 |
| `auth.token` | string | - | 访问令牌 |

启用认证后，仪表板需要通过安全 HttpOnly Cookie 进行身份验证。

```yaml
auth:
  enabled: true
  token: "your-secure-token"
```

### 安全限制

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `security.allowedIps` | string[] | `[]` | 允许的 IP 地址列表 |
| `security.rateLimit.enabled` | boolean | `true` | 是否启用速率限制 |
| `security.rateLimit.maxRequests` | number | `1000` | 时间窗口内最大请求数 |
| `security.rateLimit.windowMs` | number | `60000` | 时间窗口（毫秒） |

```yaml
security:
  allowedIps:
    - "127.0.0.1"
    - "10.0.0.0/8"
  rateLimit:
    enabled: true
    maxRequests: 1000
    windowMs: 60000
```

## 日志配置

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `logging.level` | string | `"info"` | 日志级别：`debug`、`info`、`warn`、`error` |
| `logging.format` | string | `"json"` | 日志格式：`json`、`text` |
| `logging.file` | string | - | 日志文件路径（可选） |

```yaml
logging:
  level: "info"
  format: "json"
  file: "/var/log/browser-gateway.log"
```

## 环境变量

配置文件中支持使用 `${ENV_VAR}` 语法引用环境变量。

```yaml
providers:
  - id: "cloud"
    type: "ws"
    url: "wss://api.provider.com?token=${BROWSER_TOKEN}"

auth:
  token: "${BG_TOKEN}"
```

### 常用环境变量

| 变量名 | 说明 |
|--------|------|
| `BG_TOKEN` | 访问令牌 |
| `BROWSER_TOKEN` | 云服务 API Token |
| `CHROME_PATH` | Chrome 可执行文件路径 |

## 配置加载机制

配置文件通过 `src/server/config/loader.ts` 模块加载，支持热重载。启动时使用 `--config` 参数指定配置文件路径。

```bash
# 指定配置文件
browser-gateway serve --config /path/to/gateway.yml

# 开发环境
browser-gateway serve --config gateway.dev.yml
```

### 配置验证

启动时会自动验证配置格式，错误时输出详细的验证信息并终止启动。也可通过 API 验证配置而不保存：

```bash
curl -X POST http://localhost:9500/v1/config/validate \
  -H "Content-Type: application/yaml" \
  -d "$(cat gateway.yml)"
```

## 命令行参数

| 参数 | 说明 |
|------|------|
| `--config <path>` | 指定配置文件路径 |
| `serve` | 以服务器模式启动 |
| `check` | 测试提供商连接 |
| `version` | 显示版本信息 |
| `help` | 显示帮助信息 |

```bash
# 完整启动命令
browser-gateway serve --config gateway.yml

# 测试配置
browser-gateway check

# 查看版本
browser-gateway version
```

## 完整配置示例

```yaml
server:
  host: "0.0.0.0"
  port: 9500

http:
  enabled: true
  cors:
    origin: "https://your-app.com"
    credentials: true
  prefix: "/v1"

providers:
  - id: "local-chrome"
    type: "launch"
    url: "http://localhost:9222"
    priority: 0
    maxConcurrent: 5
    labels: ["local"]

  - id: "playwright-server"
    type: "connect"
    url: "ws://localhost:3000"
    priority: 1
    maxConcurrent: 10
    labels: ["server"]

  - id: "cloud-service"
    type: "ws"
    url: "wss://provider.com?token=${BROWSER_TOKEN}"
    priority: 2
    maxConcurrent: 50
    labels: ["cloud"]

pool:
  maxConcurrent: 20
  sessionTtl: 300
  idleTimeout: 60

auth:
  enabled: true
  token: "${BG_TOKEN}"

security:
  allowedIps: []
  rateLimit:
    enabled: true
    maxRequests: 1000
    windowMs: 60000

logging:
  level: "info"
  format: "json"
```

## 常见配置问题

### 提供商连接失败

1. 确认 WebSocket URL 可访问
2. 检查防火墙是否放行对应端口
3. 验证 API Token 是否有效

### 会话池耗尽

当并发请求超过 `pool.maxConcurrent` 时，新请求会排队等待。可以通过以下方式解决：

- 提高 `pool.maxConcurrent` 值
- 为不同业务配置独立的提供商
- 使用标签（labels）进行请求路由

### 认证问题

启用认证后，所有 API 请求需要在请求头中携带 Token：

```bash
curl -H "Authorization: Bearer ${BG_TOKEN}" \
  http://localhost:9500/v1/status

---

<a id='architecture-overview'></a>

## 系统架构

### 相关页面

相关主题：[WebSocket 代理机制](#websocket-proxy), [会话池与状态持久化](#session-pool)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/server/rest/scrape.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/scrape.ts)
- [src/server/rest/content.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/content.ts)
- [src/server/rest/screenshot.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/screenshot.ts)
- [src/core/gateway.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/gateway.ts)
- [src/core/providers/registry.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/providers/registry.ts)
- [src/core/proxy/session.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/proxy/session.ts)
- [src/server/index.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/index.ts)
- [src/mcp/server.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/mcp/server.ts)
- [src/server/websocket.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/websocket.ts)
- [package.json](https://github.com/browser-gateway/browser-gateway/blob/main/package.json)
</details>

# 系统架构

browser-gateway 是一个专为 AI Agent 设计的高可靠、可扩展的浏览器基础设施网关。它通过统一的 WebSocket 接口将各种浏览器提供方（Provider）进行抽象，为上层应用提供可靠的浏览器操作能力，同时支持 REST API、MCP Server 等多种接入方式。

## 整体架构概览

browser-gateway 采用分层架构设计，从上到下分为四层：

```mermaid
graph TD
    subgraph 接入层
        REST[REST API<br/>v0.1.5+]
        MCP[MCP Server<br/>v0.1.5+]
        WS[WebSocket<br/>核心接口]
        CDP[CDP Auto-Discovery<br/>v0.1.8+]
    end
    
    subgraph 路由层
        Router[请求路由器]
        Pool[会话池<br/>Session Pool v0.2.0+]
        LB[负载均衡器]
    end
    
    subgraph 核心层
        Gateway[Gateway 核心]
        Registry[Provider 注册表]
        Session[会话管理]
        Failover[故障转移]
    end
    
    subgraph 供给层
        P1[Provider 1<br/>Playwright]
        P2[Provider 2<br/>Cloud Service]
        P3[Provider 3<br/>Puppeteer]
        Chrome[本地 Chrome<br/>Auto-detect]
    end
    
    REST --> Router
    MCP --> Router
    WS --> Router
    CDP --> Router
    
    Router --> LB
    LB --> Pool
    Pool --> Gateway
    Gateway --> Registry
    
    Registry --> P1
    Registry --> P2
    Registry --> P3
    Registry --> Chrome
```

## 核心组件

### Gateway 核心

Gateway 是系统的核心调度引擎，负责管理所有浏览器会话的生命周期。

**职责范围：**
- 接收并解析来自路由层的请求
- 管理浏览器会话的创建、复用和销毁
- 处理会话持久化（v0.1.8+）
- 协调 Provider 之间的故障转移

核心入口位于 `src/server/index.ts`，通过 Hono 框架构建 HTTP 服务器，挂载 WebSocket 路由和 REST API 端点。

### Provider 注册表

Provider 注册表（`src/core/providers/registry.ts`）管理所有已配置的浏览器供给方。

| 配置项 | 类型 | 说明 |
|--------|------|------|
| `id` | string | Provider 唯一标识符 |
| `type` | string | 类型：`playwright` / `puppeteer` / `cloud` |
| `wsUrl` | string | WebSocket 连接地址 |
| `priority` | number | 优先级（数值越小优先级越高） |
| `maxConcurrent` | number | 最大并发连接数 |
| `healthy` | boolean | 健康状态 |

**Provider 类型支持：**

```mermaid
graph LR
    subgraph 支持的 Provider
        PW[Playwright Server]
        PP[Puppeteer]
        CS[Cloud Browser]
        LC[本地 Chrome]
    end
    
    PW --> ws1[ws://server:3000]
    PP --> ws2[wss://provider.com]
    CS --> ws3[Any WebSocket URL]
    LC --> ws4[自动检测]
```

### 会话管理

会话管理模块（`src/core/proxy/session.ts`）负责维护客户端与浏览器实例之间的会话状态。

**关键特性：**
- 会话持久化：断开连接后重新连接可恢复同一浏览器实例 资料来源：[src/core/proxy/session.ts]()
- Cookie、localStorage、页面状态自动保留
- 可配置的 TTL（默认 5 分钟）
- 通过 `?sessionId=` 查询参数重连 资料来源：[社区 v0.1.8](https://github.com/browser-gateway/browser-gateway/releases/tag/v0.1.8)

```mermaid
sequenceDiagram
    participant Client
    participant Gateway
    participant Browser
    
    Client->>Gateway: 连接请求
    Gateway->>Browser: 创建/分配会话
    Browser-->>Gateway: 会话 ID
    Gateway-->>Client: 连接成功 + sessionId
    
    Client->>Gateway: 断开连接
    Note over Gateway: 保持 Browser 存活 (TTL)
    
    Client->>Gateway: 重连 ?sessionId=xxx
    Gateway->>Browser: 恢复会话
    Browser-->>Gateway: 状态恢复
    Gateway-->>Client: 会话已恢复
```

## 请求处理流程

### REST API 请求流程

v0.2.0 引入的 REST API 提供了简化的 HTTP 接口，无需直接管理 WebSocket 连接。

```mermaid
graph LR
    subgraph HTTP 请求
        POST[POST /v1/screenshot]
        CONTENT[POST /v1/content]
        SCRAPE[POST /v1/scrape]
    end
    
    subgraph 处理流程
        Validate[参数验证]
        Route[路由选择]
        Pool[获取会话]
        Execute[执行操作]
        Return[返回结果]
    end
    
    POST --> Validate
    CONTENT --> Validate
    SCRAPE --> Validate
    Validate --> Route
    Route --> Pool
    Pool --> Execute
    Execute --> Return
```

**REST 端点列表：**

| 端点 | 方法 | 功能 |
|------|------|------|
| `/v1/screenshot` | POST | 截取页面截图 |
| `/v1/content` | POST | 提取页面内容（markdown/text/html/readability） |
| `/v1/scrape` | POST | 使用 CSS 选择器提取数据 |
| `/v1/status` | GET | 网关状态和 Provider 信息 |
| `/v1/sessions` | GET | 活跃会话列表 |
| `/v1/providers` | GET/POST | Provider 管理 |

### 内容提取流程

内容提取是核心功能之一，支持多种格式：

```mermaid
graph TD
    subgraph extractWithDefuddle
        RawHTML[原始 HTML]
        Parse[解析内容]
        Markdown{需要 Markdown?}
        Readability{需要 Readability?}
        
        RawHTML --> Parse
        Parse --> Markdown
        Markdown -->|是| MD[转换为 Markdown]
        Markdown -->|否| Readability
        Readability -->|是| RA[Readability 提取]
        Readability -->|否| Meta[基础元数据]
        
        MD --> OutputMD[输出内容]
        RA --> OutputRA[输出内容]
        Meta --> OutputMeta[元数据]
    end
```

## 会话池机制

v0.2.0 引入的会话池（Session Pool）是架构的重大升级，实现了浏览器连接的复用。

**核心特性：**

| 特性 | 说明 |
|------|------|
| 连接复用 | 多个 HTTP 请求共享同一浏览器实例 |
| 自动路由 | 请求自动分配到可用的会话 |
| 自动重试 | 失败请求自动使用新会话重试 |
| 负载均衡 | 基于优先级的请求分发 |

```mermaid
graph TD
    subgraph 请求入口
        Req1[HTTP 请求 1]
        Req2[HTTP 请求 2]
        Req3[HTTP 请求 3]
    end
    
    subgraph Session Pool
        S1[会话 1]
        S2[会话 2]
        S3[会话 3]
    end
    
    subgraph Browser Instances
        B1[浏览器 1]
        B2[浏览器 2]
        B3[浏览器 3]
    end
    
    Req1 --> PoolReq1[获取可用会话]
    Req2 --> PoolReq2[获取可用会话]
    Req3 --> PoolReq3[获取可用会话]
    
    PoolReq1 --> S1
    PoolReq2 --> S2
    PoolReq3 --> S1
    
    S1 --> B1
    S2 --> B2
    S3 --> B3
```

## MCP Server 架构

v0.1.5 引入的 MCP Server 为 AI Agent 提供原生的浏览器工具支持。

**8 个核心工具：**

| 工具名 | 功能 |
|--------|------|
| `navigate` | 导航到指定 URL |
| `snapshot` | 获取页面快照 |
| `screenshot` | 截取屏幕截图 |
| `viewport` | 设置视口大小 |
| `interact` | 与页面元素交互 |
| `evaluate` | 执行 JavaScript |
| `close` | 关闭标签页 |
| `status` | 获取浏览器状态 |

```mermaid
graph TD
    subgraph MCP Client
        Claude[Claude Code]
        Cursor[Cursor]
        Other[其他 MCP 客户端]
    end
    
    subgraph MCP Server
        Handler[请求处理器]
        Tools[8 个浏览器工具]
        CDP[CDP 协议转换]
    end
    
    subgraph Browser
        Chrome[Chrome/Chromium]
    end
    
    Claude --> Handler
    Cursor --> Handler
    Other --> Handler
    
    Handler --> Tools
    Tools --> CDP
    CDP --> Chrome
```

## CDP 自动发现

v0.1.8 引入的 CDP 自动发现端点简化了第三方库的集成。

**支持的库：**
- browser-use
- Playwright
- Stagehand

使用方式：直接传入 `http://localhost:9500` 而非完整的 WebSocket URL。

## Web Dashboard

内置的 Web Dashboard 提供可视化的管理界面。

| 页面 | 功能 |
|------|------|
| Overview | 网关健康状态、活跃会话数、Provider 状态 |
| Providers | 添加、编辑、删除、测试 Provider |
| Sessions | 实时活跃连接列表 |
| Config | 编辑 gateway.yml 配置 |

## 认证机制

Dashboard 支持可选的 token 认证：

- 环境变量：`BG_TOKEN`
- 认证方式：安全的 HttpOnly Cookie
- 适用场景：生产环境部署

## 配置架构

系统通过 YAML 文件配置，支持多 Provider 故障转移：

```yaml
providers:
  - id: local-playwright
    type: playwright
    wsUrl: ws://localhost:3000
    priority: 1
    maxConcurrent: 5
    
  - id: cloud-provider
    type: cloud
    wsUrl: wss://provider.com?token=xxx
    priority: 2
    maxConcurrent: 10
    
session:
  ttl: 300  # 5 分钟
  
pool:
  maxSessions: 20
  idleTimeout: 60
```

## 依赖关系图

```mermaid
graph TD
    Server[src/server/index.ts]
    Gateway[src/core/gateway.ts]
    Registry[src/core/providers/registry.ts]
    Session[src/core/proxy/session.ts]
    REST[src/server/rest/*.ts]
    WS[src/server/websocket.ts]
    MCP[src/mcp/server.ts]
    
    Server --> Gateway
    Server --> WS
    Server --> REST
    Server --> MCP
    
    Gateway --> Registry
    Gateway --> Session
    
    REST --> Gateway
    WS --> Gateway
    MCP --> Gateway
```

## 技术栈

| 层级 | 技术选型 |
|------|----------|
| 运行时 | Node.js (ESM) |
| Web 框架 | Hono |
| WebSocket | ws / hono/ws |
| HTTP 客户端 | ky |
| 内容提取 | @mozilla/readability, turndown |
| MCP | @modelcontextprotocol/sdk |
| Dashboard | Next.js |
| UI 组件 | base-ui/react |

## 版本演进

| 版本 | 重大特性 |
|------|----------|
| v0.1.5 | MCP Server、零配置启动 |
| v0.1.8 | 会话持久化、CDP 自动发现 |
| v0.2.0 | REST API、Session Pool、Auto-Discovery |

## 扩展阅读

- [快速开始指南](../getting-started.md)
- [REST API 文档](../rest-api.md)
- [MCP 使用文档](../mcp.md)
- [Provider 配置](../providers.md)
- [Dashboard 使用](../dashboard.md)

---

<a id='websocket-proxy'></a>

## WebSocket 代理机制

### 相关页面

相关主题：[系统架构](#architecture-overview)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [package.json](https://github.com/browser-gateway/browser-gateway/blob/main/package.json)
- [README.md](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)
- [src/server/rest/scrape.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/scrape.ts)
- [src/server/rest/content.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/content.ts)
- [web/src/app/(dashboard)/providers/page.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/app/(dashboard)/providers/page.tsx)
- [web/src/app/(dashboard)/sessions/page.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/app/(dashboard)/sessions/page.tsx)
- [web/src/app/(dashboard)/page.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/app/(dashboard)/page.tsx)
- [web/src/components/app-sidebar.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/components/app-sidebar.tsx)
</details>

# WebSocket 代理机制

## 概述

Browser Gateway 的核心功能是作为浏览器实例的 WebSocket 代理网关。它为 AI 代理和应用程序提供可靠的、可扩展的浏览器基础设施，通过统一的 WebSocket 端点将客户端请求路由到远程浏览器服务提供商。

**核心能力：**

- 协议无关：支持 Playwright、Puppeteer、Chrome DevTools Protocol (CDP) 等任何 WebSocket 协议
- 多提供商路由：根据优先级和可用性自动选择最优浏览器提供商
- 会话持久化：断开重连后保持 Cookie、localStorage 和页面状态
- 故障转移：主提供商不可用时自动切换到备用提供商

资料来源：[package.json:1-15](https://github.com/browser-gateway/browser-gateway/blob/main/package.json)

---

## 架构设计

### 系统组件

Browser Gateway 采用分层架构设计：

| 组件层 | 功能描述 | 关键文件 |
|--------|----------|----------|
| **入口层** | WebSocket 升级处理、HTTP REST API | `src/server/ws/upgrade.ts` |
| **路由层** | 提供商选择、负载均衡、连接管理 | `src/core/proxy/` |
| **会话层** | WebSocket 管道、会话追踪、消息转发 | `src/core/session/` |
| **提供商层** | 远程浏览器服务连接、CDP 协议适配 | `src/providers/` |
| **仪表板层** | 提供商管理、会话监控、配置编辑 | `web/src/app/(dashboard)/` |

资料来源：[README.md:1-50](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)

### 请求流程

```mermaid
graph TD
    A["客户端<br/>(Playwright/Puppeteer/CDP)"] --> B["WebSocket 握手<br/>/v1/connect"]
    B --> C["身份验证<br/>?token=xxx"]
    C --> D["提供商选择器<br/>优先级 + 权重"]
    D --> E{"主提供商<br/>可用?"}
    E -->|是| F["建立连接<br/>WebSocket 管道"]
    E -->|否| G["故障转移<br/>切换备用提供商"]
    G --> H{"备用提供商<br/>可用?"}
    H -->|是| F
    H -->|否| I["返回错误<br/>无可用提供商"]
    F --> J["CDP 消息<br/>双向转发"]
    J --> K["客户端"]
    J --> L["远程浏览器"]
```

---

## WebSocket 连接端点

### `/v1/connect` 端点

主 WebSocket 连接端点，用于建立与远程浏览器的持久连接。

**连接 URL 格式：**

```
ws://localhost:9500/v1/connect?token=<TOKEN>&sessionId=<SESSION_ID>
```

| 参数 | 必填 | 说明 |
|------|------|------|
| `token` | 否 | 身份验证令牌，当 `BG_TOKEN` 环境变量设置时必需 |
| `sessionId` | 否 | 会话 ID，用于重新连接已存在的会话（会话持久化功能） |

资料来源：[README.md:50-80](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)

### CDP 自动发现端点

**`/json/version`** 端点提供 Chrome DevTools Protocol 自动发现功能，兼容 browser-use、Playwright 和 Stagehand 库。

```typescript
// 使用方式：直接传递 http://localhost:9500
const browser = await chromium.connectOverCDP('http://localhost:9500');
```

资料来源：[README.md:1-30](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)

---

## 提供商管理

### 提供商配置

提供商是远程浏览器服务的 WebSocket 端点，定义在 `gateway.yml` 配置文件中：

```yaml
version: 1

providers:
  primary:
    url: wss://provider.example.com?token=${PROVIDER_TOKEN}
    limits:
      maxConcurrent: 5
    priority: 1

  fallback:
    url: ws://my-playwright-server:4000
    limits:
      maxConcurrent: 10
    priority: 2
```

### 提供商配置参数

| 参数 | 类型 | 说明 |
|------|------|------|
| `id` | string | 唯一标识符（小写字母、数字、连字符、下划线） |
| `url` | string | WebSocket URL（必须以 `ws://` 或 `wss://` 开头） |
| `maxConcurrent` | number | 最大并发连接数（默认无限制） |
| `priority` | number | 优先级（数值越小优先级越高） |
| `weight` | number | 负载均衡权重（用于加权轮询） |

资料来源：[web/src/app/(dashboard)/providers/page.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/app/(dashboard)/providers/page.tsx)

### 支持的提供商类型

| 类型 | 示例 URL | 说明 |
|------|----------|------|
| Playwright Server | `ws://your-server:3000` | 自托管 `npx playwright run-server` |
| 云浏览器服务 | `wss://provider.com?token=xxx` | 任何提供 WebSocket URL 的云服务 |
| Chrome 远程调试 | `http://192.168.1.100:9222` | 带 `--remote-debugging-port` 启动的 Chrome |

资料来源：[web/src/app/(dashboard)/providers/page.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/app/(dashboard)/providers/page.tsx)

---

## 会话管理

### 会话生命周期

```mermaid
stateDiagram-v2
    [*] --> 连接中: WebSocket 握手
    连接中 --> 已连接: 握手成功
    连接中 --> 错误: 握手失败
    已连接 --> 活跃: 开始消息交换
    活跃 --> 活跃: CDP 消息转发
    活跃 --> 断开: 客户端关闭
    活跃 --> 重连: 网络中断
    重连 --> 已连接: 恢复成功
    重连 --> 错误: 超时
    断开 --> [*]
    错误 --> [*]
```

### 会话持久化

v0.1.8 引入的会话持久化功能允许断开后重新连接到同一浏览器实例：

- **TTL 默认值**：5 分钟（可配置）
- **保留状态**：Cookies、localStorage、页面状态
- **重连方式**：在 URL 中添加 `?sessionId=<SESSION_ID>` 参数

```typescript
// 首次连接
const ws = new WebSocket('ws://localhost:9500/v1/connect');
const sessionId = ws.headers['x-session-id'];

// 断线重连
const wsReconnect = new WebSocket('ws://localhost:9500/v1/connect?sessionId=' + sessionId);
```

资料来源：[README.md:1-30](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)

### 会话监控

仪表板的 Sessions 页面显示所有活跃连接信息：

| 字段 | 说明 |
|------|------|
| Session | 会话唯一标识符 |
| Provider | 当前路由到的提供商 |
| Connected | 连接建立时间 |
| Duration | 已持续时长 |
| Messages | 已交换的消息数量 |

资料来源：[web/src/app/(dashboard)/sessions/page.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/app/(dashboard)/sessions/page.tsx)

---

## 故障转移机制

### 提供商选择算法

```mermaid
graph TD
    A["新连接请求"] --> B{"有可用的<br/>优先级1提供商?"}
    B -->|是| C["选择优先级最高的<br/>可用提供商"]
    B -->|否| D{"有可用的<br/>优先级2提供商?"}
    D -->|是| E["选择优先级最高的<br/>可用提供商"]
    D -->|否| F["等待重试<br/>或返回错误"]
    C --> G["检查 maxConcurrent 限制"]
    E --> G
    G --> H{"达到<br/>并发限制?"}
    H -->|是| F
    H -->|否| I["建立 WebSocket 连接"]
```

### 状态检查

系统定期检查提供商健康状态：

- **主动探测**：定时发送 ping/pong 检测连接活性
- **自动移除**：连续失败达到阈值后自动标记为不可用
- **自动恢复**：提供商恢复后自动重新加入可用池

---

## 身份验证

### 令牌认证

当设置 `BG_TOKEN` 环境变量时，所有访问都需要身份验证：

```bash
BG_TOKEN=my-secret-token browser-gateway serve
```

| 客户端类型 | 认证方式 |
|------------|----------|
| WebSocket 客户端 | `?token=` 查询参数 |
| REST API 客户端 | `Authorization: Bearer <token>` 请求头 |
| 仪表板 | 登录表单，设置 HttpOnly Cookie |
| 健康检查端点 | 始终公开访问 |

资料来源：[README.md:80-100](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)

---

## 连接示例

### Playwright 连接

```typescript
import { chromium } from 'playwright';

// 通过 CDP 协议连接
const browser = await chromium.connectOverCDP('ws://localhost:9500/v1/connect');

// 或通过 Playwright 原生协议连接
const browser = await chromium.connect('ws://localhost:9500/v1/connect');
```

### Puppeteer 连接

```typescript
import puppeteer from 'puppeteer';

const browser = await puppeteer.connect({
  browserWSEndpoint: 'ws://localhost:9500/v1/connect',
});
```

### 直接 CDP 连接

```typescript
const ws = new WebSocket('ws://localhost:9500/v1/connect');

// 发送 CDP 命令
ws.send(JSON.stringify({
  id: 1,
  method: 'Page.navigate',
  params: { url: 'https://example.com' }
}));
```

资料来源：[README.md:50-80](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)

---

## 配置管理

### 命令行参数

| 命令 | 说明 |
|------|------|
| `browser-gateway serve` | 启动网关 + 仪表板 |
| `browser-gateway serve --port 8080` | 自定义端口 |
| `browser-gateway serve --config path.yml` | 自定义配置文件 |
| `browser-gateway check` | 测试提供商连通性 |
| `browser-gateway help` | 显示帮助信息 |

### 环境变量

| 变量 | 说明 |
|------|------|
| `BG_TOKEN` | 访问令牌（启用身份验证） |
| `BG_PORT` | 服务端口（默认 9500） |
| `BG_CONFIG` | 配置文件路径 |

### 配置文件热重载

网关支持动态更新配置：

1. 通过仪表板的 Config Editor 编辑 `gateway.yml`
2. 系统自动备份修改前版本
3. 语法验证通过后实时生效
4. 无需重启服务

资料来源：[web/src/app/(dashboard)/page.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/app/(dashboard)/page.tsx)

---

## 相关文档

- [REST API 文档](./rest-api.md) - HTTP 端点参考
- [MCP 文档](./mcp.md) - AI 代理集成指南
- [仪表板指南](./dashboard.md) - Web 管理界面使用
- [会话生命周期](./session-lifecycle.md) - 详细会话状态管理

---

<a id='session-pool'></a>

## 会话池与状态持久化

### 相关页面

相关主题：[系统架构](#architecture-overview), [REST API 详解](#rest-api)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/core/pool/session-pool.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/pool/session-pool.ts)
- [src/core/pool/index.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/pool/index.ts)
- [src/core/pool/types.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/pool/types.ts)
- [src/server/rest/executor.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/executor.ts)
- [src/server/rest/content.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/content.ts)
- [src/server/rest/scrape.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/scrape.ts)
- [src/server/mcp/tools.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/tools.ts)

</details>

# 会话池与状态持久化

## 概述

会话池（Session Pool）与状态持久化是 browser-gateway 实现可靠、可扩展浏览器基础设施的核心模块。它们共同解决了两个关键问题：如何在多个请求间高效复用浏览器实例，以及如何在断开连接后恢复用户的浏览状态。

从 v0.1.8 引入的会话持久化机制，到 v0.2.0 完善后的会话池架构，这一系统允许用户断开连接后重新连接到同一个浏览器实例，保持 Cookie、localStorage、页面状态等数据不丢失。通过 `?sessionId=` 查询参数即可指定会话进行重连，默认 TTL（生存时间）为 5 分钟。

## 架构设计

### 核心组件关系

```mermaid
graph TD
    A[客户端请求] --> B{请求类型}
    B -->|REST API| C[REST Executor]
    B -->|MCP| D[MCP Tools]
    B -->|WebSocket| E[WebSocket Handler]
    
    C --> F[Session Pool]
    D --> F
    E --> F
    
    F --> G{可用会话?}
    G -->|是| H[复用会话]
    G -->|否| I[创建新会话]
    
    H --> J[状态恢复]
    I --> K[启动浏览器]
    K --> J
    
    J --> L[执行操作]
    L --> M[返回结果]
    M --> N[会话释放回池]
```

### 模块职责

| 模块 | 路径 | 职责 |
|------|------|------|
| session-pool.ts | src/core/pool/ | 会话池的核心实现，管理会话的创建、分配、回收和销毁 |
| index.ts | src/core/pool/ | 会话池的导出和公共接口定义 |
| types.ts | src/core/pool/ | 会话相关的类型定义和接口 |
| executor.ts | src/server/rest/ | REST API 请求的执行器，封装页面操作逻辑 |

## 会话生命周期

### 会话状态流转

```mermaid
stateDiagram-v2
    [*] --> Created: 创建会话
    Created --> Active: 分配给客户端
    Active --> Idle: 操作完成
    Idle --> Active: 新请求到达
    Active --> Disconnected: 客户端断开
    Disconnected --> Active: 客户端重连
    Disconnected --> Expired: TTL 超时
    Expired --> [*]: 清理资源
    Idle --> Expired: TTL 超时
```

### 会话池管理策略

会话池采用以下策略管理会话资源：

1. **会话分配**：当请求到达时，池会检查是否有空闲会话可用
2. **状态保持**：断开的会话在 TTL 过期前保留所有状态数据
3. **自动清理**：会话过期后自动释放浏览器实例和关联资源
4. **重连机制**：客户端可通过 `sessionId` 参数恢复到之前的会话

## 状态持久化机制

### 支持持久化的状态类型

| 状态类型 | 说明 | 持久化方式 |
|----------|------|------------|
| Cookie | 网站认证和偏好设置 | 浏览器原生持久化 |
| localStorage | 前端应用数据 | 浏览器原生持久化 |
| sessionStorage | 会话级存储 | 浏览器原生持久化 |
| 页面状态 | DOM 树、滚动位置、表单数据 | 通过 CDP 协议恢复 |
| 浏览器上下文 | 浏览器实例的完整上下文 | 内存保留至 TTL |

### 状态恢复流程

```mermaid
sequenceDiagram
    participant Client as 客户端
    participant Gateway as Gateway
    participant Pool as Session Pool
    participant Browser as 浏览器实例

    Client->>Gateway: 断开连接 (sessionId=xxx)
    Gateway->>Pool: 将会话标记为断开
    Pool->>Browser: 保持浏览器运行
    
    Note over Pool: TTL 倒计时开始 (默认5分钟)
    
    Client->>Gateway: 重连请求 ?sessionId=xxx
    Gateway->>Pool: 根据 sessionId 查找会话
    Pool->>Browser: 恢复 CDP 连接
    Browser-->>Pool: 状态已恢复
    Pool-->>Gateway: 会话可用
    Gateway-->>Client: 连接成功
```

## REST API 执行器集成

### Executor 工作机制

REST API 执行器（executor.ts）是会话池与 REST 接口之间的桥梁。它接收 HTTP 请求中的参数，分配或复用会话，执行页面操作，最后返回结果。

```mermaid
graph LR
    A[HTTP 请求] --> B[参数解析]
    B --> C[会话获取]
    C --> D[页面操作]
    D --> E[结果提取]
    E --> F[响应返回]
    F --> G[会话释放]
```

### 核心操作支持

#### 内容提取

在 content.ts 和 scrape.ts 中，内容提取功能与会话池紧密集成：

- **HTML 提取**：直接获取页面完整 HTML 内容
- **纯文本提取**：通过 `document.body.innerText` 获取文本
- **Markdown 转换**：使用 defuddle 库将 HTML 转为 Markdown
- **可读性优化**：提取文章内容，移除广告和导航

资料来源：[src/server/rest/content.ts:17-25]()

```typescript
if (body.formats.includes("text")) {
  content.text = await page.evaluate("document.body.innerText") as string;
}
```

#### 页面元数据

所有格式请求都会收集标准元数据：

| 元数据字段 | 来源 |
|------------|------|
| title | document.title |
| description | meta[name="description"] |
| author | meta[name="author"] |
| language | documentElement.lang |
| published | 文章发布日期（如有） |
| image | og:image（如有） |
| favicon | 网站图标 |
| wordCount | 单词计数 |

#### 链接提取

```typescript
const links = await page.evaluate(`
  Array.from(document.querySelectorAll("a[href]"))
    .map(a => ({ url: a.href, text: (a.textContent || "").trim() }))
    .filter(l => l.url && l.text)
`) as Array<{ url: string; text: string }>;
```

#### 屏幕截图

截图功能支持 JPEG 格式，质量设置为 80：

```typescript
const buf = await page.screenshot({
  fullPage: false,
  type: "jpeg",
  quality: 80,
});
output.screenshot = buf.toString("base64");
```

资料来源：[src/server/rest/scrape.ts:52-58]()

## MCP 工具集成

### MCP 中的会话管理

MCP 服务器同样利用会话池来管理浏览器资源。工具定义中的 `sessionId` 参数允许客户端指定要使用的会话。

资料来源：[src/server/mcp/tools.ts:1-20]()

```typescript
server.registerTool("browser_interact", {
  inputSchema: z.object({
    action: z.enum(["click", "type", "select", "press", "scroll"]),
    sessionId: z.string().optional().describe("Session ID"),
    // ... 其他参数
  }),
}, async ({ action, sessionId, ... }) => {
  const session = await getOrCreateSession(sessionId);
  if (!session) return err("No active session. Call browser_navigate first.");
  // 执行操作
});
```

### 交互操作类型

| 操作 | 说明 | 参数 |
|------|------|------|
| click | 点击元素 | selector（引用或 CSS 选择器） |
| type | 输入文本 | selector, text, clear |
| select | 选择下拉选项 | selector, value |
| press | 按键操作 | key（Enter, Tab, Escape 等） |
| scroll | 滚动页面 | direction（up/down） |

## 配置选项

### YAML 配置

在 gateway.yml 中可以配置会话池参数：

| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| session.ttl | 300（5分钟） | 会话生存时间（秒） |
| pool.maxSessions | - | 最大并发会话数 |
| pool.idleTimeout | - | 空闲会话超时时间 |

### 环境变量

| 变量 | 说明 |
|------|------|
| BG_SESSION_TTL | 覆盖默认 TTL |
| BG_TOKEN | 仪表板认证令牌 |

## 使用示例

### 断开后重连

1. 首次连接并执行操作：
```bash
# 发起请求，系统自动分配 sessionId
curl -X POST http://localhost:9500/v1/content \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'
```

2. 断开连接（不关闭浏览器）：
```bash
# 保持浏览器运行，sessionId 在 TTL 内有效
```

3. 使用 sessionId 重连：
```bash
# 通过 ?sessionId=xxx 参数重连
curl -X POST http://localhost:9500/v1/screenshot \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/page2", "sessionId": "xxx"}'
```

### 会话状态保持场景

| 场景 | 行为 |
|------|------|
| 用户登录后断开 | Cookie 和 session 保持 |
| 填写长表单断开 | 表单数据在 localStorage 中保留 |
| 滚动浏览长列表断开 | 页面状态和滚动位置恢复 |
| 多标签操作断开 | 所有标签状态在 TTL 内可恢复 |

## 性能考量

### 资源管理

- **内存占用**：每个活跃会话占用浏览器实例资源
- **连接复用**：合理使用 sessionId 可减少浏览器启动开销
- **TTL 设置**：过长的 TTL 会占用过多资源，过短则影响用户体验

### 最佳实践

1. **批量操作**：将相关操作合并到同一会话中
2. **及时断开**：完成操作后主动断开以释放资源
3. **合理 TTL**：根据业务场景调整 TTL 长度
4. **错误处理**：实现重试逻辑应对会话过期

## API 端点与会话关联

| 端点 | 方法 | 会话行为 |
|------|------|----------|
| /v1/screenshot | POST | 分配/复用会话 |
| /v1/content | POST | 分配/复用会话 |
| /v1/scrape | POST | 分配/复用会话 |
| /v1/sessions | GET | 列出所有活跃会话 |
| /v1/providers | GET/POST | 管理浏览器提供者 |

## 故障排除

### 常见问题

| 问题 | 原因 | 解决方案 |
|------|------|----------|
| 会话无法恢复 | TTL 已过期 | 重新发起请求创建新会话 |
| sessionId 无效 | 会话不存在 | 检查 sessionId 拼写或创建新会话 |
| 状态丢失 | 浏览器崩溃 | 重新连接，系统自动分配新会话 |

### 监控会话状态

通过 `/v1/sessions` 端点可以监控所有活跃会话：

```bash
curl http://localhost:9500/v1/sessions
```

返回当前活跃的会话列表，包括会话 ID、提供者信息、持续时间和消息计数。

---

<a id='rest-api'></a>

## REST API 详解

### 相关页面

相关主题：[会话池与状态持久化](#session-pool), [MCP 服务器](#mcp-server)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [docs/rest-api.md](https://github.com/browser-gateway/browser-gateway/blob/main/docs/rest-api.md)
- [src/server/rest/screenshot.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/screenshot.ts)
- [src/server/rest/content.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/content.ts)
- [src/server/rest/scrape.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/scrape.ts)
- [src/server/rest/schemas.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/schemas.ts)
- [src/server/rest/executor.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/rest/executor.ts)
</details>

# REST API 详解

## 概述

REST API 是 browser-gateway 在 v0.2.0 版本中引入的核心功能，旨在将网关转变为一个完整的浏览器操作 API。通过简洁的 HTTP POST 请求，用户可以直接获取截图、内容提取或结构化数据，无需管理 WebSocket 连接。 资料来源：[README.md](README.md)

REST API 的主要特点包括：

- **会话池化（Session Pool）**：浏览器连接在多个请求之间复用，类似于数据库连接池
- **自动重试（Auto-Retry）**：失败的请求会自动使用新的浏览器页面重试
- **协议无关（Protocol Agnostic）**：支持 Playwright、Puppeteer 等任何 WebSocket 协议
- **零配置启动**：auto-detect Chrome，启动后即可使用

## 核心端点

REST API 提供以下核心端点：

| 端点 | 方法 | 描述 |
|------|------|------|
| `/v1/screenshot` | POST | 捕获任意页面的屏幕截图（PNG 或 JPEG） |
| `/v1/content` | POST | 以 markdown、text、HTML 或 cleaned article 格式提取页面内容 |
| `/v1/scrape` | POST | 通过 CSS 选择器提取数据或获取全页内容 |
| `/v1/status` | GET | 网关健康状态、provider 状态和连接池状态 |
| `/v1/sessions` | GET | 活跃会话列表 |
| `/v1/providers` | GET/POST | 列出或添加 providers |
| `/v1/providers/:id` | PUT/DELETE | 更新或删除 provider |
| `/v1/providers/:id/test` | POST | 测试 provider 连接性 |
| `/v1/config` | GET/PUT | 读取或保存配置 |
| `/v1/config/validate` | POST | 验证 YAML 配置（不保存） |

资料来源：[README.md](README.md)

## 架构设计

### 请求处理流程

```mermaid
graph TD
    A[HTTP POST 请求] --> B{认证检查}
    B -->|有 token| C[验证 Bearer Token]
    B -->|无 token| D[通过]
    C -->|无效| E[返回 401 Unauthorized]
    C -->|有效| D
    D --> F[路由到对应端点处理器]
    F --> G[从会话池获取浏览器页面]
    G --> H{Provider 可用?}
    H -->|否| I[进入冷静期或选择其他 provider]
    H -->|是| J[执行页面操作]
    J --> K{操作成功?}
    K -->|是| L[返回结果]
    K -->|否| M[重试?]
    M -->|是| G
    M -->|否| N[返回错误]
    L --> O[释放或保留会话到池中]
    N --> O
```

### 会话池机制

会话池（Session Pool）是 REST API 实现连接复用的核心组件。每个会话代表一个活跃的浏览器连接，包含以下元数据：

| 字段 | 类型 | 描述 |
|------|------|------|
| id | string | 唯一会话标识符 |
| providerId | string | 关联的 provider ID |
| connectedAt | number | 连接建立时间戳 |
| lastActivity | number | 最后活动时间戳 |
| messageCount | number | 消息计数 |

资料来源：[src/core/types.ts:32-38](src/core/types.ts#L32-L38)

### 重试机制

REST API 内置智能重试机制，通过 `executor.ts` 实现。系统区分可重试和不可重试的错误类型：

```mermaid
graph TD
    A[请求失败] --> B{错误类型检查}
    B -->|ERR_NAME_NOT_RESOLVED| C[不可重试]
    B -->|ERR_INVALID_URL| C
    B -->|ERR_CERT_*| C
    B -->|ERR_SSL_*| C
    B -->|Protocol error| C
    B -->|其他错误| D[可重试]
    C --> E[返回错误]
    D --> F{重试次数 < max?}
    F -->|是| G[等待后重试]
    F -->|否| E
    G --> H[获取新页面]
    H --> I{成功?}
    I -->|是| J[返回结果]
    I -->|否| D
```

不可重试的错误包括：
- `ERR_NAME_NOT_RESOLVED` - DNS 解析失败
- `ERR_INVALID_URL` - 无效的 URL 格式
- `ERR_CERT_*` / `ERR_SSL_*` - SSL 证书错误
- `Protocol error` - 协议错误

资料来源：[src/server/rest/executor.ts:22-28](src/server/rest/executor.ts#L22-L28)

## `/v1/screenshot` 端点

### 功能说明

截图端点用于捕获任意 URL 的页面截图，支持配置视口大小、图片格式和质量参数。

### 请求参数

| 参数 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|--------|------|
| url | string | 是 | - | 目标页面 URL |
| viewport | object | 否 | {width: 1280, height: 720} | 视口尺寸 |
| fullPage | boolean | 否 | false | 是否截取整页 |
| type | string | 否 | png | 图片格式：png 或 jpeg |
| quality | number | 否 | 80 | JPEG 图片质量 (0-100) |
| timeout | number | 否 | 30000 | 超时时间（毫秒） |
| waitUntil | string | 否 | load | 等待策略 |
| waitForSelector | string | 否 | - | 等待特定元素出现 |
| waitForTimeout | number | 否 | - | 等待时间（毫秒） |
| headers | object | 否 | - | 自定义请求头 |
| userAgent | string | 否 | - | 自定义 User-Agent |
| retries | number | 否 | 2 | 重试次数 |

### 响应格式

```json
{
  "success": true,
  "data": {
    "url": "https://example.com",
    "statusCode": 200,
    "screenshot": "base64_encoded_image_data",
    "metadata": {
      "width": 1280,
      "height": 720
    }
  },
  "timings": {
    "total": 1523,
    "navigation": 1200,
    "action": 323
  }
}
```

资料来源：[src/server/rest/screenshot.ts](src/server/rest/screenshot.ts)

## `/v1/content` 端点

### 功能说明

内容提取端点用于获取页面的各种文本格式，支持 markdown、纯文本、HTML 原文和可读性优化内容。

### 请求参数

| 参数 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|--------|------|
| url | string | 是 | - | 目标页面 URL |
| formats | string[] | 是 | - | 输出格式数组 |
| viewport | object | 否 | {width: 1280, height: 720} | 视口尺寸 |
| timeout | number | 否 | 30000 | 超时时间（毫秒） |
| waitUntil | string | 否 | load | 等待策略 |
| waitForSelector | string | 否 | - | 等待特定元素出现 |
| headers | object | 否 | - | 自定义请求头 |
| userAgent | string | 否 | - | 自定义 User-Agent |
| retries | number | 否 | 2 | 重试次数 |

### 支持的格式

| 格式 | 描述 | 附加元数据 |
|------|------|------------|
| markdown | 转换为 Markdown 格式 | title, description, author, wordCount, site |
| text | 纯文本提取 | title, description, author |
| html | 原始 HTML 内容 | - |
| readability | 可读性优化内容 | title, description, author, published, language, image, favicon, wordCount, site |

### 响应格式

```json
{
  "success": true,
  "data": {
    "url": "https://example.com",
    "statusCode": 200,
    "content": {
      "markdown": "# 页面标题\n\n这是页面内容...",
      "text": "页面标题\n\n这是页面内容...",
      "readability": "优化后的可读内容..."
    },
    "metadata": {
      "title": "Example Domain",
      "description": "页面描述",
      "author": "作者名",
      "wordCount": 1234,
      "site": "example.com"
    },
    "links": [
      {"url": "https://example.com/about", "text": "关于我们"}
    ]
  },
  "timings": {
    "total": 2100,
    "navigation": 1500,
    "action": 600
  }
}
```

### 内部处理流程

当请求包含 `markdown` 或 `readability` 格式时，系统会调用 `extractWithDefuddle` 函数进行处理：

1. 获取原始 HTML 内容
2. 根据格式参数决定是否转换为 Markdown
3. 提取元数据（标题、描述、作者等）
4. 如果同时请求 markdown 和 readability，优先使用 readability 的元数据

资料来源：[src/server/rest/content.ts](src/server/rest/content.ts)

## `/v1/scrape` 端点

### 功能说明

数据抓取端点提供更灵活的数据提取能力，支持通过 CSS 选择器精准提取页面元素，或获取完整页面内容。

### 请求参数

| 参数 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|--------|------|
| url | string | 是 | - | 目标页面 URL |
| selectors | Selector[] | 否 | - | CSS 选择器数组 |
| formats | string[] | 否 | - | 完整页面格式 |
| screenshot | boolean | 否 | false | 是否同时返回截图 |
| viewport | object | 否 | {width: 1280, height: 720} | 视口尺寸 |
| timeout | number | 否 | 30000 | 超时时间（毫秒） |
| waitUntil | string | 否 | load | 等待策略 |
| waitForSelector | string | 否 | - | 等待特定元素出现 |
| headers | object | 否 | - | 自定义请求头 |
| userAgent | string | 否 | - | 自定义 User-Agent |
| retries | number | 否 | 2 | 重试次数 |

### Selector 对象

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| name | string | 是 | 数据字段名称 |
| selector | string | 是 | CSS 选择器 |
| attribute | string | 否 | 提取的属性（如 href、src） |

### formats 支持的格式

与 `/v1/content` 端点相同，支持：markdown、text、html、readability

### 响应格式

```json
{
  "success": true,
  "data": {
    "url": "https://example.com",
    "statusCode": 200,
    "data": {
      "title": "页面标题",
      "links": ["https://example.com/about"]
    },
    "content": {
      "markdown": "# 页面内容..."
    },
    "screenshot": "base64_encoded_image",
    "metadata": {
      "title": "Example Domain",
      "description": "页面描述"
    }
  },
  "timings": {
    "total": 1800,
    "navigation": 1300,
    "action": 500
  }
}
```

### 业务规则

1. **必填校验**：必须提供 `selectors` 或 `formats`（或两者都提供）
2. **Markdown/Readability 处理**：当请求包含这些格式时，使用 defuddle 库进行处理
3. **元数据合并**：如果同时请求 readability 和 markdown，元数据从 readability 结果获取

资料来源：[src/server/rest/schemas.ts:40-43](src/server/rest/schemas.ts#L40-L43)

## 请求选项详解

### 等待策略（waitUntil）

| 值 | 描述 |
|----|------|
| load | 默认值，等待 load 事件 |
| domcontentloaded | 等待 DOMContentLoaded 事件 |
| networkidle | 等待网络空闲 |
| commit | 页面开始响应即可 |

### 视口配置

```json
{
  "viewport": {
    "width": 1920,
    "height": 1080
  }
}
```

默认视口为 1280x720，适用于大多数场景。

## 认证机制

当设置 `BG_TOKEN` 环境变量时，所有 `/v1/*` 端点都需要认证：

| 客户端类型 | 认证方式 |
|------------|----------|
| WebSocket 客户端 | `?token=<token>` 查询参数 |
| API 客户端 | `Authorization: Bearer <token>` 请求头 |
| 仪表板 | 登录表单，设置 HttpOnly cookie |

注意：`/health` 端点始终公开可用，无需认证。

资料来源：[README.md](README.md)

## 使用示例

### 截图示例

```bash
# 基本截图
curl -X POST http://localhost:9500/v1/screenshot \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}' --output screenshot.png

# 整页截图
curl -X POST http://localhost:9500/v1/screenshot \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "fullPage": true, "type": "jpeg", "quality": 90}' \
  --output screenshot.jpg

# 自定义视口
curl -X POST http://localhost:9500/v1/screenshot \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "viewport": {"width": 1920, "height": 1080}}'
```

### 内容提取示例

```bash
# 提取 Markdown
curl -X POST http://localhost:9500/v1/content \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "formats": ["markdown"]}'

# 同时提取多种格式
curl -X POST http://localhost:9500/v1/content \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "formats": ["markdown", "text", "html"]}'

# 可读性优化内容
curl -X POST http://localhost:9500/v1/content \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "formats": ["readability"]}'
```

### 数据抓取示例

```bash
# 使用 CSS 选择器提取数据
curl -X POST http://localhost:9500/v1/scrape \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://news.ycombinator.com",
    "selectors": [
      {"name": "titles", "selector": ".titleline > a"},
      {"name": "scores", "selector": ".score"}
    ]
  }'

# 提取带截图
curl -X POST http://localhost:9500/v1/scrape \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "selectors": [{"name": "title", "selector": "h1"}],
    "screenshot": true
  }'

# 结合页面格式和选择器
curl -X POST http://localhost:9500/v1/scrape \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "selectors": [{"name": "price", "selector": ".price"}],
    "formats": ["markdown"]
  }'
```

## 性能优化

### 会话池配置

会话池允许配置每个 provider 的最大并发数：

```yaml
providers:
  primary:
    url: wss://provider.example.com
    limits:
      maxConcurrent: 5
    priority: 1
```

### 建议

1. **合理设置超时**：避免长时间等待无响应页面
2. **使用选择器而非全文**：只请求需要的数据，减少传输量
3. **批量处理**：多个 URL 请求可并行发送
4. **选择合适的等待策略**：不需要完整加载时使用 `domcontentloaded`

## 错误处理

### 常见错误响应

| HTTP 状态码 | 错误信息 | 原因 |
|-------------|----------|------|
| 400 | Bad Request | 请求参数验证失败 |
| 401 | Unauthorized | 缺少或无效的认证 token |
| 404 | Not Found | 资源不存在 |
| 500 | Internal Server Error | 服务器内部错误 |
| 503 | Service Unavailable | 所有 provider 都不可用 |

### 错误响应格式

```json
{
  "success": false,
  "error": "错误描述",
  "code": "ERROR_CODE"
}
```

## 相关文档

- [Dashboard 使用指南](./dashboard.md)
- [MCP Server 文档](./mcp.md)
- [配置参考](../gateway-configuration.md)

---

<a id='mcp-server'></a>

## MCP 服务器

### 相关页面

相关主题：[快速入门](#getting-started)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [docs/mcp.md](https://github.com/browser-gateway/browser-gateway/blob/main/docs/mcp.md)
- [src/server/mcp/server.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/server.ts)
- [src/server/mcp/tools.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/tools.ts)
- [src/server/mcp/local-chrome.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/local-chrome.ts)
- [src/server/mcp/sessions.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/sessions.ts)
</details>

# MCP 服务器

## 概述

MCP 服务器是 browser-gateway 内置的 Model Context Protocol 实现，为 AI 智能体提供直接的浏览器访问能力。通过 MCP 协议，AI 智能体可以执行网页导航、内容提取、截图、交互等操作，无需额外安装 Playwright 或 Puppeteer 等浏览器自动化工具。

```mermaid
graph TB
    subgraph "MCP 客户端"
        A[Claude Code]
        B[Cursor]
        C[其他 MCP 兼容客户端]
    end
    
    subgraph "browser-gateway MCP 服务器"
        D[MCP Streamable HTTP]
        E[工具注册表]
        F[浏览器会话管理]
    end
    
    subgraph "浏览器层"
        G[本地 Chrome]
        H[远程 CDP 提供商]
    end
    
    A --> D
    B --> D
    C --> D
    D --> E
    E --> F
    F --> G
    F --> H
```

MCP 服务器随 browser-gateway v0.1.5 引入，提供 8 种浏览器操作工具，支持零配置启动和并发会话管理。资料来源：[package.json:4]()

## 核心功能

### 8 种浏览器工具

| 工具名称 | 功能描述 | 输入参数 |
|---------|---------|---------|
| `navigate` | 导航到指定 URL | `url`, `waitUntil` |
| `snapshot` | 获取页面快照 | `url` |
| `screenshot` | 截取页面截图 | `url`, `fullPage` |
| `viewport` | 设置视口大小 | `width`, `height` |
| `interact` | 执行页面交互 | `selector`, `action`, `value` |
| `evaluate` | 执行 JavaScript | `script` |
| `close` | 关闭当前页面 | 无 |
| `status` | 获取浏览器状态 | 无 |

资料来源：[docs/mcp.md](https://github.com/browser-gateway/browser-gateway/blob/main/docs/mcp.md)

### 零配置启动

MCP 服务器默认自动检测本地 Chrome 安装，无需手动配置浏览器路径。首次使用工具时会自动启动浏览器实例。资料来源：[src/server/mcp/local-chrome.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/local-chrome.ts)

### 并发会话支持

每个 AI 智能体获得独立的浏览器实例，不同智能体之间不会产生冲突。MCP 服务器通过会话管理模块维护多个独立的浏览器连接。资料来源：[src/server/mcp/sessions.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/sessions.ts)

## 架构设计

### 组件结构

```mermaid
graph TD
    A[MCP 服务器入口] --> B[server.ts - HTTP 端点]
    B --> C[Streamable HTTP 处理]
    C --> D[工具路由分发]
    
    D --> E[tools.ts - 工具定义]
    E --> E1[navigate]
    E --> E2[snapshot]
    E --> E3[screenshot]
    E --> E4[viewport]
    E --> E5[interact]
    E --> E6[evaluate]
    E --> E7[close]
    E --> E8[status]
    
    D --> F[sessions.ts - 会话管理]
    F --> F1[会话创建]
    F --> F2[会话复用]
    F --> F3[会话清理]
    
    D --> G[local-chrome.ts - Chrome 管理]
    G --> G1[Chrome 检测]
    G --> G2[进程启动]
    G --> G3[CDP 连接]
```

资料来源：[src/server/mcp/server.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/server.ts)

### MCP 端点

MCP 服务器通过 HTTP Streamable 协议提供服务，端点位于 `/mcp`。请求格式遵循 Model Context Protocol 规范。资料来源：[docs/mcp.md](https://github.com/browser-gateway/browser-gateway/blob/main/docs/mcp.md)

## 启动方式

### 命令行启动

```bash
# 默认启动，自动检测本地 Chrome
browser-gateway mcp

# 指定 Chrome 路径
browser-gateway mcp --chrome-path /usr/bin/google-chrome

# 连接到现有浏览器
browser-gateway mcp --cdp-endpoint ws://localhost:9222

# 使用配置文件启动
browser-gateway mcp --config gateway.yml
```

### Claude Code 配置

在 Claude Code 配置文件中添加 MCP 服务器：

```json
{
  "mcpServers": {
    "browser-gateway": {
      "command": "npx",
      "args": ["browser-gateway", "mcp"]
    }
  }
}
```

### Cursor 配置

在 Cursor 设置中添加 MCP 服务器：

```json
{
  "mcpServers": {
    "browser-gateway": {
      "command": "npx",
      "args": ["browser-gateway", "mcp"]
    }
  }
}
```

资料来源：[docs/mcp.md](https://github.com/browser-gateway/browser-gateway/blob/main/docs/mcp.md)

## 工具详解

### navigate - 页面导航

导航到指定 URL 并等待页面加载完成。

**输入参数：**

| 参数 | 类型 | 必需 | 描述 |
|-----|------|-----|------|
| `url` | string | 是 | 目标页面 URL |
| `waitUntil` | string | 否 | 等待策略：`load`, `domcontentloaded`, `networkidle` |

**返回结果：**

```json
{
  "url": "https://example.com",
  "title": "Example Domain",
  "statusCode": 200
}
```

### snapshot - 内容快照

获取页面的结构化快照，包含标题、描述、主要内容等元数据。

**输入参数：**

| 参数 | 类型 | 必需 | 描述 |
|-----|------|-----|------|
| `url` | string | 是 | 目标页面 URL |

**返回结果：**

```json
{
  "title": "Page Title",
  "description": "Page description",
  "content": "Main content text...",
  "language": "en"
}
```

### screenshot - 页面截图

截取当前页面或完整页面的截图。

**输入参数：**

| 参数 | 类型 | 必需 | 描述 |
|-----|------|-----|------|
| `url` | string | 是 | 目标页面 URL |
| `fullPage` | boolean | 否 | 是否截取整页，默认 `false` |

**返回结果：**

```json
{
  "data": "base64 encoded image...",
  "mimeType": "image/png"
}
```

### interact - 页面交互

执行点击、输入、悬停等页面交互操作。

**输入参数：**

| 参数 | 类型 | 必需 | 描述 |
|-----|------|-----|------|
| `selector` | string | 是 | CSS 选择器 |
| `action` | string | 是 | 操作类型：`click`, `hover`, `type`, `select` |
| `value` | string | 否 | 操作值（用于 type 和 select） |

### evaluate - JavaScript 执行

在页面上下文中执行任意 JavaScript 代码。

**输入参数：**

| 参数 | 类型 | 必需 | 描述 |
|-----|------|-----|------|
| `script` | string | 是 | 要执行的 JavaScript 代码 |

### viewport - 视口设置

设置浏览器视口的宽度和高度。

**输入参数：**

| 参数 | 类型 | 必需 | 描述 |
|-----|------|-----|------|
| `width` | number | 是 | 视口宽度（像素） |
| `height` | number | 是 | 视口高度（像素） |

### status - 状态查询

获取当前浏览器会话的状态信息。

**返回结果：**

```json
{
  "sessionId": "abc123",
  "url": "https://example.com",
  "title": "Example Domain",
  "viewport": {
    "width": 1920,
    "height": 1080
  }
}
```

### close - 关闭页面

关闭当前浏览器页面，释放相关资源。

资料来源：[src/server/mcp/tools.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/tools.ts)

## 本地 Chrome 检测

MCP 服务器实现了智能的 Chrome 检测机制：

```mermaid
graph TD
    A[启动 MCP 服务器] --> B{检测 CHROME_PATH 环境变量}
    B -->|已设置| C[使用指定路径]
    B -->|未设置| D{Windows}
    D -->|是| E[检查常见安装路径]
    D -->|否| F{macOS}
    F -->|是| E
    F -->|否| G[Linux AppImage/Flatpak]
    E --> H[验证 Chrome 可执行]
    G --> H
    H -->|有效| I[启动 Chrome]
    H -->|无效| J[返回错误]
```

检测顺序：
1. `CHROME_PATH` 环境变量
2. Windows：`C:\Program Files\Google\Chrome\Application\chrome.exe`
3. macOS：`/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`
4. Linux：`/usr/bin/google-chrome`, `/usr/bin/chromium-browser`

资料来源：[src/server/mcp/local-chrome.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/local-chrome.ts)

## 会话管理

### 会话生命周期

```mermaid
graph LR
    A[请求到达] --> B{查找现有会话}
    B -->|存在| C[复用会话]
    B -->|不存在| D[创建新会话]
    C --> E[执行工具]
    D --> E
    E --> F{会话空闲超时}
    F -->|超时| G[清理会话]
    F -->|活跃| H[保留会话]
```

### 会话特性

- **会话复用**：相同客户端的后续请求复用已有会话
- **TTL 管理**：会话空闲时自动清理，默认为 5 分钟
- **独立状态**：每个会话维护独立的 Cookie、LocalStorage 和页面状态

资料来源：[src/server/mcp/sessions.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/mcp/sessions.ts)

## 使用示例

### 完整使用流程

```typescript
// 1. 启动 MCP 服务器
// browser-gateway mcp

// 2. AI 智能体发送导航请求
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "navigate",
    "arguments": {
      "url": "https://github.com"
    }
  }
}

// 3. 获取截图
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "screenshot",
    "arguments": {
      "url": "https://github.com",
      "fullPage": false
    }
  }
}

// 4. 交互操作
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "interact",
    "arguments": {
      "selector": "a[href='/login']",
      "action": "click"
    }
  }
}
```

### 与 Claude Code 配合

1. 安装 browser-gateway：`npm install -g browser-gateway`
2. 配置 Claude Code 的 MCP 设置
3. 直接使用自然语言指令：

```
请访问 GitHub 并截取首页截图，然后告诉我页面上有哪些主要导航链接。
```

## 配置选项

### 命令行参数

| 参数 | 描述 | 默认值 |
|-----|------|-------|
| `--port` | MCP 服务器监听端口 | 9500 |
| `--host` | 服务器绑定地址 | localhost |
| `--chrome-path` | Chrome 可执行文件路径 | 自动检测 |
| `--cdp-endpoint` | 远程 CDP WebSocket 端点 | 无 |
| `--config` | 配置文件路径 | gateway.yml |
| `--session-ttl` | 会话存活时间（秒） | 300 |

### 环境变量

| 变量 | 描述 |
|-----|------|
| `CHROME_PATH` | Chrome 可执行文件路径 |
| `BG_PORT` | Gateway 监听端口 |
| `BG_TOKEN` | Dashboard 认证令牌 |

## 注意事项

1. **Chrome 安装**：确保本地已安装 Google Chrome 或 Chromium
2. **端口占用**：默认端口 9500，确保无冲突
3. **权限问题**：Linux 上可能需要调整 Chrome 启动参数
4. **资源限制**：大量并发会话会消耗系统资源

## 相关文档

- [MCP 文档](./mcp.md) - 官方 MCP 使用指南
- [配置参考](./configuration.md) - 完整配置选项
- [会话生命周期](./session-lifecycle.md) - 会话管理详解
- [支持的提供商](./providers.md) - 远程浏览器提供商

---

<a id='webhook-system'></a>

## Webhook 通知系统

### 相关页面

相关主题：[Provider 管理](#provider-management)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/core/notifications/webhooks.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/notifications/webhooks.ts)
- [README.md](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)
- [src/core/gateway.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/gateway.ts)
- [gateway.dev.yml](https://github.com/browser-gateway/browser-gateway/blob/main/gateway.dev.yml)
- [gateway.example.yml](https://github.com/browser-gateway/browser-gateway/blob/main/gateway.example.yml)
</details>

# Webhook 通知系统

## 概述

browser-gateway 的 Webhook 通知系统允许用户在提供商状态发生变化时接收实时通知。该系统采用事件驱动架构，当检测到提供商宕机、恢复、进入冷却期或队列超时时，自动向配置的 Webhook 端点发送 HTTP POST 请求。

资料来源：[README.md:18](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)

## 架构设计

### 系统组件

```mermaid
graph TD
    GW[Gateway 核心]
    WN[WebhookNotifier]
    EH[事件处理器]
    HR[HTTP 请求发送器]
    RT[重试机制]
    
    GW -->|发布事件| EH
    EH -->|分发| WN
    WN -->|构建负载| HR
    HR -->|HTTP POST| Webhook
    
    HR -->|失败| RT
    RT -->|延迟重试| HR
    
    subgraph "配置"
        Webhook1[Webhook 配置 A]
        Webhook2[Webhook 配置 B]
    end
    Webhook1 --> WN
    Webhook2 --> WN
```

### 事件流

```mermaid
sequenceDiagram
    participant P as Provider
    participant G as Gateway
    participant W as WebhookNotifier
    participant U as Webhook Endpoint
    
    P->>G: Provider Down Event
    G->>W: emit("provider.down", data)
    W->>W: 构建 WebhookPayload
    W->>U: POST /webhook_url
    alt 请求成功
        U-->>W: 200 OK
    else 请求失败
        U-->>W: 4xx/5xx Error
        W->>W: 重试延迟: 1s, 5s, 15s
        W->>U: 重试 POST
    end
```

## 事件类型

browser-gateway 的 Webhook 系统支持以下事件类型：

| 事件名称 | 触发条件 | Status 状态 |
|---------|---------|-------------|
| `provider.cooldown` | 提供商进入冷却期（限流或临时不可用） | `firing` |
| `provider.down` | 提供商完全不可用 | `firing` |
| `provider.up` | 提供商从故障中恢复 | `resolved` |
| `shutdown.start` | 网关开始关闭流程 | `firing` |
| `queue.timeout` | 请求队列超时 | `firing` |

资料来源：[src/core/notifications/webhooks.ts:37-56](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/notifications/webhooks.ts)

## Webhook 负载格式

每个 Webhook 请求都会发送以下 JSON 格式的负载：

```json
{
  "version": "1",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "event": "provider.down",
  "status": "firing",
  "source": "browser-gateway",
  "data": {
    "providerId": "provider-a",
    "reason": "connection_timeout",
    "activeConnections": 5
  }
}
```

### 字段说明

| 字段 | 类型 | 描述 |
|-----|------|-----|
| `version` | string | Webhook 协议版本，当前为 `"1"` |
| `timestamp` | string | ISO 8601 格式的事件时间戳 |
| `event` | string | 事件类型名称 |
| `status` | string | `"firing"` 表示问题进行中，`"resolved"` 表示问题已解决 |
| `source` | string | 固定为 `"browser-gateway"` |
| `data` | object | 事件相关的具体数据，不同事件类型包含不同字段 |

资料来源：[src/core/notifications/webhooks.ts:14-25](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/notifications/webhooks.ts)

## 重试机制

WebhookNotifier 实现了指数退避重试机制：

```typescript
private retryDelays = [1000, 5000, 15000];
```

重试策略如下：

| 重试次数 | 延迟时间 |
|---------|---------|
| 第 1 次重试 | 1 秒 |
| 第 2 次重试 | 5 秒 |
| 第 3 次重试 | 15 秒 |

超过最大重试次数后，请求将被丢弃并记录错误日志。

资料来源：[src/core/notifications/webhooks.ts:27](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/notifications/webhooks.ts)

## 配置方式

### 配置结构

在 `gateway.yml` 中配置 Webhook：

```yaml
webhooks:
  - url: https://your-webhook-endpoint.com/notify
    events:
      - provider.down
      - provider.up
      - provider.cooldown
      - queue.timeout
  - url: https://slack-webhook.example.com/hooks/incoming
    events:
      - provider.down
```

### 配置参数

| 参数 | 类型 | 必填 | 描述 |
|-----|------|-----|-----|
| `url` | string | 是 | Webhook 端点 URL |
| `events` | string[] | 否 | 要订阅的事件列表，默认接收所有事件 |

资料来源：[gateway.dev.yml](https://github.com/browser-gateway/browser-gateway/blob/main/gateway.dev.yml)

## 核心实现

### WebhookNotifier 类

```typescript
export class WebhookNotifier {
  private retryDelays = [1000, 5000, 15000];

  constructor(
    private webhooks: WebhookConfig[],
    private logger: Logger
  ) {}

  static fromGateway(gateway: Gateway, webhooks: WebhookConfig[], logger: Logger): WebhookNotifier {
    const notifier = new WebhookNotifier(webhooks, logger);
    
    gateway.on("provider.cooldown", (data) => {
      notifier.send("provider.cooldown", "firing", data);
    });
    
    // ... 其他事件监听
    return notifier;
  }

  async send(event: string, status: "firing" | "resolved", data: Record<string, unknown>): Promise<void> {
    // 构建并发送 Webhook 负载
  }
}
```

### 事件绑定

Webhooks 与 Gateway 核心通过事件系统集成：

```mermaid
graph LR
    G[Gateway] -->|"on('provider.cooldown')"| WC[Webhooks 冷却]
    G -->|"on('provider.down')"| WD[Webhooks 宕机]
    G -->|"on('provider.up')"| WU[Webhooks 恢复]
    G -->|"on('shutdown.start')"| WS[Webhooks 关闭]
    G -->|"on('queue.timeout')"| WQ[Webhooks 超时]
```

资料来源：[src/core/notifications/webhooks.ts:29-56](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/notifications/webhooks.ts)

## 使用场景

### 运维告警集成

将 Webhook 与 PagerDuty、Opsgenie 等告警系统集成：

```yaml
webhooks:
  - url: https://events.pagerduty.com/v2/enqueue
    events:
      - provider.down
      - queue.timeout
```

### Slack/Teams 通知

在 Slack 或 Microsoft Teams 频道中接收状态更新：

```yaml
webhooks:
  - url: https://hooks.slack.com/services/xxx/yyy/zzz
    events:
      - provider.down
      - provider.up
```

### 自动化恢复

配合外部系统实现自动故障恢复：

```yaml
webhooks:
  - url: https://your-automation-service.com/webhook
    events:
      - provider.up
```

## 与 Gateway 生命周期集成

WebhookNotifier 在 Gateway 初始化时通过 `fromGateway` 静态方法创建，自动绑定所有事件监听器：

```typescript
const notifier = WebhookNotifier.fromGateway(gateway, webhooks, logger);
```

这种设计确保了：

1. **无状态通知**：每个 Webhook 独立处理，无需维护连接状态
2. **事件解耦**：Gateway 核心与通知系统通过事件接口分离
3. **可扩展性**：可轻松添加新的事件类型或通知渠道

## 最佳实践

| 实践 | 说明 |
|-----|-----|
| 使用 HTTPS | 确保 Webhook URL 使用 HTTPS 协议 |
| 快速响应 | Webhook 处理服务应快速响应，避免阻塞 |
| 幂等性 | 接收端应支持幂等处理，应对重试场景 |
| 监控 | 监控 Webhook 端点的可用性和响应时间 |
| 过滤事件 | 仅订阅需要的事件，减少不必要的流量 |

## 限制与注意事项

- Webhook 通知是**尽力而为**的，不保证 100% 送达
- 重试机制仅在 3 次内有效，超过后请求将被丢弃
- 建议配合其他监控手段（如轮询 `/v1/status`）确保告警可靠性

---

<a id='docker-deployment'></a>

## Docker 部署

### 相关页面

相关主题：[快速入门](#getting-started), [Provider 管理](#provider-management)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [docs/docker.md](https://github.com/browser-gateway/browser-gateway/blob/main/docs/docker.md)
- [Dockerfile](https://github.com/browser-gateway/browser-gateway/blob/main/Dockerfile)
- [examples/docker-compose.yml](https://github.com/browser-gateway/browser-gateway/blob/main/examples/docker-compose.yml)
- [.env.example](https://github.com/browser-gateway/browser-gateway/blob/main/.env.example)
- [README.md](https://github.com/browser-gateway/browser-gateway/blob/main/README.md)
- [gateway.yml](https://github.com/browser-gateway/browser-gateway/blob/main/gateway.yml)
</details>

# Docker 部署

## 概述

Browser Gateway 提供官方的 Docker 镜像，支持在容器化环境中快速部署和运行。Docker 部署适合需要隔离、可移植性和易于扩展的生产环境。通过 Docker，用户可以快速启动网关服务，无需手动安装 Node.js 运行时和依赖项。

官方镜像托管在 GitHub Container Registry (ghcr.io)，镜像名为 `ghcr.io/browser-gateway/server`。每次发布新版本时都会构建并推送对应的 Docker 镜像，确保用户可以使用最新稳定版本。

## 快速开始

### 基础运行

使用以下命令可以快速启动 Browser Gateway 容器：

```bash
docker run -d \
  -p 9500:9500 \
  -v ./gateway.yml:/app/gateway.yml:ro \
  -e PROVIDER_TOKEN=xxx \
  ghcr.io/browser-gateway/server:latest
```

这个命令会：
- 以守护进程模式（-d）运行容器
- 将宿主机的 9500 端口映射到容器的 9500 端口
- 将本地的 gateway.yml 配置文件挂载到容器的 /app/gateway.yml（只读）
- 通过环境变量传递 Provider Token

### 端口说明

| 端口 | 协议 | 用途 |
|------|------|------|
| 9500 | HTTP/WebSocket | Gateway 主服务端口 |

容器内部网关监听 9500 端口，所有 HTTP REST API、WebSocket 连接和 Web Dashboard 都通过这个端口访问。

## 环境变量配置

Browser Gateway 支持通过环境变量进行配置。以下是常用的环境变量：

| 环境变量 | 必填 | 说明 |
|----------|------|------|
| `PROVIDER_TOKEN` | 是 | Provider 身份验证令牌 |
| `BG_TOKEN` | 否 | Dashboard 访问认证令牌 |
| `BG_HOST` | 否 | 绑定主机地址，默认为 0.0.0.0 |
| `BG_PORT` | 否 | 监听端口，默认为 9500 |
| `BG_CONFIG` | 否 | 配置文件路径，默认为 /app/gateway.yml |

设置 `BG_TOKEN` 后，Web Dashboard 将启用认证功能，用户需要通过安全的 HttpOnly Cookie 进行身份验证。

资料来源：[.env.example](https://github.com/browser-gateway/browser-gateway/blob/main/.env.example)

## Docker Compose 部署

对于更复杂的部署场景，推荐使用 Docker Compose 进行管理。Docker Compose 可以同时管理网关服务、配置文件和环境变量。

### 基本配置示例

```yaml
services:
  browser-gateway:
    image: ghcr.io/browser-gateway/server:latest
    ports:
      - "9500:9500"
    volumes:
      - ./gateway.yml:/app/gateway.yml:ro
    environment:
      - PROVIDER_TOKEN=${PROVIDER_TOKEN}
      - BG_TOKEN=${BG_TOKEN}
    restart: unless-stopped
```

### 生产环境配置

对于生产环境，建议添加健康检查、资源限制和日志配置：

```yaml
services:
  browser-gateway:
    image: ghcr.io/browser-gateway/server:latest
    ports:
      - "9500:9500"
    volumes:
      - ./gateway.yml:/app/gateway.yml:ro
      - gateway-data:/app/data
    environment:
      - PROVIDER_TOKEN=${PROVIDER_TOKEN}
      - BG_TOKEN=${BG_TOKEN}
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9500/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 512M
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  gateway-data:
```

资料来源：[examples/docker-compose.yml](https://github.com/browser-gateway/browser-gateway/blob/main/examples/docker-compose.yml)

## 配置文件挂载

配置文件通过卷挂载方式传入容器，可以实现配置与容器镜像的分离，便于维护和更新。

### 配置挂载方式

```bash
# 只读挂载配置文件
-v ./gateway.yml:/app/gateway.yml:ro

# 读写挂载（用于保存配置变更）
-v ./gateway.yml:/app/gateway.yml:rw
```

Dashboard 中的配置编辑器支持直接修改配置文件。如果希望保存修改，需要使用读写挂载模式。

### 配置文件示例

```yaml
providers:
  - id: my-provider
    endpoint: wss://provider.example.com
    maxConcurrent: 5
    healthy: true

pool:
  maxConcurrent: 10
  sessionTimeout: 300

server:
  port: 9500
  host: 0.0.0.0
```

资料来源：[gateway.yml](https://github.com/browser-gateway/browser-gateway/blob/main/gateway.yml)

## 网络配置

### 容器网络模式

Browser Gateway 需要与外部 Provider 建立 WebSocket 连接，确保容器可以访问外部网络：

```mermaid
graph LR
    A[客户端] -->|HTTP/WebSocket| B[Browser Gateway 容器:9500]
    B -->|WebSocket| C[外部 Provider]
    B -->|WebSocket| D[本地 Provider]
```

### 宿主机网络模式

如果需要让宿主机上的浏览器可以直接访问 CDP 端点，可以使用宿主机网络模式：

```bash
docker run -d \
  --network host \
  -v ./gateway.yml:/app/gateway.yml:ro \
  -e PROVIDER_TOKEN=xxx \
  ghcr.io/browser-gateway/server:latest
```

使用 `--network host` 时，容器共享宿主机的网络命名空间，可以直接访问宿主机的 localhost 服务。

### 代理配置

如果部署环境需要通过代理访问外部网络，需要配置代理环境变量：

```yaml
environment:
  - HTTP_PROXY=http://proxy.example.com:8080
  - HTTPS_PROXY=http://proxy.example.com:8080
  - NO_PROXY=localhost,127.0.0.1
```

## 健康检查

Docker 支持内置的健康检查机制，可以监控 Browser Gateway 的运行状态。

### 健康检查端点

Browser Gateway 提供 `/health` 端点用于健康检查：

```bash
curl http://localhost:9500/health
```

响应示例：
```json
{
  "status": "ok",
  "uptime": 3600,
  "providers": 2,
  "activeConnections": 5
}
```

### 配置健康检查

在 docker-compose.yml 中配置健康检查：

```yaml
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:9500/health"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 40s
```

## 数据持久化

### 会话数据

Browser Gateway 支持会话持久化功能，用户的浏览器状态（Cookie、localStorage、页面状态）可以在断开重连后恢复。默认 TTL 为 5 分钟。

### 卷挂载

为确保数据持久化，需要挂载数据目录：

```bash
docker run -d \
  -p 9500:9500 \
  -v ./gateway.yml:/app/gateway.yml:ro \
  -v ./data:/app/data \
  ghcr.io/browser-gateway/server:latest
```

## 安全考虑

### 令牌管理

- `PROVIDER_TOKEN`：Provider 身份验证，部署时通过环境变量注入
- `BG_TOKEN`：Dashboard 认证，建议使用强随机字符串

### 网络隔离

- 使用 Docker 网络隔离其他服务
- 通过防火墙限制对 9500 端口的访问
- 生产环境建议启用 HTTPS 反向代理

### 只读配置

配置文件使用 `ro` (read-only) 挂载选项，防止容器内修改配置：

```bash
-v ./gateway.yml:/app/gateway.yml:ro
```

## 镜像版本

### 版本标签

| 标签 | 说明 |
|------|------|
| `latest` | 最新稳定版本 |
| `v0.2.0` | 指定版本 |
| `v0.1.8` | 历史版本 |

建议在生产环境中使用具体版本号，避免自动升级导致兼容性问题。

### 更新镜像

```bash
# 拉取最新版本
docker pull ghcr.io/browser-gateway/server:latest

# 重启容器
docker-compose down
docker-compose up -d
```

## 常见问题

### 容器启动失败

检查日志排查问题：

```bash
docker logs <container_id>
```

常见原因包括配置文件格式错误、端口冲突、环境变量缺失等。

### WebSocket 连接问题

确保容器可以访问 Provider 的 WebSocket 端点，检查网络连通性和防火墙规则。

### 内存不足

浏览器操作需要较大内存，建议容器内存限制不少于 512MB，生产环境建议 2GB 以上。

## 相关文档

- [配置参考](./configuration.md)
- [Provider 配置](./providers.md)
- [负载均衡策略](./load-balancing.md)
- [故障转移机制](./failover.md)
- [REST API](./rest-api.md)

---

<a id='provider-management'></a>

## Provider 管理

### 相关页面

相关主题：[配置参考](#quick-configuration)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [docs/providers.md](https://github.com/browser-gateway/browser-gateway/blob/main/docs/providers.md)
- [src/core/providers/cdp.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/providers/cdp.ts)
- [src/core/providers/health.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/providers/health.ts)
- [web/src/app/(dashboard)/providers/page.tsx](https://github.com/browser-gateway/browser-gateway/blob/main/web/src/app/(dashboard)/providers/page.tsx)
- [src/server/config/writer.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/server/config/writer.ts)
- [src/core/types.ts](https://github.com/browser-gateway/browser-gateway/blob/main/src/core/types.ts)
</details>

# Provider 管理

Provider 是 browser-gateway 的核心概念之一，指代提供浏览器实例的后端服务。gateway 通过统一的管理接口，将请求路由到不同的 Provider，实现浏览器资源的高可用、负载均衡和故障转移。

## 概述

browser-gateway 支持接入多个浏览器提供方（Provider），包括：

| Provider 类型 | 示例 | 说明 |
|---------------|------|------|
| Playwright Server | `ws://your-server:3000` | 自托管的 Playwright 服务 |
| 云端浏览器服务 | `wss://provider.com?token=xxx` | 第三方云服务 |
| Chrome DevTools Protocol | `ws://localhost:9222` | 原生 Chrome/CDP 连接 |
| MCP 协议服务 | `http://localhost:9500/mcp` | MCP 兼容的浏览器服务 |

资料来源：[web/src/app/(dashboard)/providers/page.tsx:55-75]()

### 核心功能

- **多 Provider 接入**：同时管理多个浏览器后端服务
- **健康检查**：实时监控 Provider 可用性
- **负载均衡**：基于优先级和权重的请求分发
- **故障转移**：Provider 不可用时自动切换
- **会话池**：复用浏览器连接提升性能
- **CRUD 操作**：通过 Dashboard 或 API 动态管理

## Provider 数据模型

### ProviderConfig（配置）

定义 Provider 的静态配置信息：

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `id` | `string` | 是 | 唯一标识符，使用小写字母和连字符 |
| `url` | `string` | 是 | WebSocket 连接地址 |
| `priority` | `number` | 否 | 优先级（数字越小优先级越高） |
| `weight` | `number` | 否 | 权重（用于加权轮询） |
| `maxConcurrent` | `number` | 否 | 最大并发连接数 |
| `cooldown` | `number` | 否 | 故障后冷却时间（毫秒） |
| `timeout` | `number` | 否 | 请求超时时间（毫秒） |
| `headers` | `Record<string, string>` | 否 | 自定义请求头 |

资料来源：[src/core/types.ts:1-25]()

### ProviderState（运行时状态）

描述 Provider 的运行时状态：

| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `string` | Provider ID |
| `config` | `ProviderConfig` | 当前配置 |
| `active` | `number` | 当前活跃连接数 |
| `healthy` | `boolean` | 健康状态 |
| `cooldownUntil` | `number \| null` | 冷却截止时间戳 |
| `failureCount` | `number` | 连续失败次数 |
| `successCount` | `number` | 成功请求次数 |
| `lastFailure` | `number \| null` | 最后失败时间戳 |
| `avgLatencyMs` | `number` | 平均延迟（毫秒） |
| `totalConnections` | `number` | 历史总连接数 |

资料来源：[src/core/types.ts:27-39]()

## 架构设计

```mermaid
graph TD
    Client[客户端请求] --> Gateway[Browser Gateway]
    Gateway --> Router[路由引擎]
    Router --> HealthMonitor[健康监控]
    Router --> LoadBalancer[负载均衡器]
    LoadBalancer --> P1[Provider 1<br/>优先级: 1]
    LoadBalancer --> P2[Provider 2<br/>优先级: 2]
    LoadBalancer --> P3[Provider N<br/>优先级: N]
    
    HealthMonitor -->|健康检查| P1
    HealthMonitor -->|健康检查| P2
    HealthMonitor -->|健康检查| P3
    
    P1 -->|连接成功| Browser1[浏览器实例]
    P2 -->|连接成功| Browser2[浏览器实例]
    P3 -->|连接成功| Browsern[浏览器实例]
    
    P1 -.->|故障| Cooldown[冷却期]
    Cooldown -.->|恢复| P1
```

### 请求路由流程

```mermaid
sequenceDiagram
    participant C as 客户端
    participant G as Gateway
    participant R as 路由引擎
    participant H as 健康检查
    participant P as Provider
    
    C->>G: POST /v1/screenshot
    G->>R: 请求路由
    R->>H: 检查 Provider 状态
    H-->>R: Provider 可用
    R->>P: 建立浏览器连接
    P-->>R: 连接成功
    R->>P: 导航到目标 URL
    P-->>R: 截图数据
    R-->>G: 返回结果
    G-->>C: HTTP 响应
```

## Provider 配置管理

### 通过 Dashboard 配置

在 Dashboard 的 Providers 页面可以完成以下操作：

| 操作 | 入口 | 说明 |
|------|------|------|
| 查看列表 | `/web/providers` | 显示所有 Provider 及其状态 |
| 添加 Provider | 添加按钮 | 输入 ID、URL、优先级等 |
| 编辑 Provider | 编辑按钮 | 修改现有配置 |
| 删除 Provider | 删除按钮 | 移除 Provider 配置 |
| 测试连接 | 测试按钮 | 验证 Provider 连通性 |

资料来源：[web/src/app/(dashboard)/providers/page.tsx:1-100]()

### Provider ID 命名规范

- 使用小写字母
- 使用连字符 `-` 分隔
- 示例：`playwright-local`、`cloud-browser-1`

```typescript
// 验证规则
/^[a-z][a-z0-9-]*$/
```

资料来源：[web/src/app/(dashboard)/providers/page.tsx:30-35]()

### WebSocket URL 格式

| 类型 | 格式 | 示例 |
|------|------|------|
| 自托管 | `ws://host:port` | `ws://localhost:3000` |
| 云服务 | `wss://host?token=xxx` | `wss://provider.com?token=xxx` |
| 带认证 | `wss://host?api_key=xxx` | `wss://cloud.browser.io?api_key=xxx` |

## 健康检查机制

### 健康检查流程

```mermaid
graph LR
    A[定时检查] --> B{连接成功?}
    B -->|是| C[更新 healthy=true]
    B -->|否| D[增加 failureCount]
    D --> E{超过阈值?}
    E -->|是| F[设置 cooldownUntil]
    E -->|否| G[标记 unhealthy]
    F --> H[等待冷却期]
    H --> I{冷却期结束?}
    I -->|是| J[重新尝试]
```

### 健康检查实现

健康检查模块负责监控每个 Provider 的可用性：

```typescript
// 检查间隔：默认 10 秒
// 冷却时间：默认 30 秒
// 失败阈值：连续 3 次失败
```

资料来源：[src/core/providers/health.ts:1-50]()

### 冷却机制

当 Provider 连续失败达到阈值后，进入冷却状态：

| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `cooldown` | `30000ms` | 冷却持续时间 |
| `failureThreshold` | `3` | 进入冷却的连续失败次数 |

冷却期间，该 Provider 不会被路由选中。冷却结束后，系统会重新尝试连接。

## 负载均衡策略

### 优先级选择

Provider 按 `priority` 字段排序，数字越小优先级越高。路由引擎优先选择优先级最高的可用 Provider。

```mermaid
graph TD
    R[路由请求] --> Q{Provider 1 可用?}
    Q -->|是| A[使用 Provider 1]
    Q -->|否| Q2{Provider 2 可用?}
    Q2 -->|是| B[使用 Provider 2]
    Q2 -->|否| Q3{Provider 3 可用?}
    Q3 -->|是| C[使用 Provider 3]
    Q3 -->|否| E[返回错误]
```

### 加权轮询

当多个 Provider 具有相同优先级时，使用权重进行加权轮询：

| Provider | Weight | 相对权重 |
|----------|--------|----------|
| local-1 | 2 | 50% |
| local-2 | 1 | 25% |
| cloud-1 | 1 | 25% |

资料来源：[web/src/app/(dashboard)/providers/page.tsx:85-95]()

### 并发控制

每个 Provider 可以设置 `maxConcurrent` 限制最大连接数：

```yaml
providers:
  - id: local-chrome
    url: ws://localhost:9222
    maxConcurrent: 5  # 最多同时 5 个连接
```

当达到上限时，路由引擎会尝试选择其他 Provider。

## REST API 接口

### 获取 Provider 列表

```http
GET /v1/providers
```

响应示例：

```json
{
  "success": true,
  "data": [
    {
      "id": "playwright-local",
      "url": "ws://localhost:3000",
      "priority": 1,
      "weight": 1,
      "maxConcurrent": 10,
      "cooldown": 30000,
      "timeout": 30000,
      "headers": {}
    }
  ]
}
```

### 添加 Provider

```http
POST /v1/providers
Content-Type: application/json

{
  "id": "new-provider",
  "url": "ws://new-server:9222",
  "priority": 2,
  "weight": 1,
  "maxConcurrent": 5
}
```

### 更新 Provider

```http
PUT /v1/providers/:id
Content-Type: application/json

{
  "url": "ws://updated-server:9222",
  "priority": 1
}
```

### 删除 Provider

```http
DELETE /v1/providers/:id
```

### 测试 Provider 连接

```http
POST /v1/providers/:id/test
```

用于验证 Provider 的 WebSocket 连接是否正常，返回连接延迟和健康状态。

## 配置示例

### gateway.yml 完整配置

```yaml
server:
  port: 9500
  host: "0.0.0.0"

providers:
  - id: playwright-local
    url: ws://localhost:3000
    priority: 1
    weight: 1
    maxConcurrent: 10
    cooldown: 30000
    timeout: 30000

  - id: cloud-browser-1
    url: wss://cloud.provider.com?token=xxx
    priority: 2
    weight: 2
    maxConcurrent: 20
    cooldown: 60000
    headers:
      Authorization: "Bearer xxx"

pool:
  minSessions: 1
  maxSessions: 100
  sessionTimeout: 300000

auth:
  enabled: false
  token: ""
```

### 多地域配置

```yaml
providers:
  - id: us-east-chrome
    url: ws://us-east.browser.internal:9222
    priority: 1
    headers:
      X-Region: us-east

  - id: eu-west-chrome
    url: ws://eu-west.browser.internal:9222
    priority: 1
    headers:
      X-Region: eu-west

  - id: backup-cloud
    url: wss://backup.provider.com?token=xxx
    priority: 3
    weight: 1
```

## 监控与状态

### Dashboard 状态指示

| 指示灯 | 颜色 | 含义 |
|--------|------|------|
| ● | 绿色 | Provider 健康 |
| ● | 红色（闪烁） | Provider 不健康 |
| 徽章 | cooldown | Provider 处于冷却期 |

资料来源：[web/src/app/(dashboard)/page.tsx:25-40]()

### 状态端点

```http
GET /v1/status
```

返回所有 Provider 的实时状态：

```json
{
  "success": true,
  "data": {
    "providers": [
      {
        "id": "playwright-local",
        "healthy": true,
        "active": 3,
        "maxConcurrent": 10,
        "avgLatencyMs": 45,
        "priority": 1
      },
      {
        "id": "cloud-browser",
        "healthy": false,
        "active": 0,
        "maxConcurrent": 20,
        "avgLatencyMs": 0,
        "priority": 2,
        "cooldownUntil": 1699999999999
      }
    ],
    "sessions": 3,
    "uptime": 86400
  }
}
```

## 最佳实践

### Provider 命名约定

1. **使用描述性名称**：`playwright-local`、`cloud-browser-prod`
2. **包含环境标识**：`chrome-staging`、`chrome-production`
3. **包含区域信息**：`us-east-1-chrome`、`eu-west-2-chrome`

### 故障恢复策略

```yaml
# 推荐配置：本地优先，云端备份
providers:
  - id: local-primary
    url: ws://localhost:9222
    priority: 1
    cooldown: 5000  # 本地故障快速恢复

  - id: local-replica
    url: ws://localhost:9223
    priority: 1
    cooldown: 5000

  - id: cloud-backup
    url: wss://cloud.provider.com?token=xxx
    priority: 3
    cooldown: 30000  # 云端较长冷却期
```

### 性能优化

| 优化项 | 建议值 | 说明 |
|--------|--------|------|
| `maxConcurrent` | CPU 核心数 × 2 | 平衡并发与资源 |
| `cooldown` | 30s - 60s | 避免频繁切换 |
| `timeout` | 30s - 60s | 合理超时设置 |

### 高可用部署

```mermaid
graph TD
    LB[负载均衡器] --> GW1[Gateway 实例 1]
    LB --> GW2[Gateway 实例 2]
    LB --> GW3[Gateway 实例 N]
    
    GW1 --> P1[Provider Pool]
    GW2 --> P1
    GW3 --> P1
    
    P1 --> PW1[Playwright 1]
    P1 --> PW2[Playwright 2]
    P1 --> PWn[Playwright N]
    
    PW1 --> Chrome1[Chrome 实例]
    PW2 --> Chrome2[Chrome 实例]
    PWn --> Chromen[Chrome 实例]
```

## 故障排除

### 常见问题

| 问题 | 可能原因 | 解决方案 |
|------|----------|----------|
| Provider 显示不健康 | WebSocket 连接失败 | 检查 URL 和网络连通性 |
| 连接数达到上限 | `maxConcurrent` 过低 | 调高或设为 unlimited |
| 频繁故障转移 | Provider 性能不足 | 升级硬件或增加 Provider |
| 冷却状态无法恢复 | 配置错误 | 检查 `cooldown` 配置 |

### 调试命令

```bash
# 测试 Provider 连通性
browser-gateway check

# 查看详细日志
DEBUG=provider:* browser-gateway serve

# 验证配置文件
browser-gateway config validate
```

## 相关文档

- [REST API 文档](./rest-api.md)
- [Dashboard 使用指南](./dashboard.md)
- [MCP Server 文档](./mcp.md)
- [配置参考](./configuration.md)

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：browser-gateway/browser-gateway

摘要：发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。

## 1. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 建议检查：将假设转成下游验证清单。
- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。
- 证据：capability.assumptions | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | README/documentation is current enough for a first validation pass.

## 2. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。
- 证据：evidence.maintainer_signals | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | last_activity_observed missing

## 3. 安全/权限坑 · 下游验证发现风险项

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：下游已经要求复核，不能在页面中弱化。
- 建议检查：进入安全/权限治理复核队列。
- 防护动作：下游风险存在时必须保持 review/recommendation 降级。
- 证据：downstream_validation.risk_items | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | no_demo; severity=medium

## 4. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 建议检查：把风险写入边界卡，并确认是否需要人工复核。
- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。
- 证据：risks.scoring_risks | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | no_demo; severity=medium

## 5. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。
- 防护动作：issue/PR 响应未知时，必须提示维护风险。
- 证据：evidence.maintainer_signals | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | issue_or_pr_quality=unknown

## 6. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。
- 证据：evidence.maintainer_signals | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | release_recency=unknown

<!-- canonical_name: browser-gateway/browser-gateway; human_manual_source: deepwiki_human_wiki -->
