内容
<h1 align="center">VZT-Browser</h1>
<p align="center">
<b>一个侧边类浏览器代理 — MCP · CLI · REPL — 其中的空白被填补。</b><br>
跨越您实际登录的网站。秘密从未触及模型。除非您允许,否则不会发生任何变化。
</p>
<p align="center">
<a href="#安装">安装</a> ·
<a href="#快速开始">快速开始</a> ·
<a href="#三个界面">界面</a> ·
<a href="#工具参考-48">工具</a> ·
<a href="#安全性模型">安全性</a> ·
<a href="#工作原理">工作原理</a>
</p>
---
## 关于
**VZT-Browser 为 AI 代理提供了一个真正的浏览器,该浏览器已登录到您的帐户** — Gmail、GitHub、您的 CI、仪表板、暂存、内部管理工具 — 并允许它在那里执行有用的工作:收集审查证据、填写表单、运行流程、验证声明并记住它所学到的内容。
它是一个开放的、可自我托管的 [Aside](https://aside.com) 替代品。Aside 是一个封闭的 macOS 应用程序,没有开放的 API,没有审批门槛,也没有审计跟踪。VZT-Browser 与 Aside 的整个公开界面相匹配 — **CLI、MCP 和 REPL,用于私有浏览器证据** — 作为一个开放的工具,任何模型或应用程序都可以驱动,并且在关键地方进一步扩展:
- **秘密从不进入模型的上下文。** 凭证存储在 macOS 钥匙串中;VZT-Browser 将它们输入到页面中,并仅返回成功/失败。
- **“不更改任何内容”被强制执行,而不是被请求。** 只读 *证据模式* 在工具层硬阻止突变。
- **所有内容都是可审计的。** JSONL 日志记录每次凭证访问和审批决定。
- **自带模型。** MCP 客户端模型针对可访问性快照进行推理 — 无需服务器端 API 密钥即可进行核心操作,无使用积分。
构建于 [`playwright-core`](https://playwright.dev)。macOS优先(钥匙串保险库,对话框回退);浏览器自动化本身是跨平台的。
---
## 为什么
| 您想要的 | Aside | VZT-Browser |
|---|---|---|
| 在您登录的网站上工作 | ✅ | ✅ 持久 Chrome 配置文件 (`launchPersistentContext`) |
| 本地 Markdown 内存(“梦想”) | ✅ | ✅ 按站点 **和** 跨任务,自动注入,可编辑 |
| 代理密码管理器 | ✅ | ✅ macOS 钥匙串 — **模型上下文中没有秘密** |
| CLI · MCP · REPL | ✅ | ✅ 这三个,共享相同的稳定元素引用 |
| 敏感操作前审批 | *隐含* | ✅ **强制执行** (MCP 诱导 → macOS 对话框) |
| 保证“不更改” | 请求模型 | ✅ **硬只读模式** 在工具层 |
| 审计跟踪 | ❌ | ✅ 每个凭证访问 + 审批的 JSONL |
| 调度/循环运行 | ❌ | ✅ 记录 → 确定性重放;监控直到阈值 |
| 开放 API / 可组合 | ❌ 封闭应用 | ✅ MCP 服务器 + CLI,自带模型,可自我托管 |
| 浏览历史回忆 | ✅ | ✅ 读取配置文件中的真实 Chrome 历史记录 (`node:sqlite`) |
---
## 安装
需要 **Node ≥ 20** (≥ 22.5 用于浏览历史记录回忆)和 **Google Chrome** (回退到 `CHROMIUM_PATH` 或 Playwright 的捆绑 Chromium)。
> **尚未在 npm 上。** 直接从 GitHub 安装 — `prepare` 脚本在安装时自动构建包,因此下面的 `github:` 表单今天起作用。`@vzt-protocol/vzt-browser` 名称将在发布后生效。
### 作为 MCP 服务器
将以下内容添加到您的 MCP 客户端配置文件(`.mcp.json`、`claude_desktop_config.json`、Cursor 等)中:
```jsonc
{
"mcpServers": {
"vzt-browser": {
"command": "npx",
"args": ["-y", "github:vonzelle-vzt/vzt-browser"],
"env": { "VZT_BROWSER_APPROVAL": "auto" }
}
}
}
```
### 作为依赖项/全局 CLI
```bash
# 进入项目
npm install github:vonzelle-vzt/vzt-browser
# 或全局安装,以获取 vzt-browser / vzt-browser-cli / vzt-browser-vault 二进制文件
npm install -g github:vonzelle-vzt/vzt-browser
vzt-browser-cli --help
```
### 从源代码
```bash
git clone https://github.com/vonzelle-vzt/vzt-browser.git
cd vzt-browser
npm install # 自动运行构建(准备脚本)
# MCP 服务器: node dist/index.js
# CLI: node dist/cli.js --help (或:npm link → vzt-browser-cli)
```
所有状态都存储在 `~/.vzt/browser/` 下(覆盖 `VZT_BROWSER_HOME`)。
---
## 快速开始
```
1. 登录一次 login_mode({ url: "https://github.com/login" }) → 手动登录 → session_stop
2. 自动执行 session_start() → 快照 → 点击 / 填写 → 获取文本
3. 存储秘密 npx vzt-browser-vault add github-password (隐藏输入;模型从未看到)
4. 使用它 fill_credential({ name: "github-password", selector: "#password", pressEnter: true })
5. 教它 save_site_memory(...) → 自动注入下次访问
6. 记录 + 重放 record_save({ task: "..." }) → replay_task({ task: "..." }) (无 LLM 重放)
```
登录在配置文件中永久保持(cookie + localStorage),因此步骤 2 及以后可以完全无头运行。
---
## 三个界面
### MCP — 面向您的编码代理
48 种工具,您的代理无需离开编辑器即可调用。代理使用 `snapshot` 读取页面(可访问性树 + 稳定 `[ref=vN]` 句柄)并使用 `click` / `fill` / `fill_credential` 等进行操作。
### CLI — 开发工作流中的浏览器检查
```bash
vzt-browser-cli open https://example.com # → 标题/网址
vzt-browser-cli snapshot # aria 树 + 稳定引用
vzt-browser-cli text ".pricing" # 选择器的可读文本
vzt-browser-cli shot out.jpg --full # 全页截图
vzt-browser-cli eval "getComputedStyle(document.querySelector('.card')).transition"
vzt-browser-cli evidence https://ci.example.com/run/74288420 \
--template ci-triage --title "PR #482 CI" --readonly
vzt-browser-cli monitor https://status.example.com --text-appears "Incident" --every 30000 --for 900000
vzt-browser-cli login https://github.com/login # 有头,一次登录
vzt-browser-cli repl https://example.com # 交互式 REPL
```
全局标志:`--profile <name>` (默认 `default`),`--headed`,`--readonly`,`--keep` (保持浏览器打开)。
### REPL — 确定性类似 Playwright 的检查
```
$ vzt-browser-cli repl https://example.com
vzt> await snap() // aria 树 + [ref=vN] 列表
vzt> await ref('v3').click() // 您在 snap() 中看到的精确元素
vzt> await $('h1').textContent() // 原始 Playwright 定位器
vzt> await shot() // 截图到文件
vzt> tabs(); net({ failuresOnly:true }); errors(); downloads()
vzt> await evidence('quick look') // 构建证据包
```
`snap()` 中的引用是 **相同** 的,代理和 MCP `snapshot` 使用的引用,因此您在 REPL 中点击的内容是代理将操作的内容。
---
## 签名工作流
### 审查证据(永远不会更改任何内容)
`collect_evidence` 打开私人页面(CI 运行、PR、Sentry、功能标志仪表板、暂存)并生成一个 **可审查的包** — 全页截图、捕获的 **日志链接** (失败的网络请求)、控制台错误、下载的文件和一个为作业搭建的 Markdown **笔记** 模板:`ci-triage`、`pr-packet`、`qa`、`flag-audit`、`incident`、`generic`。
将其与只读会话 (`readOnly: true`、`VZT_BROWSER_READONLY=true` 或 CLI `--readonly`)配对,以获得一个硬保证:填充、选择和更改状态的点击在工具层被阻止;导航、截图、`eval_js` 和监控仍然有效。
### 研究与声明漂移
基于模式,与 Aside 类似 — 在浏览之前声明字段,然后比较运行:
- `research_define_table` — 模式(默认:`claim, sourceUrl, publisher, dateAccessed, screenshot, status, oldClaim`)。重新定义相同的名称以保留行 + 基线,以便每周运行与相同的模式进行比较。
- `research_capture_source` — 打开只读源,截图,返回页面文本/快照,以便 **您** 提取字段。
- `research_upsert_row` — 存储提取的行并附带状态(`verified` / `changed` / `missing` / `needs-review`)。
- `research_diff` — **漂移报告**:更改 / 缺失 / 新声明与上次运行的比较(例如 *"免费计划包含 10 个席位" → "5 个席位"*)。`promote:true` 设置新的基线。
- `research_export` — CSV 或 Markdown。
### 持续学习的记忆
- **站点记忆** (`save_site_memory`) — 站点的工作路径;下次访问时自动注入。
- **梦想** (`remember`) — 跨任务人员/公司/决策 → `~/.vzt/browser/memory/_workspace.md`,在每次 `session_start` 时自动注入。
- **历史回忆** (`search_history`) — 查询此配置文件的真实 Chrome 历史记录(“找到我昨天打开的页面”);使用 `navigate` 重新打开。
- **可检查** (`show_memory`) — 每个记忆文件都是磁盘上的纯 Markdown。打开它,编辑它,删除错误的行。
---
## 工具参考(48)
| 组 | 工具 |
|---|---|
| **会话** | `session_start` (`readOnly`,`headed`,`video`),`session_stop`,`login_mode` |
| **导航/读取** | `navigate`,`snapshot` (aria 树 + 稳定 `[ref=vN]`),`screenshot`,`get_text` |
| **操作** | `click`,`fill`,`fill_credential`,`press_key`,`select_option`,`wait_for`,`hover` |
| **检查** | `set_viewport` (桌面/平板/移动),`list_tabs`,`new_tab`,`switch_tab`,`eval_js`,`read_console`,`read_network`,`list_downloads` |
| **证据** | `collect_evidence`,`monitor_page` |
| **研究/漂移** | `research_define_table`,`research_capture_source`,`research_upsert_row`,`research_diff`,`research_export`,`research_list_tables`,`research_get_table`,`research_delete_table` |
| **记忆** | `save_site_memory`,`list_site_memory`,`get_site_memory`,`delete_site_memory`,`remember`,`show_memory`,`search_history` |
| **保险库** | `vault_add`,`vault_list`,`vault_delete` |
| **记录/重放** | `record_save`,`task_list`,`task_delete`,`replay_task` |
| **审查** | `session_gif`,`audit_log_path` |
### CLI 二进制文件
| 二进制文件 | 目的 |
|---|---|
| `vzt-browser` | MCP stdio 服务器 |
| `vzt-browser-cli` | CLI + REPL |
| `vzt-browser-vault` | 从终端存储/列出/删除凭证(隐藏输入) |
---
## 安全模型
- **秘密永远不会到达模型。** `fill_credential` 从 Keychain 服务器读取,通过键盘输入,并仅返回 `{ filled: true }`。错误会清除秘密。`fill` 拒绝 `type=password` 字段。
- **强制审批。** 将敏感操作分类 — 检出/支付/删除 URL、购买/支付/删除按钮名称、始终询问域名或新域名上的首次凭证使用 — 通过 MCP 诱导暂停,并回退到 macOS 对话框。`VZT_BROWSER_APPROVAL=off` 禁用门控(例如受信任的 cron 重放)。
- **只读证据模式。** `readOnly: true` 完全阻止填充、选择和更改状态的点击 — 真正的“不更改”保证,用于审查和监控任务。
- **所有内容都是可审计的。** `~/.vzt/browser/audit.log` (JSONL)记录每次保险库访问和审批决定 — 仅凭证 **名称**,而非值。
- **记录轨迹。** 每个会话写入每个操作的一张 JPEG 截图 + `actions.jsonl`;`session_gif` 组装审查 GIF(需要 `ffmpeg`)。
---
## 配置
### `~/.vzt/browser/config.json`
```json
{
"alwaysAskDomains": ["your-bank.com", "stripe.com"],
"sensitiveKeywords": ["取消订阅", "授予访问权限"]
}
```
### 环境变量
| 变量 | 默认值 | 目的 |
|---|---|---|
| `VZT_BROWSER_HOME` | `~/.vzt/browser` | 数据根目录(配置文件、内存、任务、会话、保险库索引、审计日志) |
| `VZT_BROWSER_APPROVAL` | `auto` | `auto` (诱导 → 对话框)\| `off` |
| `VZT_BROWSER_READONLY` | `false` | `true` = 证据模式:硬阻止突变 |
| `CHROMIUM_PATH` | — | 如果未找到 `chrome` 通道,则使用 Chrome 二进制文件 |
### 数据布局
```
~/.vzt/browser/
├── profiles/<name>/ 持久的 Chrome 用户数据目录(您的登录)
├── memory/<domain>.md 按站点记忆(“梦想”)
├── memory/_workspace.md 跨任务记忆
├── tasks/<slug>.json 已记录、可重放的任务
├── sessions/<id>/ 截图轨迹 + actions.jsonl (+ 证据、下载)
├── research/<name>.json 基于模式的证据表
├── vault-index.json 凭证 **名称** + 注释(永远不会是秘密值)
├── audit.log JSONL 审计轨迹
└── config.json 始终询问域名,额外的敏感关键词
```
---
## 工作原理
- **引擎:** 直接使用 `playwright-core`。MCP 客户端的模型根据可访问性快照进行推理 — 无需服务器端 LLM 密钥即可进行核心操作。
- **持久化配置文件:** 在专用配置文件上使用 `launchPersistentContext`,带有 PID 锁文件(每个配置文件一个活动上下文)。您的日常 Chrome 不受影响。
- **稳定引用:** `playwright-core` 不公开引用引擎,因此 VZT-Browser 注入自己的 `data-vzt-ref` 属性;`snapshot.refs` 列出它们,而 `[data-vzt-ref="vN"]` 解析它们 — 在快照、点击和 REPL 中相同。导航时引用重置。
- **保险库:** 通过 `security` CLI 使用 macOS 钥匙串(参数通过 `execFile` 传递,从不 shell-interpolated)。`vault_add` 通过有头的本地表单或 `vzt-browser-vault` 终端工具捕获秘密。
- **重放:** 记录器记录每个突变操作,并使用稳定的选择器;`replay_task` 确定性地运行步骤,并在漂移(选择器不再唯一匹配,或可访问的名称更改)时停止并返回失败点 + 快照,以便代理可以完成并重新保存。
- **历史回忆:** 读取配置文件的 Chrome `History` SQLite 数据库的副本,使用 Node 的内置 `node:sqlite`,转换 Chrome 的 1601-epoch 微秒时间戳。
---
## 路线图
LLM 自动蒸馏“梦想” · TOTP 凭证 · 独立 cron 运行器 · Stagehand 驱动的漂移自愈 · Browserbase 传输,用于云扩展 · Linux `secret-tool` 保险库后端 · 发布到 npm。
---
## 许可证
[MIT](./LICENSE) © Vonzelle Brown / VZT Tech Consulting