dsh 的真实浏览器自动化:基于 Playwright 的 MCP 服务,提供导航、点击、填写、输入、截图与带编号引用的无障碍快照操作,22 个 web_* 工具经 stdio 接入 Agent。
安装
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:JohnXu22786/browser-automation
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本。请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
Web Bridge — 浏览器自动化 MCP server(dsh 插件)
Web Bridge 是一个使用真实浏览器的自动化 MCP server。它让 agent 拥有浏览器的眼睛和手:打开网页、读取页面结构、点击、填表、截图、执行脚本。核心机制是无障碍树快照——把页面渲染成结构化文本树并给可交互元素编号,agent 无需视觉模型即可精确操作页面。
- 语言:TypeScript(Node.js ≥ 20),通过 MCP 协议(stdio 传输)通信
- 浏览器引擎:Chromium / Firefox / WebKit(默认 Chromium)
- 工具数量:22 个,全部以
web_前缀命名
功能特性
- 快照驱动:
web_snapshot生成带引用编号(ref)的无障碍树,元素可被精确点击/填写,无需猜测选择器 - 真实交互:点击、双击、右键、组合键、填表、下拉选择、悬停、滚动、键盘输入
- 视觉能力:视口/整页/元素截图(PNG/JPEG),可返回给调用方或保存到本地
- 脚本执行:在页面上下文执行 JS,结果自动净化(循环引用、BigInt、NaN 等安全转换)
- 多标签页:新建、列出、切换、关闭标签页,弹窗自动接管
- 细粒度等待:按加载状态 / 元素状态 / URL 匹配 / 固定时长等待
- 会话管理:浏览器懒启动、
web_shutdown释放资源、断开连接自动清理
安装
npm install # 安装依赖
npm run build # 编译到 dist/
npx playwright install chromium # 安装浏览器引擎(首次使用必需)
也支持 firefox / webkit 引擎:
npx playwright install firefox,并通过配置切换。
快速开始
方式一:通用 MCP 客户端(stdio)
{
"mcpServers": {
"web-bridge": {
"command": "node",
"args": ["D:/path/to/browser-automation/dist/index.js"]
}
}
}
方式二:命令行验证
node dist/index.js --help # 查看用法
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}' | node dist/index.js
方式三:dsh 插件化加载(见下节)
在 DSH 中安装
dsh plugin --profile demo add github:JohnXu22786/browser-automation
将本插件以 github:JohnXu22786/browser-automation 加入 dsh 的 demo profile。授权、加载与生命周期细节见下节「dsh 插件接入说明」。
dsh 插件接入说明
本插件遵循 dsh「一切皆是插件」的约定,通过根目录的 dsh-plugin.json 清单描述自身:
| 字段 | 值 | 含义 |
|---|---|---|
id |
dsh.web-bridge |
插件唯一标识 |
kind |
mcp-server |
插件类型:提供 MCP 工具集 |
entry |
dist/index.js |
入口文件(node dist/index.js 直接运行) |
transport |
stdio |
传输方式:MCP 客户端通过标准输入输出与插件通信 |
config.envPrefix |
WEB_BRIDGE_ |
插件配置通过该前缀的环境变量注入 |
tools |
22 项 | 插件暴露的工具清单(名称 + 标题) |
harness 加载流程(dsh 运行时按以下步骤接入):
- 扫描插件目录,读取
dsh-plugin.json,校验kind/entry/runtime; - 检查 Node 版本满足
runtime.minVersion; - 以
spawn('node', [entry])拉起插件进程,stdin/stdout 接 MCP 协议(JSON-RPC 2.0,换行分隔); - 依据
config.envPrefix把 harness 配置映射为环境变量注入子进程(例如actionTimeout→WEB_BRIDGE_ACTION_TIMEOUT); - MCP 客户端握手(initialize / notifications/initialized / tools/list)后,
tools清单中的工具自动进入 agent 的工具集,每个工具的 schema 与权限说明由插件在tools/list响应中提供; - 会话结束或进程退出时,harness 关闭 stdin,插件自动回收浏览器并退出(见「生命周期」)。
任何标准的 MCP 客户端(不支持 manifest 的)也可直接按「方式一」接入。
配置
优先级:默认值 < 配置文件(--config 或 WEB_BRIDGE_CONFIG)< 环境变量。
环境变量(前缀 WEB_BRIDGE_)
| 变量 | 默认 | 说明 |
|---|---|---|
WEB_BRIDGE_BROWSER |
chromium |
引擎:chromium / firefox / webkit |
WEB_BRIDGE_HEADLESS |
true |
无头模式 |
WEB_BRIDGE_VIEWPORT |
1280x720 |
视口尺寸,如 1440x900 |
WEB_BRIDGE_EXECUTABLE |
— | 自定义浏览器可执行文件路径 |
WEB_BRIDGE_USER_DATA_DIR |
— | 用户数据目录(持久化上下文,登录态跨会话保留) |
WEB_BRIDGE_PROXY |
— | 代理地址,如 http://proxy:3128 |
WEB_BRIDGE_LOCALE / WEB_BRIDGE_TIMEZONE |
— | 区域与浏览器时区 |
WEB_BRIDGE_USER_AGENT |
— | 自定义 User-Agent |
WEB_BRIDGE_IGNORE_HTTPS_ERRORS |
false |
忽略证书错误(仅调试) |
WEB_BRIDGE_SANDBOX |
true |
浏览器沙箱;容器内无沙箱时设 false |
WEB_BRIDGE_PERMISSIONS |
— | 授予上下文的权限,逗号分隔(如 geolocation,clipboard-read) |
WEB_BRIDGE_ACTION_TIMEOUT |
10000 |
单次动作超时(毫秒,0 不限制) |
WEB_BRIDGE_NAV_TIMEOUT |
60000 |
导航超时(毫秒,0 不限制) |
WEB_BRIDGE_SETTLE_MS |
500 |
动作后等待异步任务安定的时长(毫秒) |
WEB_BRIDGE_STORAGE_STATE |
— | 会话恢复文件路径(仅非持久化模式) |
WEB_BRIDGE_TEST_ID_ATTR |
data-testid |
testid= 选择器使用的属性名 |
WEB_BRIDGE_CONFIG |
— | 配置文件路径 |
配置文件
{
"browser": { "name": "chromium", "headless": true, "viewport": { "width": 1280, "height": 720 } },
"context": { "ignoreHTTPSErrors": false, "permissions": ["geolocation"] },
"timeouts": { "action": 10000, "navigation": 60000, "settle": 500 },
"sandbox": true,
"testIdAttribute": "data-testid"
}
启动:node dist/index.js --config web-bridge.config.json。
工具清单
全部工具的描述与权限说明由 MCP tools/list 返回,此处列要点。
导航
| 工具 | 说明 | 权限影响 |
|---|---|---|
web_open |
打开 URL(支持 http/https/file/data),可选等待策略 |
发起真实网络请求并渲染页面 |
web_back / web_forward |
历史后退 / 前进 | 触发导航,可能重载页面 |
web_refresh |
刷新当前页 | 重新请求页面全部资源 |
交互
| 工具 | 说明 | 权限影响 |
|---|---|---|
web_click |
点击(ref/selector;支持按钮、双击、修饰键) | 派发鼠标事件,可能触发跳转/提交/脚本 |
web_fill |
清空并填写输入框/文本域 | 修改表单数据,可能触发校验 |
web_type |
向聚焦元素逐键输入 | 发送键盘事件 |
web_press |
按键(Enter、Control+a 等) | 发送键盘事件 |
web_select |
下拉选择(按 value 或 label) | 修改表单数据 |
web_hover |
悬停(触发菜单/提示) | 派发鼠标移动事件 |
web_scroll |
滚动页面/元素(up/down/left/right/top/bottom/into_view) | 仅改变滚动位置 |
观察
| 工具 | 说明 | 权限影响 |
|---|---|---|
web_snapshot |
生成无障碍树快照(ref 编号 + 状态标注) | 只读,不产生网络请求 |
web_screenshot |
截图(PNG/JPEG、视口/整页/元素、可保存本地) | 只读页面;save_to 会写入调用方指定路径 |
web_status |
会话状态:运行状态、标签页、当前页 | 只读 |
脚本与视口
| 工具 | 说明 | 权限影响 |
|---|---|---|
web_evaluate |
页面上下文执行 JS,返回净化结果 | 高危:可读写页面数据、cookie、登录态,可发起网络请求 |
web_resize |
调整视口尺寸 | 只改变渲染视口 |
标签页与会话
| 工具 | 说明 | 权限影响 |
|---|---|---|
web_tab_new |
新建标签页(可带 URL、可选是否激活) | 新建标签页,可能发起网络请求 |
web_tab_list |
列出全部标签页 | 只读 |
web_tab_switch |
切换活动标签页 | 只读 |
web_tab_close |
关闭标签页(默认当前页) | 关闭标签页,未保存数据丢失 |
web_wait |
等待:load / networkidle / selector / url / sleep | 只读 |
web_shutdown |
关闭浏览器并清理会话 | 关闭浏览器进程,登录态丢失 |
快照与 ref 机制
web_snapshot 把页面渲染为带缩进的结构化文本,例如:
title: Demo Home
url: http://localhost:8080/index.html
tree:
banner
navigation
[1] link "首页"
[2] link "文档"
main
heading "欢迎来到演示站点" (level: 1)
form
[3] textbox "用户名" (placeholder: "请输入用户名")
[4] checkbox "记住我" (unchecked)
[5] button "提交表单"
[n]是引用编号(ref),只分配给可交互元素(按钮/链接/输入框/下拉框/复选框等);- 后续
web_click/web_fill/web_select等可用ref定位(ref: 3),也可用选择器(selector: "#username"、text=关键词、testid=值); - 快照展示状态:
(checked/unchecked)、(disabled)、(selected)、(expanded/collapsed)、(password)、(value: ...)、(placeholder: ...); - 密码框永不展示
value; - 支持
selector参数只快照子树、max_depth限制深度、max_nodes限制节点总数(防 token 炸弹)。
ref 是位置型路径(由 DOM 结构决定):页面导航后旧 ref 自动失效(报错提示重新快照);未导航时若页面脚本增删了 DOM,旧 ref 可能解析到其他元素——操作异常时请重新快照。
等待策略
web_open 的 wait_until:commit(请求发出)→ domcontentloaded(DOM 就绪)→ load(资源加载完成)→ networkidle(网络空闲)。默认 load。
动作后默认等待 settleMs(500ms)让异步任务(导航、请求)安定。
权限与安全说明
- 本插件不是安全边界。
web_evaluate可执行任意脚本、web_open可访问任意站点、save_to可写任意路径——请仅在可信环境中使用,并在 harness 层配置工具级权限。 - 建议最小化权限:日常观察用
web_snapshot(零网络请求、零副作用),需要视觉确认时用web_screenshot,最后才考虑web_evaluate。 - 浏览器进程由插件管理:客户端断开、
web_shutdown、SIGINT/SIGTERM 都会回收浏览器进程。 - 无头模式默认开启;需要可视化调试时设置
WEB_BRIDGE_HEADLESS=false。
已知限制
- 影子 DOM / iframe 内容不在快照中:遍历器只覆盖主文档的常规 DOM 子树;若页面依赖 shadow DOM 承载交互元素,请用
web_evaluate或页面自身的测试钩子(testid=)。 - ref 为位置路径:见上文「快照与 ref 机制」。
- 弹窗自动激活:
target=_blank等弹出的新标签页会自动成为活动页(agent 点击链路的直觉行为);可通过web_tab_list+web_tab_switch找回其他标签页。 web_evaluate的语句序列形态(含函数声明的多语句)按副作用执行、无返回值;表达式与函数形态返回结果。异步逻辑请用async函数形态。
开发与测试
npm run build # tsc 编译到 dist/
npm test # 全部测试(单元 + 浏览器集成 + MCP 协议链路)
npm run test:unit # 仅单元测试(配置/工具函数/快照格式/遍历器)
npm run test:integration # 仅浏览器集成测试
测试覆盖:配置解析、遍历器行为、快照格式、结果净化、16+ 个真实浏览器集成场景(导航/点击/填表/截图/标签页/历史/等待/滚动/失败路径)、真实 stdio 进程链路(含断开后浏览器回收断言)。
项目结构
src/
index.ts 入口:CLI 参数、配置加载、启动 MCP server
config.ts 配置(默认值/文件/环境变量三级合并与校验)
server.ts MCP server 组装、错误映射、生命周期清理
browser.ts 浏览器会话:懒启动/标签页/引用表/关闭
walker.ts 页面端无障碍树遍历器(单一源码,Node 测试与页面共用)
snapshot.ts 快照编排、ref 分配、文本格式化
scripting.ts 脚本执行与结果净化
locators.ts ref/selector 解析
util.ts 参数校验、URL 校验、超时错误归类
tools/ 22 个工具实现(按职责分组)
registry.ts 工具注册表
dsh-plugin.json 插件清单(dsh harness 接入说明见 README)
test/ 测试与夹具
许可
链接
同类插件
superdesigndev/treg★ 428
给 Agent 的工具目录:按「要做的事」检索约 2,600 个外部接口(SEO 与 SERP、外链、社交、人物与公司信息补全、广告库、抓取),查看参数与单次调用价格后直接调用,凭据由服务端注入。附带技能,MCP 行在未设置 TREG_TOKEN 前保持禁用。
Lum1104/dsh-browser★ 216
Chrome 侧边栏扩展,让 DSH 直接操控你的浏览器,无需视觉能力。
zhaoolee/notes★ 142
将 DSH 对话导出为锤子便签风格 PNG,或在配置的账号工作区中新建和更新 Markdown 便签。
liustack/modsearch★ 115
纯文本 agent 的联网搜索桥:搜索网页与 X,返回结构化 JSON 证据(search/fetch/引用)。
taxueseek/argo★ 94
专为 agent 打造的搜索工具:多语言,覆盖中文/英文/学术/代码/购物/金融/新闻/百科。
Vladimir-Human/ru-marketplace-mcp#dsh★ 64
面向俄罗斯十家电商平台的技能与可选 MCP 行:跨 Wildberries、Detsky Mir、Yandex Market 比价,以及各平台的搜索、商品卡与评论。安装后 13 个技能立即可用;两行 MCP 默认关闭,需将 RU_MARKETPLACE_MCP_DIR 指向本地克隆,该克隆需要 Python 3.12+ 与 uv。