内容
WebBrowserForAgent
一个 MCP(模型上下文协议)服务器,为 AI 代理提供对真实网页浏览器的完全控制 Playwright 构建,支持 Chromium、Firefox 和 Web提供截图捕获、鼠标/、多标签页管理以及**可访问性地图** ——文本的页面上所有交互元素的表示方式 —— 使任何模型都能够操作浏览器多模态能力。
[한국어 문서 (Korean)](_ko.md)
## 功能特点
- **截图捕获** — 单次捕获和基于 FPS 的连续录制(1-5 FPS,环形缓冲区)
- **可访问性地图** — 将所有交互元素的坐标、角色和属性提取为文本。无需视觉即可控制浏览器。
- **双模式定位** — 通过 `{x, y}` 像素坐标或来自可访问性地图的 `{elementIndex}` 进行交互 **完全输入控制 点击、双击、右、拖动、滚动、输入文本、快捷键
- **多标签页管理** — 自动检测新标签页、显式标签页切换、打开/关闭标签页
- **设备预设** — 桌面、iPhone、Pixel、iPad 和其他移动/平板电脑视口
- **双重传输** — stdio(本地)/ 流式 HTTP(远程)
## 要求
- **Node.js** >= 18
- **操作系统**:macOS、Windows、Linux(包括无头服务器)
### 无头 Linux 服务器(Ubuntu、 等)
Playwright 在仅有 CLI 的环境中模式下工作,无需。Docker、CI/CD服务器都支持。但是,必须安装:
```bash
# 自动安装 Chromium 的操作系统级依赖(需要px playwright install-de
```
关键库:nss3`atk-bridge2.0`、`libdrm2libxkbcommon0`、`libgbm1`等。上面的命令通过 apt 自动安装它们。
### Docker
file
FROM node:lim
# 启用 p通过 Corepack 与 Node 捆绑)
RUN corepack enable
# 安装 系统依赖
RUN n install-deps chromium
/app
COPY packagenpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
RUN npx playwright install chromium
COPY . .
RUN pnpm build
EXPOSE 3100
CMD ["node", "dist/mcp/server.js", "--transport", "http"]
资源需求
| 资源 | 最小值 | 推荐 --- | --- |
| RAM | 512MB | 1GB+ CPU | 1 个 2+ 个核心 |
| 磁盘 | (Chromium 二进制文件) | 1GB+ |
单个 Chromium 实例大约使用 200-500MB 内存。复杂的页面需要更多。
## 限制
- **单个**:每个 MCP 服务器实例。要同时运行多个启动多个服务器实例。
- **视口大小限制** 1280×720。此限制旨在优化 AI 令牌消耗。使用滚动超出视口的页面。
- **文件下载/上传目前不支持文件下载input type="file">`- **身份验证弹出窗口**:不支持 HTTP 基本身份验证和操作系统级身份验证对话框。仅支持基于 Web 的登录表单。
- **WebRTC/媒体**:不支持摄像头、麦克风和媒体流功能。
- **HTTP 传输安全性**:HTTP 模式默认绑定到 `127.0.0.1`,并强制执行主机头允许列表(DNS 重新绑定保护),因此即使在环回绑定上,恶意的网页也无法访问端点。`/mcp` 端点**没有内置身份 —— 绑定到非主机会暴露对持有用户登录会话的浏览器的,因此需要一个具有 TLS验证反向代理,而不是可选的。当远程绑定时,请将 `MCP_HTTP_ALLOWED(和可选的CP_HTTP_ALLOWED_ORIGINS`)设置为客户端连接的主机- **并发连接** HTTP 连接的多个客户端共享一个浏览器实例,这状态冲突。请为使用单独的服务器实例 **浏览器二进制文件不包含在内**:npm包含浏览器二进制文件。安装后,请单独运行 ` playwright install chromium`。Kit 也需要它们自己的。
## 快速### 通过 npm 安装
```bash
npm install web-browser-for-agent
```
安装后,安装 Playwright Chromium 浏览器:
```bash
npx playwright
```
### 与 Claude Desktop / MCP 客户端一起使用
`claude_desktop`:
```json "m": {
"web-browser": {
"command": "",
" ["web-browser-for "--transport", "stdio"]
}
}
}
作为 HTTP 服务器运行
```bash
npx web-browser --transport http
#监听 127.0.1:3100
```
通过环境配置:
| | 默认值 | 描述 |
| --- | --- | --- `MCP_HTTP | `3100` | 监听端口 |
| `_HTTP_HOST` | `127.0.0. | 绑定地址。回绑定需要反向代理(参见 [限制](#) |
| `_HTTP_ALLOWED_HOSTS` | 环 绑定 |号分隔的主机头(DNS 重新) |
| `MCP_ORIGINS` |任意)_ |号分隔的源允许列表 |
## MCP 工具
### 导航
| 工具 |
| --- || `browser_launch` | 启动浏览器(引擎、、设备预设) |
| `browser_navigate 导航到 URL |
| `browser_back` | 后退历史记录 |
|_forward` | 前进 |
| `browser_close` | 关闭浏览器 |
| `browser_resize` | 调整视口大小,或应用设备预设的尺寸(仅视口 - 无 UA/触摸仿真) |
### 截图和录制
| 工具 | 描述 |
| --- | --- |
| `browser_screenshot` | 捕获截图 +性地图 |
| `_recording` | 开始基于 FPS 的连续捕获(1-5 FPS) |
| `browser_stop_recording连续捕获 无障碍
| 工具 | 描述 |
| ---| `browser_get_map` | 获取文本地图 |
### 鼠标
| 工具 |
| --- | --- |
| `browser_click`(坐标或 elementIndex| `browser_double_click 双击 |
|_right_click` |点击 |
| `` | 拖动和释放 |
| `browser` | 移动鼠标停) |
| `browser_scroll` | 滚动### 键盘
| 工具 | 描述 |
| --- |
| `` | 输入文本 |
browser_key_press` |键(Enter、Tab 等) |
|_hotkey` | (Ctrl+A、Cmd+C 等) |
### 标签页管理
| 工具 | 描述 |
| --- |
| `browser_list | 列出所有打开页 |
| `browser_switch_tab` | 标签页 |
| `browser_new_tab` | 打开页 |
| `browser_close_tab` | 关闭标签页 |
## 可访问性地图
使没有视觉能力的通过将页面上的提取为结构化文本浏览器。
### 示例```
[可访问性地图 - 5 个元素:main]
[ 按钮 "登录" @ (350, 420120, 40)
] 链接 "注册" @ (500, 80,) - href=https://example.com/signup
[2 [text] "" @ (300, 300, 35) - placeholder=电子邮件地址3] 输入 [password] "" @ (300, 350, 200, 35) - placeholder=密码4] 复选框 "记住我" @ (300, 390, 20, 20) -
[可访问性地图 - 1 个元素:iframe#payment]
[5] 输入 [text] "" @ (100, 200, 250, - placeholder=
```
- 每个获得一个唯一的索引 - 使用 `browser_click({ target: { elementIndex: 0 } })` 进行交互
- 自动遍历 iframe;坐标相对于主框架
- 通过 `cursor:pointer` 和 `onclick` 属性检测非标准的可点击元素
- 链接 href 是 DOM 解析的绝对 URL(例如,`example 上的 `/signup显示为 `href=https://example.com/signup### 检测到的标准交互元素:[href]`、`、`input`、`、`textarea`、`[role="button"]`、`="link"]`、`[role="checkbox"]`、`[role="radio"]`role="tab[role="menuitem"]`、`[tabindex]`、`[contenteditable]`
非标准的可点击`cursor: pointer` 样式、`onclick`click`/`ng-click` 属性
## 设备预设
| 预设 | 设备视口 | 应用(限幅) | 描述 |
| --- | --- || `desktop` | 1280×720 | 1280×720 | 默认 |
| `iphone- 390×664390×664OS 移动设备 |
| `iphone-14-l 750×340 | 750×480向模式 |
| `pixel-7` | 839 | 412 | Android 移动| `ipad-pro-11` | 1194 | 834×720 | 平板电脑口被限制在 320-1280(× 480-高度),设备缩放因子被 2 倍 —— 将截图保持在优化牌大小上限内。`browser_launch({ device 应用完整的移动设备仿真(用户代理、触isMobile`);_resize({ device })仅应用**视**。
> 预设视口跟踪的 Playwright 设备注册表(针对 Playwright.58.x 验证)。
## 编程使用模块可以直接导入,而 MCP 服务器:
```import {
Browser AccessibilityMapper,
ScreenshotEngine,
InputController,
} from 'web-agent';
const browser BrowserManager();
const mapper =Mapper();
const screenshot ScreenshotEngine(mapconst input = new InputController();
await browser.launch({: true });
const page = browser.getActivePage page.goto('https://example.com');
// 截图 + 可访问性地图
= browser.getViewport();
const result = await screenshot.capture(page, viewport, true);
console.log(AccessibilityMapper.formatAsText(result.accessibilityMap!));
// 按元素索引点击 - 找到的帮助函数在生成的地图上可用
const map = await mapper.generateMap(page, viewport);
const loginBtn = map.findByText('登录');
if (loginBtn) {
await input.click(page, { elementIndex: loginBtn.index }, map);
}
await browser.close();
```
## 开发
```bash
git clone https://github.com/MosslandOpenDevs/WebBrowserForAgent.git
BrowserForAgent
pnpm install
pnpnpm test
```
| 命令 | 描述 --- | --- |
| `pnpm build`构建 TypeScript → dist/ |
| `pnpm dev` | 监视模式构建 |
| `pnpm test` | 运行所有测试 |
| `pn -- src/core/__tests__/browser.test.ts`单个测试文件 |
| `pnpm lint` | |
| `pnpm format` | Prettier |
## 架构
```
src/
├── core/ # 浏览器控制核心
│ ├── browser.ts — 浏览器/标签生命周期,视口 ├── screenshot.ts # ScreenshotEngine — FPS 录制,环形缓冲区
│ ├── accessibility.ts # AccessibilityMapper — DOM 查询,边界框提取
│ ├── input.ts # Input 鼠标,键盘,拖动
│ └── errors.ts # 自定义错误类
├── mcp/
│ ├── server.ts # MCP 服务器入口点,传输选择
│ └── tools/ # MCP 工具定义(每个域一个文件)
└── # 库重新导出
```
## 路线图和未来方向
WebBrowserForAgent 故意设计且可组合,离完成还有很远。下面是我们认为值得探索的方向,而不是一个承诺的计划多数直接源自当前的 [限制](#限制)。讨论和 PR 都欢迎。
### 功能
- **HTTP 上的并发会话**。今天,一个浏览器由每个服务器进程共享。一个选择加入的模式,为每个 MCP 会话提供自己的浏览器上下文(或一个池化的浏览器),将允许一个 HTTP 服务器在隔离状态下驱动多个代理,而不是为每个客户端运行一个进程。
- **文件上传和下载**。支持 `<input type="file">` 上传和捕获下载,以便代理可以将数据移入和移出页面。
- **等待原语**。browser_wait_for`(选择器/文本/网络空闲)让代理可以同步动态 SPA 内容,而不是依赖固定延迟。
- **对话框和身份验证处理**。拦截 `alert` / `confirm` / `prompt` 并处理 HTTP 基本身份验证弹出窗口。
- **会话持久性**。保存和恢复 cookie 和存储状态(Playwright 的 `storageState`),以便登录在重启后仍然有效,理想情况下使用命名配置文件。
### 可观察性
- **控制台和网络访问**。将控制台日志和网络请求/响应(包括故障)作为工具公开,以便代理可以调试页面,而不仅仅是驱动它们。
- **可访问性地图差异返回快照之间的“变化内容”,以及更(禁用/聚焦/展开,滚动偏移,视口外提示),以减少繁忙页面牌使用。
### 健壮性和性能
内置 HTTP 身份。一个可选的令牌/API 密钥层,以便远程部署不需要严格的代理。
- **更快的提取**。并发的提取和增更新,适用于页面。
###和基础设施
-引擎 CI**。Git 矩阵,实际测试 Chromium、Firefox 和 WebKit —— 针对所有三个引擎,但目前仅覆盖 Chromium。
CP 处理器测试**。围绕工具/测试,补充当前的内核类覆盖。
这些都不是一成不变的。如果这里的方向 — 或我们尚未想到的方向 — 对您很重要,请打开一个问题或 PR,让我们讨论。
## 许可证
[MIT](./LICENSE)