内容
<div align="center">
#
### AI 的手和眼睛在网络上
**为 AI 驱动而构建的浏览器** - 感知和行动层,使代理能够
快速、完整、 *可验证* 地控制网络。 在 npm 上以 **`ecobrowser`** 发布:一个 **TypeScript 库** 和一个 **MCP 服务器**。








*结构化(无像素)感知 · 验证的自我修复动作 · 增量差异感知 · 直观视图以观察其工作。*
</div>
---
## 目录
- [这是什么?](#这是什么?)
- [亮点](#亮点)
- [架构](#架构)
- [工作原理](#工作原理)
- [快速开始](#快速开始)
- [MCP 工具](#mcp-工具)
- [比较](#比较)
- [配置](#配置)
- [脚本](#脚本)
- [项目布局](#项目布局)
- [安全性和范围](#安全性和范围)
- [路线图](#路线图)
---
## 这是什么?
大多数“AI 浏览器”要么是在浏览器上附加的聊天侧边栏,要么是没有反馈循环的无头爬取 API。而这两者都不是。它是 **使真正的浏览器可由模型使用** 的层 - 主要“用户”是 AI,而人类只是监督。
它为代理提供了一个紧凑、 **结构化** 的页面视图(可寻址的交互元素列表,而不是截图),让它通过 **稳定的 ID** 对这些元素进行操作,告诉它 **每个操作是否实际有效**,并将整个过程流式传输到人类可以监视的 **实时视图**。它是模型无关且可下载的 - 不绑定到某个供应商的扩展。
> **设计原则,无处不在:** _在代码中完成工作,以便模型不必花费令牌和推理能力_ - 验证结果、差异页面、从故障中恢复、查找元素。
> ⚠️ **范围和诚实度。** 这是一个快速、本地、 **单用户开发者工具**,旨在指向您自己的或授权的网站。它很年轻 - 在自己的路径上经过了彻底测试,但没有像成熟的工具那样在数千个真实网站上经过战斗测试。参见 [安全性和范围](#安全性和范围)。
---
## ✨ 亮点
| | |
|---|---|
| 👁️ **结构化感知** | AI 看到一个紧凑的交互元素列表,具有稳定的 ID - 无需截图→视觉往返。 |
| 🎯 **按 ID 操作** | 通过 `e3` 点击/输入/选择,从不通过猜测的 CSS 选择器或像素坐标。 |
| ✅ **验证的操作** | 每个操作返回 *是否成功以及页面是否更改* - 成功 / 静默无效 / 失败,而不是猜测。 |
| 🩹 **自我修复** | 如果元素的 ID 移动(页面重新渲染),它会通过标识重新定位元素并重试。 |
| 🔗 **持久 ID** | 元素在快照中保留其 ID,以便 AI 可以引用它在几步之前看到的内容。 |
| ⚡ **增量感知** | `changes()` 仅返回增量;快照在 DOM 实际更改之前缓存。 |
| 🔎 **`find(description)`** | 询问“搜索框”并仅获取匹配项 - 而不是整个页面转储。 |
| 🐛 **一流调试** | 控制台日志、页面错误和网络请求被捕获 - 错误范围限定为导致它们的动作。 |
| 🖥️ **实时视图** | 在浏览器中观察无头运行 - 刷新截图 + 着色动作跟踪。 |
| 🔌 **MCP + npm** | 一个引擎,两个前端:一个 MCP 服务器(零代码)和一个类型化的 TypeScript 库。 |
---
## 🏗 架构
```mermaid
flowchart TD
AI["🤖 AI 客户端<br/>Claude Desktop · Cursor · 您的代理"]
MCP["<b>mcp.ts</b><br/>MCP 服务器 · 13 个工具"]
LIVE["<b>live.ts</b><br/>实时视图服务器"]
ENGINE["<b>browser.ts</b><br/>AIBrowser / AIPage<br/><i>整个产品</i>"]
CHROME["Chromium<br/>(默认无头)"]
HUMAN["🧑 人类<br/>观察和监督"]
AI -- "JSON-RPC 2.0 / stdio" --> MCP
MCP -- "方法调用" --> ENGINE
ENGINE -- "Chrome DevTools 协议" --> CHROME
ENGINE -- "事件 + 帧" --> LIVE
LIVE -- "截图 + 动作跟踪" --> HUMAN
classDef eng fill:#6E56CF,stroke:#4C3A9E,color:#fff;
classDef srv fill:#1e2a3a,stroke:#89b4fa,color:#cdd6f4;
class ENGINE eng;
class MCP,LIVE srv;
```
**一个引擎,两个前端。** 所有真正的逻辑都位于 `browser.ts` 中。`mcp.ts` 是一个薄适配器,它将引擎的方法公开为协议工具;`live.ts` 是一个只读窗口,供人类使用。同一个引擎可以被封装为 CLI 或 REST API - MCP 只是一个适配器。
---
## 🧠 工作原理
### 感知 → 操作 → 验证
```mermaid
flowchart LR
A["按 ID 操作<br/>(点击 / 输入 / 选择)"] --> B{"元素<br/>找到?"}
B -- 是 --> C["智能等待<br/>+ 操作"]
B -- "否 · ID 移动" --> H["🩹 自我修复:<br/>通过身份重新定位"]
H --> C
C --> D{"效果<br/>验证?"}
D -- 是 --> OK["✅ ActionResult<br/>确定 · 更改?"]
D -- "否 · 错误" --> R{"重试<br/>剩余?"}
R -- 是 --> C
R -- 否 --> F["⚠️ ActionResult<br/>失败 + 修复提示"]
classDef ok fill:#1e3a2e,stroke:#a6e3a1,color:#a6e3a1;
classDef bad fill:#3a1e26,stroke:#f38ba8,color:#f38ba8;
class OK ok;
class F bad;
```
感知运行页面 **内部** 的脚本,收集交互元素,为每个元素赋予 **持久** 的 `data-ai-id`,并捕获角色 / 名称 / 值 / 状态。`MutationObserver` 跟踪 DOM 版本,因此未更改的快照从 **缓存** 提供,并且 `changes()` 可以仅返回 **增量**。
### MCP 对话
```mermaid
sequenceDiagram
participant AI as 🤖 AI 客户端
participant S as mcp.ts (服务器)
participant E as browser.ts (引擎)
AI->>S: 初始化
S-->>AI: 功能
AI->>S: 工具/列表
S-->>AI: 13 个工具 + JSON 模式
Note over AI: 模型现在知道它可以做什么
AI->>S: 工具/调用 · browser_navigate {url}
S->>E: goto() + 快照()
E-->>S: 结构化元素
S-->>AI: 内容:[ 文本 ]
AI->>S: 工具/调用 · browser_click {id}
S->>E: clickById() → 验证 → 修复
E-->>S: ActionResult + 增量
S-->>AI: 内容:[ 文本 ]
```
它是一个 **MCP 服务器**,因为它注册了模式化的工具,并回答 `initialize` / `tools/list` / `tools/call` 作为 JSON-RPC 2.0 via stdio - 浏览器控制只是这些工具恰好执行的操作。
---
## 🚀 快速开始
**先决条件:** Node.js 18+。
```bash
npm install ecobrowser
npx playwright install chromium # 一次性浏览器下载
```
### 选项 A - 作为 MCP 服务器(从 AI 驱动)
**Claude Desktop** - 添加到 `claude_desktop_config.json`:
```json
{
"mcpServers": {
"ecobrowser": {
"command": "npx",
"args": ["-y", "ecobrowser-mcp"],
"env": { "AI_BROWSER_HEADED": "1" }
}
}
}
```
**Claude 代码:
```bash
claude mcp add ecobrowser -- npx -y ecobrowser-mcp
```
重启客户端,然后直接询问:*“导航到 example.com 并列出链接。”*
*(从克隆而不是发布的包工作?直接将客户端指向源:`npx tsx <repo>/src/mcp.ts`.)*
### 选项 B - 作为 TypeScript 库
```ts
import { AIBrowser } from "ecobrowser";
const browser = await AIBrowser.launch({ headless: true });
const page = await browser.newPage();
await page.goto("https://example.com");
const snap = await page.snapshot(); // { url, title, elements: [{ id, tag, role, name, value?, state? }] }
const [search] = await page.find("搜索框");
const result = await page.clickById(snap.elements[0].id);
console.log(result.detail); // "点击 e0 成功(页面已更改)。"
const diff = await page.changes(); // { added, removed, changed, unchanged }
console.log(page.console(), page.network()); // 一流调试
await browser.close();
```
---
## 🧰 MCP 工具
服务器公开 **13 个工具**;MCP 客户端通过 `tools/list` 发现它们(名称 + JSON 模式)。
| 工具 | 功能 |
|---|---|
| `browser_navigate` | 打开 URL,返回结构化快照。 |
| `browser_snapshot` | 当前页面的结构化快照(缓存直到更改)。 |
| `browser_changes` | **仅** 自上次快照以来发生的变化 - 廉价的重新感知。 |
| `browser_find` | 查找匹配描述的交互元素;仅获取匹配项。 |
| `browser_read_text` | 页面的可见文本。 |
| `browser_back` | 返回历史记录。 |
| `browser_click` | 按 ID 点击元素(验证,自我修复);返回增量。 |
| `browser_type` | 在字段中输入 ID(验证值是否生效)。 |
| `browser_console` | 当前页面的控制台日志 + 页面错误。 |
| `browser_network` | 网络响应(状态,方法,URL)。 |
| `browser_evaluate` | 在页面中运行 **表达式**,返回结果。 |
| `browser_extract_links` | 所有链接作为名称/地址对。 |
| `browser_reset` | 丢弃会话;下一个操作重新开始(崩溃恢复)。 |
---
## 📊 比较(衡量)
与 **Playwright MCP** 在同一页面上的逐项比较(`npm run bench`),衡量 **返回给模型的字节** 和工具延迟。
**完整页面快照** - *越小越好*
```
此框架 ███████░░░░░░░░░░░░░░░░░ 41 KB (~10K 个令牌)
Playwright MCP ████████████████████████ 128 KB (~32K 个令牌)
```
**重新感知延迟** - *越小越好*
```
此框架 ▏ 5 毫秒 (缓存命中)
Playwright MCP ████████████████████████ 150 毫秒 (每次重新序列化)
```
**操作后增量重新感知**
```
此框架 ▏ 仅限增量(字节)
Playwright MCP ████████████████████████ 再次完整页面 (无差异基元)
```
> **诚实的缺点。** 这衡量 **感知有效载荷 + 工具延迟**,而不是端到端 LLM 墙上时钟(无实时模型运行)。大小差距的一部分是 *范围* - 我们仅捕获交互元素,而 Playwright MCP 捕获整个可访问性树。而我们比 **Playwright MCP** (包装器)快,**而不是** Playwright(两个工具共用的引擎)- 胜利来自缓存、差异和更精简的格式,这些都是竞争对手可以采用的。
---
## ⚙️ 配置
| 环境变量 | 效果 |
|---|---|
| `AI_BROWSER_HEADED=1` | 显示原生浏览器窗口(默认:无头)。 |
| `AI_BROWSER_LIVE=0` | 禁用实时视图服务器。 |
| `AI_BROWSER_LIVE_PORT=N` | 首选实时视图端口(默认 `7333`,如果忙则跳转到下一个空闲端口)。 |
| `AI_BROWSER_ALLOW_LOCAL=1` | 允许 `file://` / 特权方案导航(默认阻止)。 |
**实时视图:** 当 MCP 服务器启动时,它还会提供一个仅限环回的页面(默认 `http://localhost:7333`)- 刷新截图 + 着色动作跟踪 - 这样您可以观察到无头运行。
---
## 📜 脚本
```bash
npm test # 单元测试(差异、查找、状态、URL 保护)- 无需浏览器
npm run build # 编译可发布的包到 dist/(库 + MCP 二进制文件)
npm run typecheck # 对所有内容(包括开发脚本)执行 tsc --noEmit
npm run demo # 直接驱动引擎(头部;AI_BROWSER_HEADED=0 为无头)
npm run smoke # 将 MCP 服务器作为真正的 MCP 客户端启动并驱动它
npm run live # 启动实时视图并验证其端点
npm run bench # 与 Playwright MCP 对比
npm run mcp # 在 stdio 上运行 MCP 服务器
```
> **基准测试说明:** Playwright MCP 是一个 `devDependency`;使用
> `npx @playwright/mcp install-browser chrome-for-testing` 在 `npm run bench` 之前安装其浏览器。
---
## 🗂 项目布局
```
src/
index.ts # 公共包入口 - 重新导出引擎 + LiveView
browser.ts # 核心引擎 - AIBrowser / AIPage(这是整个产品)
mcp.ts # MCP 服务器:注册引擎的方法为 13 个工具(ecobrowser-mcp 二进制文件)
live.ts # 实时视图服务器(截图 + 动作跟踪)
demo.ts # 引擎演示(5 个部分,包括自我修复)
mcp-smoke.ts # 端到端 MCP 客户端测试
live-smoke.ts # 实时视图端点测试
bench-h2h.ts # 与 Playwright MCP 的逐项基准测试
test.ts # 纯逻辑单元测试
tsconfig.build.json # 构建配置 - 仅编译公共接口到 dist/
SPEC.md # 完整技术规范、北极星、路线图
```
只有 `dist/` (以及 README、SPEC、LICENSE)被发布到 npm 压缩包中 - 开发脚本保留在仓库中。
---
## 🔒 安全性和范围
由于它是一个 **您自己运行的可下载工具**,因此如何使用它取决于您的责任。内置防护:
- **仅限环回的实时视图** - 绝不暴露给 LAN;跟踪以 XSS 安全的方式渲染(`textContent`,而非 `innerHTML`)。
- **导航保护** - 默认阻止 `file://` 、 `chrome://` 、 `javascript:` 和其他特权方案(`AI_BROWSER_ALLOW_LOCAL=1` 以选择加入)。
- **有界限和可恢复** - 限额日志、每个工具的超时、自动崩溃恢复、正常关闭、端口回退。
**不属于** 范围:多租户托管、用户之间的身份验证/会话隔离或沙盒 `browser_evaluate` (在页面中运行任意 JS - 仅适用于您信任的站点)。指向您自己的或授权的站点。
---
## 🗺 路线图
```mermaid
flowchart LR
M0["M0 · 原型"] --> M1["M1 · 引擎"] --> REL["可靠性<br/>+ 自我修复"] --> M3["M3 · MCP"] --> M4["M4 · 速度"] --> M5["M5 · 实时视图"] --> AIF["AI 友好性"] --> HARD["强化"] --> M2["M2 · npm<br/>包"] --> M6["M6 · 认证/代理<br/>(BYO) 📦 下一步"]
classDef done fill:#1e3a2e,stroke:#a6e3a1,color:#a6e3a1;
classDef next fill:#3a2e1e,stroke:#f9e2af,color:#f9e2af;
class M0,M1,REL,M3,M4,M5,AIF,HARD,M2 done;
class M6 next;
```
已构建和测试:引擎、可靠性 + 自我修复、MCP 服务器、缓存 + 差异感知、实时视图、AI 友好性、强化和 npm 包(`ecobrowser`,带有 `ecobrowser-mcp` 二进制文件)。
**下一步 - M6:** 有限、BYO 密钥身份验证/代理/CAPTCHA,用于授权站点。
参见 [`SPEC.md`](./SPEC.md) 了解完整的规格和北极星。
---
<div align="center">
<sub>构建为 AI 优先的浏览器层 - AI 在网络上的手和眼睛。</sub>
</div>