Back to directory

browser-bridge

Maintenance: Active

hanelalo/browser-bridge

MCP bridge that lets your agent genuinely control your browser window, just like you would.

View on GitHub
$ dsh plugin add browser-bridge

Install

dsh has no central install command — add this plugin’s entry (documented in its README) to your profile or patch config, then restart.

How installs work

57

stars

12

forks

Rust

Language

MIT

License

2026-08-02

Created

2026-11-04

Last push

README

Browser Bridge

通过 WebSocket 把本地工具和真实浏览器连接起来的桥,不需要 CDP。

扩展安装在浏览器里,作为"手";server 是本地的 WebSocket 枢纽;client 是发指令的入口(Rust CLI),也可通过 bridge-mcp 暴露给 Claude / Cursor 等 agent。

项目结构

目录 技术 职责
extension/ Vue 3 + TypeScript(WXT / Manifest V3) 安装在浏览器里,执行指令
server/ Rust(tokio + tokio-tungstenite) WebSocket 枢纽,路由指令与响应;可选内置 MCP over HTTP
client/ Rust CLI(clap) 发指令、打印结果
bridge-core/ Rust 共享库 传输层(连接/自动拉起/重连)、元素定位、站点配方
bridge-mcp/ Rust(rmcp,MCP server) 把全部指令暴露为 MCP tools(stdio;bridge-server 复用同一套工具提供 HTTP 传输)

快速开始

1. 启动 server

推荐用管理脚本后台常驻(server 不会自动退出,多个 agent 共享同一个进程):

./scripts/build.sh              # 首次先构建
./scripts/server.sh start       # 后台启动(start|stop|restart|status|logs)
./scripts/server.sh status

也可以前台跑,方便看日志:

cd server
cargo run            # 默认监听 ws://127.0.0.1:9225(MCP over HTTP 另开 9226)
# 换端口:BRIDGE_PORT=9226 cargo run
# 关闭 HTTP MCP:BRIDGE_HTTP_PORT=0 cargo run

2. 加载插件

cd extension
pnpm install
pnpm dev             # 会自动打开 Chrome 并加载开发版插件

也可以 pnpm build 后,在 chrome://extensions 打开"开发者模式",加载 extension/dist/chrome-mv3 目录。

点击扩展弹窗里的「任务面板」,或从 Chrome 侧边栏打开 Browser Bridge,可以看到当前窗口里正在执行和排队的任务。排队数据在 bridge-server 上,server 与扩展需要一起升级。

3. 使用 client

client 连接失败时会自动拉起 bridge-server(需要已构建的二进制,可用 BRIDGE_SERVER_BIN 指定路径);插件断线后按 500ms→5s 退避自动重连。

cd client
cargo run -- list-tabs
cargo run -- --window 5 list-tabs
cargo run -- navigate https://example.com
cargo run -- click '#submit'
cargo run -- set_value '#username' alice
cargo run -- scrape 'div.card' --fields 'name:.name,price:.price,img:img@src'
cargo run -- querydomains 'browserbridge'
cargo run -- googlesearch 'Haze Seas'
cargo run -- redditsearch 'rust programming'
cargo run -- youtubesearch 'rust programming' --time week --sort popularity --max 10
cargo run -- youtubeinfo 'https://www.youtube.com/watch?v=rQ_J9WH6CGk'
cargo run -- youtuberinfo 'https://www.youtube.com/@xiaojunpodcast/videos'
cargo run -- youtuberinfo '@xiaojunpodcast' --max 20
cargo run -- googletrends 'ai image' --date 'today 1-m' --geo Worldwide
cargo run -- oldgoogletrends 'ai image detector' --date 'now 7-d' --geo Worldwide
cargo run -- googletrends-compare 'ai image' 'GPTs' --date 'today 1-m'
cargo run -- oldgoogletrends-compare 'coffee' 'tea' --date 'now 7-d'
cargo run -- get-page-markdown --url https://example.com
cargo run -- get-a11y-tree
cargo run -- screenshot --out shot.png

指令速查表

