内容
<div align="center">
# 🪿 goshawk
**浏览器在代理手中。9 种工具。每个操作一个判决。零猜测。**
导航、读取、点击、填写、登录、抓取。纯 Go 语言,单个二进制文件,无 Node.js,无 Python,无 Docker。
基于 Chrome DevTools Protocol + MCP 构建。与 Claude Code、Cursor、OpenCode、Pi 等任何支持 MCP 的工具配合使用。
[](https://go.dev)
[](LICENSE)
[](CHANGELOG.md)
[](https://github.com/dondai1234/goshawk/stargazers)
```bash
go install github.com/dondai1234/goshawk/v4/cmd/goshawk@latest
```
[安装](#-安装) · [9 种工具](#-9-工具) · [自我诊断判决](#-自我诊断判决) · [比较](#-比较) · [令牌成本](#-令牌成本) · [goshawk 不能做的事情](#-goshawk-不能做的事情)
</div>
<br>
## 为什么选择 goshawk
大多数浏览器 MCP 服务器给代理一个原始的页面快照,让它自己判断发生了什么。代理会花费 3 到 5 次调用进行调查:*点击是否成功?页面是否空白?出了什么问题?* goshawk 弥补了这一缺陷。
- 🔬 **自我诊断判决**:每个操作返回一个带有置信度的判决。当事情出错时,判决会解释原因并给出下一步的建议。“您是否想输入 Sign in?”当您输入“Sgn in”时。“错误可见:Email is required. 修复并重试”当表单失败时。无需额外的工具调用,无需 LLM 参与,纯粹的启发式方法。
- 🪶 **9 种工具,约 3.4K 令牌**:密集的 a11y-tree 快照(参考行,而不是 aria 转储),意图优先的操作,每个调用一个判决。比通常的 6K+ 令牌的工具具有更多功能。
- 🦅 **意图优先**:`act intent="Sign in"` 查找按钮。`act fields={"Username":"john","Password":"hunter2"}` 填写整个表单。命名您想要的内容,而不是如何找到它。
- 🛡️ **自我修复引用**:来自 `see`/`find` 的引用在重新渲染时存活。当 React 重新创建具有相同角色+名称的节点时,goshawk 会自动修复引用。不会出现 stale-selector 失败。
- 🍪 **自动关闭 cookie 横幅**:每次导航时。自动恢复同意重定向。a11y 树返回干净,不会因“接受 cookie”叠加层而混乱。
- 📄 **空白页面检测**:当页面加载为空(慢速 SPA、速率限制、JS 未初始化)时,判决会显示 `BLANK PAGE` 并给出尝试方法。一次调用,而不是五次。
- 🔐 **一次性登录**:`login username= password=` 处理单步和多步,验证结果状态,检测 2FA、SSO 重定向、记住我、忘记密码。报告状态,而不是 HTTP 状态。
- 🎭 **命名配置文件**:隔离的 cookie、身份验证、存储。一次调用切换身份。登录在重启时存活,配置文件持久存在。
- 🦿 **单个 Go 二进制文件**:14 MB。无需 Node.js 运行时,无需 Python 虚拟环境,无需 Docker。`go install` 即可。
> goshawk 是为代理设计的。您只需安装一次;代理通过 9 种工具驱动浏览器。
---
## 🧰 9 种工具
| 工具 | 简介 |
|------|-----------|
| `nav` | 导航到 URL 并获取页面类型、身份验证、主要操作和引用的方向。自动关闭 cookie 横幅,检测 CHALLENGE 和 BLANK PAGE。`waitSelector=` 用于慢速 SPA。 |
| `see` | 检查当前页面。级别:简要、引用、文本、轮廓(CSS 选择器用于 js)、完整、截图。 |
| `act` | 交互:点击、填写、选择、悬停、按键、上传或批量表单填写(`fields={}`)。返回自我诊断判决。不要在操作后重新检查。 |
| `js` | 运行 JavaScript,获取干净的 JSON。辅助函数:`$(sel)`、`text(x)`、`table(sel)`、`links(sel)`、`wait(fn,ms)` 等。 |
| `find` | 定位元素:`role=`/`text=` 过滤 a11y 树,`selector="css"` 直接查询 DOM。 |
| `tabs` | 列出、切换、关闭、标记标签页。 |
| `history` | 会话操作日志。`errors=true` 用于失败,`last=N` 用于最近步骤。 |
| `session` | `reset`(重新启动),`clear`(清除 cookie+存储),`profile`(命名身份:创建/切换/导出/导入)。 |
| `login` | 一次性登录。检测字段,填写,提交,验证状态。处理多步。报告:已登录 / 2FA / CHALLENGE / 错误 / SSO。 |
---
## 🔬 自我诊断判决
goshawk 的特色功能。三个层次,无需额外的工具调用:
**层次 1:“您是否想输入?”**
当 `act intent="Sgn in"` 找不到确切匹配时,goshawk 返回 3 个最接近的匹配,基于 Levenshtein 距离:
```
未找到名为“Sgn in”的元素;您是否想输入:“Sign in”(按钮,r4)、“Sign in to GitHub”(标题,r2)?
```
代理重试正确的名称。无需 `see` + `find` + `see` 调查循环。
**层次 2:“是什么阻止了它?”**
当操作触发但置信度不确定或可能时,goshawk 扫描页面查找可见的错误消息、HTML5 验证失败和阻止的模态窗口:
```
判决:[不确定] 无明显效果
错误可见:”Email is required”。修复这些字段并重试
模态窗口“Login Required” 打开 - 调用 see 检查
```
**层次 3:“接下来是什么?”**
每个诊断都是一个可行的建议,而不是简单的描述。代理确切地知道下一步该怎么做,无需额外的调用。
纯粹的启发式方法。无需 LLM 参与。无需额外的 API 调用。在 React、Vue、Angular、原生 JavaScript 中均有效。
---
## 🎯 置信度评分的判决
每个 `act` 返回一个带有置信度标签的判决:
| 标签 | 含义 | 何时 |
|-----|---------|------|
| `[confirmed]` | DOM 更改或 XHR 2xx 发出 | 操作肯定有效 |
| `[likely]` | 内容移动或 XHR 发出 | 某些事情发生了,需要验证 |
| `[uncertain]` | 无明显效果 | 使用 `see` 或诊断检查 |
导航始终是确认的。机器人挑战始终是不确定的。无需再猜测点击是否成功。
---
## 📝 批量表单填写
一次填写整个表单:
```
act fields={"Username":"john","Password":"hunter2","Remember me":"true","Country":"United States"}
```
每个标签解析为一个表单字段(a11y 名称 + DOM 备用)。类型自动检测:文本、复选框、单选按钮、选择、滑块、文件。为每个字段执行正确的操作。一次重新快照,报告验证错误。
---
## 🔐 一次性登录
```
login username="john" password="hunter2" url="https://example.com/login"
```
检测用户名 + 密码 + 提交字段,填写它们,提交,并验证结果状态。处理:
- 单步(一个页面上的用户名 + 密码)
- 多步(用户名首先出现,然后出现密码)
- 2FA(停止并报告需要什么)
- SSO 重定向(报告域名)
- 记住我复选框(报告,不会自动切换)
- 忘记密码链接(报告)
- OAuth 按钮(报告,不会自动点击)
验证状态,而不是 HTTP 状态。报告静默失败,而不是隐藏。
---
## 🛡️ 自我修复引用
来自 `see` 和 `find` 的引用在重新渲染时保持稳定。当框架重新创建具有相同角色 + 名称的 DOM 节点时(React 键更改,Vue v-if 切换),goshawk 搜索当前树并自动修复引用。不会出现 stale-selector 失败。
引用是每个标签页的,导航时清除。在页面内重新渲染时存活。
---
## 🍪 Cookie 横幅和同意重定向
每次导航时自动关闭 cookie/同意横幅。a11y 树返回干净,不会因叠加层元素而混乱。
如果站点重定向到全页同意声明(适用于欧盟用户),goshawk 会检测重定向,尝试更广泛的关闭,并重新导航到原始 URL。如果无法恢复,判决会显示 `CONSENT REDIRECT: original -> current` 以及尝试方法。
---
## 📄 空白页面检测
当页面加载但渲染为空(慢速 SPA 水合、速率限制、JS 错误)时,goshawk 会检测并清楚地报告:
```
BLANK PAGE: 未检测到交互元素或标题。
页面可能是仍在加载的慢速 SPA,可能需要 JS 执行,
或可能存在渲染问题。使用 js 检查或稍后查看。
```
之前:代理看到 `interactive: 0`,调用 `see`,然后 `find`,然后 `see full`,然后 `js`。4 到 5 次调用浪费了。之后:一次调用,判决解释了发生了什么。
`waitSelector=` 在 `nav` 上为慢速 SPA 提供原生 waitForSelector:等待 `#dashboard` 渲染后再返回方向。
---
## 🎭 命名配置文件
隔离的浏览器身份。不同的登录、cookie、存储。一次调用切换身份。
```
session mode=profile action=create name="work"
session mode=profile action=switch name="work"
session mode=profile action=list
session mode=profile action=export # 以 JSON 导出 cookie+存储
session mode=profile action=import data="..." # 从 JSON 恢复
```
默认情况下,goshawk 持久化到 `<os config dir>/goshawk`,因此登录和 cookie 在服务器重启时存活。代理不需要每次运行都重新登录。使用 `--no-persist` 进行临时会话。
---
## 🚀 安装
```bash
go install github.com/dondai1234/goshawk/v4/cmd/goshawk@latest
```
然后添加到您的 MCP 客户端配置中:
```json
{
"mcpServers": {
"goshawk": {
"command": "goshawk",
"args": ["mcp"]
}
}
}
```
需要安装 Chrome 或 Chromium。goshawk 通过 CDP 连接。
<details>
<summary><b>CLI 标志</b></summary>
| 标志 | 默认值 | 目的 |
|------|---------|---------|
| `--headless` | `true` | `--headless=false` 用于真实 GPU 指纹(硬防 bot) |
| `--user-data-dir` | `<config>/goshawk` | 持久化配置文件目录。登录在重启时存活。 |
| `--no-persist` | `false` | 临时配置文件 |
| `--proxy-server` | 无 | 代理 URL。住宅代理修复大多数 IP 声誉阻止。 |
| `--user-agent` | Chrome 默认 | 重写 User-Agent |
| `--viewport` | `1366,768` | 窗口大小 W,H |
| `--no-stealth` | `false` | 禁用反检测补丁 |
| `--no-cookie-dismiss` | `false` | 禁用 cookie 横幅自动关闭 |
| `--no-eval` | `false` | 禁用 `js` 工具 |
| `--op-timeout` | `20s` | 每个操作超时 |
| `--idle-timeout` | `10m` | 空闲后自动关闭 Chrome |
| `--allow-insecure-schemes` | `false` | 允许 `file://`、`data:` 等 |
</details>
---
## 📊 比较
| | **goshawk** | Playwright MCP | Browser-use | Puppeteer MCP |
|---|---|---|---|---|
| **语言** | Go(单个二进制文件) | Node.js | Python | Node.js |
| **工具** | 9 | 17+ | 变化 | 10+ |
| **令牌成本** | ~3.4K | ~6K+ | 变化 | ~5K+ |
| **自我诊断判决** | 是 | 否 | 否(使用 LLM) | 否 |
| **置信度评分** | 是 | 否 | 否 | 否 |
| **批量表单填写** | 是(`fields=`) | 否 | 否 | 否 |
| **命名配置文件** | 是 | 否 | 否 | 否 |
| **自我修复引用** | 是 | 否 | 否 | 否 |
| **cookie 横幅自动关闭** | 是 | 否 | 否 | 否 |
| **空白页面检测** | 是 | 否 | 否 | 否 |
| **一次性登录** | 是 | 否 | 否 | 否 |
| **意图优先操作** | 是 | 否(选择器) | 是(LLM) | 否(选择器) |
| **每次调用 LLM** | 否 | 否 | 是 | 否 |
| **运行时依赖** | 仅 Chrome | Node + Playwright | Python + Playwright | Node + Puppeteer |
---
## 🪙 令牌成本
大多数浏览器 MCP 服务器的成本为 5 到 8K 令牌。goshawk 的 9 种工具成本为 **~3.4K 令牌**,在 `tools/list` 处测量(来自实时 MCP JSON 响应,13623 个字符)。连接时间的 `instructions`(~66 令牌)在握手时一次性注入,不会每次都重复。
典型页面的 `nav` 方向返回 ~60 到 80 个令牌。具有 10 个交互元素的页面的 `see refs` 返回 ~40 个令牌。设计紧凑:参考行,而不是 aria 转储。
---
## 🔧 首次了解
| 事物 | 需要了解 |
|---|---|
| **必须安装 Chrome** | goshawk 通过 CDP 连接到 Chrome/Chromium。没有 Chrome,就没有浏览器。 |
| **每个进程一个配置文件** | Chrome 锁定配置文件目录。使用单独的 `--user-data-dir` 路径运行并发客户端。 |
| **20 秒操作超时** | 如果页面在 20 秒内未加载,则认为已死。提高 `--op-timeout` 以适应已知的慢速目标。 |
| **无头模式可能会触发 bot 检测** | 使用 `--headless=false` 以防站点具有激进的反 bot 措施。住宅代理( `--proxy-server` )是 IP 阻止的 #1 修复方法。 |
| **`js` 工具可以禁用** | 启动时使用 `--no-eval` 阻止任意页面 JS。其他 8 种工具仍然有效。 |
---
## 🚧 goshawk 不能做的事情
| 限制 | 发生的情况 |
|-------|----------------------|
| **硬 CAPTCHAs**(Turnstile,hCaptcha) | 在判决中报告为 `CHALLENGE`。代理知道停止,而不是盲目重试。 |
| **Shadow DOM 穿透** | `js` 使用 `$(sel)` 访问开放的 shadow 根。封闭的 shadow 根需要 `selector=` 在 `act` 或 `find` 上。 |
| **Iframe 访问** | 同源 iframe 可访问。跨源 iframe 被浏览器安全阻止。 |
| **无头模式下无截图** | `see shot` 捕获页面,但某些站点在无头模式下渲染不同。使用 `--headless=false` 以实现视觉保真度。 |
| **速率限制站点** | HN、Reddit 等站点在大量无头使用时提供“抱歉”页面。BLANK PAGE 判决会捕获此情况。 |
<div align="center">
### 如果 goshawk 为您节省了调用次数,请给仓库加星:它可以帮助其他人找到它。
[](https://github.com/dondai1234/goshawk/stargazers)
**MIT** · [更新日志](CHANGELOG.md) · [问题](https://github.com/dondai1234/goshawk/issues)
</div>