指令 作用
list-tabs 列出所有标签页
new-tab [url] 新建标签页(可指定 URL)
activate-tab --tab <id> 切换标签页并聚焦窗口
close-tab [--tab <id>] 关闭标签页(默认当前激活页)
close-auto-tabs 关闭 bridge 自动打开的全部标签页(不碰手动开的)
navigate <url> 导航并等待页面加载完成
click <target> [--new-tab] 点击匹配定位的元素(锚点默认当前标签页打开)
click-at <x> <y> 按坐标点击
press-key <key> 模拟按键(支持修饰键、--wait-load)
scroll --dx --dy 滚动窗口或指定容器
set-value <target> <value> 设置 input/textarea/contenteditable 的值
check <target> 勾选/取消 checkbox、radio
select-option <target> --text/--value/--option-index 选中下拉项
clear <target> 清空输入类元素
get-value <target> 读取元素当前值
scrape <item> --fields '...' 按选择器提取结构化数据
run-script '<js>' 页面里执行任意 JS,返回 JSON
get-page-content 读取页面标题/URL/文本
get-page-markdown [--url <url>] [--selector <css>] [--full] 把页面内容转换成标准 Markdown(默认自动提取正文,去掉导航/页脚等噪音)
get-a11y-tree [--include-hidden] [--max-nodes <n>] 读取页面 a11y tree,可交互节点(按钮/链接/输入框等)带 target 可直接喂给 click / set_value
screenshot [--tab <id>] [--format png|jpeg] [--quality <0-100>] [--out <file>] [--foreground] 截取页面可见区域截图,返回 base64 data URL;--out 直接保存为文件
googlesearch '<关键词>' Google 搜索,输出 { tab_id, results }
redditsearch '<关键词>' Reddit 搜索,输出 { tab_id, results }
youtubesearch '<关键词>' [--time] [--sort] [--max] YouTube 搜索,支持上传日期 / 优先顺序筛选,最多返回 --max 条(默认 5),输出 { tab_id, results }
youtubeinfo '<视频URL或ID>' 获取指定 YouTube 视频详情:字幕全文、URL、作者、时长、点赞/评论/订阅数,输出 { tab_id, video }
youtuberinfo '<频道URL或handle>' [--max] 获取指定 YouTube 频道(youtuber)的视频列表:频道名、订阅数、视频名称/URL/观看数/时长/发布时间,最多返回 --max 条(默认 10),输出 { tab_id, channel, videos }
googletrends '<关键词>' [--date] [--geo] Google Trends,输出 { tab_id, trend[], top[], rising[], regions[] }
oldgoogletrends '<关键词>' [--date] [--geo] 经典版 Google Trends(legacy),读取页面趋势表格 + 完整热门/上升查询 + 地区热度
googletrends-compare <词1> <词2>... [--date] [--geo] Google Trends 多词对比,输出 { series[] }
oldgoogletrends-compare <词1> <词2>... [--date] [--geo] 经典版 Google Trends(legacy)多词对比,共享 0-100 刻度,支持 now 7-d,输出 { series[] }
querydomains '<关键词>' [--tlds 'com,ai,xyz'] Query.Domains 批量查域名注册情况与价格,输出 { results[] }(每项含 domain / tld / status / available / price / badges)

多数指令支持 --tab <id> 指定标签页,默认操作当前激活页。

标签页管理:click 点击锚点链接默认在当前标签页打开(自动覆盖 target="_blank"),需要新开时用 --new-tab(由扩展创建标签页,响应会返回新标签页的 tab_id,便于链式操作)。new-tab 指令和 click --new-tab 打开的标签页都会被扩展记录,流程结束后可用 close-auto-tabs 一键清理,不会误关你手动打开的标签页。

close-auto-tabs

清理"自动打开的标签页",需要单独执行(CLI 手动调用,或 MCP 流程在收尾时调用一次),不会误关手动打开的标签页。支持多 agent 隔离:

  • MCP(close_auto_tabs 工具):每个 MCP 进程启动时生成独立身份(mcp-<pid>-<nanos>),只清理本进程创建的标签页,不会误关其他 agent 正在用的标签页;任务结束后可再调 close_agent_window 关闭自己的专用窗口(连同窗口内标签页一并释放)
  • CLI(close-auto-tabs):作为人工管理入口,清理全部自动标签页(不管是谁创建的)

会被清理的:new-tab 指令和 click --new-tab 创建的标签页(扩展记录在 chrome.storage.session,service worker 重启不丢)。例如 googletrends 每次查询都会新开一个标签页,跑完后清理效果最明显:

cargo run -- googletrends 'ai image'
cargo run -- close-auto-tabs   # 关闭刚才 googletrends 开的标签页

不会被清理的:手动开的标签页(如 Sitemap Monitor)、以及 navigate / googlesearch / redditsearch 复用的当前标签页(这些不新开 tab,属于"工作标签页",留着是正常的)。

get-page-markdown

Read the full README on GitHub →

DSH Plugins is an independent community directory of DeepSeek Harness plugins. Not affiliated with or endorsed by DeepSeek. Third-party plugins are not security-audited — review the source before installing.

New DeepSeek Harness plugins, weekly. No spam.