Browser MCP
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Browser MCP
简体中文 | English
把浏览器页面通过本地通道开放给任意 CLI / IDE / Agent 控制的轻量体系。
broker.py 本身就是一个 MCP 服务器(stdio / Streamable HTTP / SSE 三种传输),
IDE、Agent 等把 broker 配成一个普通 MCP 服务器即可操控浏览器。
页面纯文本化(无截图依赖的多模态),LLM 用元素编号定位,适合做浏览器自动化编排。
当前版本:v0.1.16(以 chrome-extension/manifest.json 为准)
⚠️ 仍在开发中:本项目处于 活跃开发阶段(v0.1.x),接口、命令与扩展行为可能在未提前通知的情况下变更,且不保证向后兼容。请勿用于关键生产环境;接入前请先跑通「快速开始」验证,并随时关注
docs/changelog.md的更新记录。扩展为「加载未打包」的开发者模式方案,未经商店审核与稳定性打磨。
┌─ 浏览器(N 个标签页)──────────┐ ┌─ 本机 ───────────┐ ┌─ MCP 客户端(IDE / Agent / CLI)──┐
│ 接入端(Chrome 扩展) │ WS/ │ broker.py │ MCP │ ·list_pages / list_marks 发现 │
│ ·自动加载,轻注入,零构建 │──────▶│ ·页面注册中心 │◀────▶│ ·page_snapshot 看页面 │
│ ·hello 广播(url/title/caps) │ │ ·上线/下线广播 │ │ ·page_call 操控页面 │
│ ·snapshot/动作执行/eval │◀──────│ ·命令转发/等结果 │─────▶│ ·page_logs 看页面异常 │
└──────────────────────────────┘ └─────────────────┘ │ (也可直接走 HTTP /call) │
└─────────────────────────────────┘目录结构与文件说明
文件 | 作用 |
| 本地注册/广播/转发中心,同时就是一个 MCP 服务器。维护在线页面表,把外部命令转发给对应页面并等结果。通过 MCP 接入时它就是那个 MCP 服务进程;唯一需要常驻运行的进程 |
| broker 的 Python 依赖(aiohttp;YAML 解析在扩展侧,无 pyyaml) |
| 本机生效的 MCP 接入配置(stdio 方式,MCP 客户端自动拉起 broker) |
| 可复制的 MCP 配置模板,把 |
| 外部 CLI 接入示例(纯标准库):发现 → 校验 URL → 接入 → LLM 驱动循环; |
| 仅一个 CLI 示例 YAML(flow 库真相源在扩展本地 |
| 接入端(唯一方案):Chrome 扩展 MV3 |
├ | 扩展清单:权限、注入规则( |
├ | Service Worker:每个标签页维持一条到 broker 的 WebSocket;命令路由(DOM 动作转发给 content,截图/标签管理自己执行);站点白名单过滤;webRequest 观察模式接口捕获(URL/请求头/请求体/响应头) |
├ | 白名单核心:配置存储、eTLD+1 主域名提取、匹配引擎(SW/popup/options 共用) |
├ | 工具栏弹窗:接入总开关、当前页白名单状态、一键加入/移出 |
├ | 完整配置页:域名列表与正则规则的增删改查、导入导出、正则实时测试面板 |
├ | 页面捕获层( |
├ | 内容脚本:每个标签页一个实例,负责 DOM 快照与动作执行(click/type/eval 等);并为页面工具箱转发扩展桥消息( |
├ | flow 自检 / 自报 / 自记录(内容脚本,加载顺序在 |
├ | flow 执行器(内容脚本):解析 YAML( |
├ | js-yaml 4.1.0(随扩展打包;content 与 background 共用,无网络/无 Python 依赖) |
└ | 页面工具箱(设计原型 |
| 早期油猴脚本版,已停止维护、仅作存档;接入请一律使用 Chrome 扩展 |
| YAML 测试流规范:schema、执行语义、断言、MCP/HTTP/CLI 接口 |
| flow 自检 / 自报 / 自记录模块:五类能力、数据 schema、容错降级与已知边界 |
| 早期调研笔记(console 注入方案的原理与坑) |
Related MCP server: orchords-web-pilot
快速开始
1. 启动 broker(本机常驻)
pip install -r requirements.txt
python broker.py
# 可选环境变量:
# BRIDGE_PORT=8766 换端口
# BRIDGE_TOKEN=xxx 接口鉴权(外部请求需带 ?token=xxx 或 X-Bridge-Token 头)只用 MCP 的 stdio 方式时可以跳过这步——MCP 客户端会把 broker 自动拉起(见下文「MCP 接入」)。
2. 浏览器接入(Chrome 扩展)
Chrome 打开
chrome://extensions右上角开启「开发者模式」
点「加载未打包的扩展程序」(Load unpacked)→ 选择本仓库的
chrome-extension目录打开任意网页,页面自动广播上线
要操控本地
file://页面,需在扩展详情页开启「允许访问文件网址」。eval 绕过页面 CSP 需在扩展详情页开启「允许用户脚本」(Chrome ≥ 135),见「eval 与 CSP」。
3. 验证
curl http://127.0.0.1:8766/pages
# [{"id":"a1b2c3d4","url":"https://github.com","title":"GitHub","mode":"ws","ago":1.2}, ...]打开几个标签页,每个都会出现一条记录。页面关闭/跳转时列表自动更新。
扩展安装与更新
只支持开发者模式下的「加载未打包的扩展程序」(Load unpacked),即直接加载本仓库的 chrome-extension 目录(步骤见上文「快速开始 · 浏览器接入」),不做 zip / .crx / 商店分发。
改了扩展代码:
chrome://extensions→ 该扩展卡片点「重新加载」→ 刷新目标页面(content.js才会带上最新逻辑)驱动本地
file://页面:扩展详情页开启「允许访问文件网址」卸载重装:未指定私钥的未打包扩展,ID 由目录路径推导;重装后重新打开目标页面即可重新接入
MCP 接入(推荐):把 broker 配成一个 MCP 服务器
broker.py 自带完整 MCP 服务——接入就是把它配成你客户端里的一个普通 MCP 服务器,不需要另起 MCP 服务,也不需要额外依赖;页面接入、CLI 调用、MCP 客户端共用这一个进程。仓库根目录的 .mcp.json 就是本机生效的接入配置,.mcp.example.json 是可复制的模板。
传输 | 地址 / 命令 | 说明 |
stdio(推荐) |
| 由 MCP 客户端拉起,broker 随 MCP 一起启动,无需先跑 |
Streamable HTTP |
| 无状态, |
旧版 HTTP+SSE |
|
|
方式一:stdio 自动拉起(推荐)——仓库根目录的 .mcp.json / .mcp.example.json 就是这个配置,把它加进你的 MCP 客户端配置(Trae 的 .trae/mcp.json、Claude Desktop 的 claude_desktop_config.json、项目级 .mcp.json 等均可):
{
"mcpServers": {
"page-bridge": {
"command": "python",
"args": ["E:\\WORK\\PROJECT\\TOOLS\\browser-agent\\broker.py", "--stdio"]
}
}
}把
args里的路径改成你的broker.py绝对路径;走项目虚拟环境时把command换成…\\browser-agent\\.venv\\Scripts\\python.exe进程内同时跑 stdio JSON-RPC 和
127.0.0.1:8766中枢,页面照常接入;stdout 只留 JSON-RPC,日志全部走 stderr客户端断开(stdin EOF)后进程自动退出、端口释放
同一端口只允许一个 broker:已有实例在跑时,stdio 实例会自动探测(
GET /pages)并跳过自启,把请求转发给现有实例——MCP 配置无需任何改动,两种情况下同一份配置都能用不要把
start-broker.bat配成 stdio 的command——bat 的 echo 会污染 stdout
方式二:连已启动的 broker(HTTP URL)(先跑 start-broker.bat;开了 BRIDGE_TOKEN 时 URL 追加 ?token=<token>):
{
"mcpServers": {
"page-bridge": { "url": "http://127.0.0.1:8766/mcp" }
}
}MCP 工具:
工具 | 参数 | 作用 |
| - | 发现当前接入的页面(id / mark / url / title / ago) |
| - | 标记列表(离线时也给最后一次 URL) |
|
| 实时快照(交互元素带 bid 编号 + 正文)。输出过大时用 |
|
| 下发任意命令,参数同下方命令表(click / type / nav / eval / dom / screenshot…)。元素定位 bid / selector / text 三选一; |
|
| 仅扩展版:读取页面运行日志与异常(console / 未捕获异常 / Promise 拒绝 / 资源加载失败 / CSP),带 |
|
| YAML 测试流(docs/spec-flow.md):把页面操作序列编排成 YAML(每步唯一 id,步骤级 |
page 可传标记 id 或 pid;只有一个在线页面时可省略。工具调用与 /call 走同一条转发链路,超时上限同样 120s。
HTTP API(不走 MCP 的直接接入)
MCP 工具底层就是这套 HTTP 接口;自己写脚本/编排框架、或不想用 MCP 的客户端可以直接调(无需 SDK,curl 即可验证)。
接口 | 用途 |
| 发现:在线页面列表(id / url / title / mode / ago / eval_mode) |
| 订阅广播(SSE): |
| 执行一条命令:body 为命令 JSON, |
| 列出全部页桥标记: |
| 按标记查网页:返回在线状态、 |
| 按标记执行命令(body 同 |
| flow 库列表(库在浏览器扩展本地,broker 转发,docs/spec-flow.md) |
| 执行 flow:body |
| 异步进度轮询: |
`GET | PUT |
| 长连接:收广播 + attach 页面 + 双向命令流(适合常驻会话) |
# 发现并校验 URL("是否适合接入"由外部自己判断,比如正则匹配域名)
curl http://127.0.0.1:8766/pages
# 看页面快照(LLM 的眼睛:交互元素带 [bid] 编号 + 正文)
curl -X POST http://127.0.0.1:8766/call/a1b2c3d4 -d "{\"action\":\"snapshot\"}"
# 点击 3 号元素
curl -X POST http://127.0.0.1:8766/call/a1b2c3d4 -d "{\"action\":\"click\",\"bid\":3}"
# 截图(仅扩展版支持,返回 base64 PNG)
curl -X POST http://127.0.0.1:8766/call/a1b2c3d4 -d "{\"action\":\"screenshot\"}"命令一览
定位元素三选一:bid 传快照里的元素编号、selector 传 CSS selector、text 按可见文本匹配(快照没给 bid 的元素,如自绘组件,用 text 也能点)。
action | 参数 | 说明 |
| - | 探活,返回页面信息 |
|
| 页面快照:url/title/viewport/滚动位置/元素列表/正文; |
|
| 精简 DOM:Pug 缩进树( |
|
| 滚动到元素并点击(带完整鼠标事件序列) |
|
| 输入文本,走原生 setter,兼容 React/Vue 受控组件 |
|
| 按键(Enter 会自动提交表单/点击) |
|
| 下拉选择 |
|
| 滚动页面或滚到某元素 |
|
| 悬停 |
|
| 页面跳转 |
| - | 后退 / 刷新 |
|
| 页面内执行任意 JS(支持 async/await)。优先走 userScripts 通道绕过 CSP;未开启「允许用户脚本」开关时走内容脚本,受页面 CSP 约束。详见下方「eval 与 CSP」 |
|
| 读/写 cookie(op=get/set) |
|
| 读/写 localStorage / sessionStorage |
|
| 给 |
|
| 等待(上限 15s) |
|
| 红框标出元素 2 秒(调试用) |
|
| 仅扩展版:查询页面捕获的接口记录(URL/请求体/响应/鉴权头)。 |
|
| 仅扩展版:查询页面日志与异常。 |
| - | 仅扩展版:截图。经 MCP |
| - | 仅扩展版:列出所有标签页 |
|
| 仅扩展版:新开标签页 |
|
| 仅扩展版:关标签页(可传 pageId) |
|
| 仅扩展版:切换到某标签页(可传 pageId) |
|
| 往页面 console 打一行(ISOLATED world 派发 |
YAML 测试流(flow)
把页面操作序列编排成 YAML,代替 Playwright 的轻量路线:不引入 Node。
YAML 的解析与执行都在浏览器扩展里(flowrun.js + vendor/js-yaml),
broker 只负责传输(LLM → broker → 浏览器)与进度汇总,不解析 YAML、不落盘。
flow: demo-login
desc: 登录并检查仪表盘
vars: { user: admin } # ${vars.user};密码走 ${env.X} 不落盘
steps:
- id: s01 # 每步唯一 id,报告与轨迹按 id 输出
do: nav
url: https://example.com/login
- id: s02
do: type
selector: '#username'
text: ${vars.user}
- id: s03
do: click
selector: 'button[type=submit]'
text: 登录 # selector 失败自动回退按文本定位
expect: { url_contains: /dashboard } # 断言:url_contains / url_is / text / selector
max_wait_ms: 8000执行:MCP
flow {op:"run", name:"demo-login"}、CLIpython cli_client.py flow <本地.yaml>、 或工具箱「直接运行(不保存)」;执行体是目标页里的扩展脚本,跨页跳转自动续跑auto-wait:定位类动作(click / type / select / hover / press)找不到元素时不立即失败, 在
auto_wait_ms窗口(默认 5s,step 级可覆盖,0 关闭)内每 0.3s 重试定位—— 录制的 flow 回放不必手写等待也能扛住路由切换后的异步渲染;显式等待仍用expect报告:每步
{id, do, 值, ok, ms, url, error?},失败自动截图(dataUrl 内联,不落盘)并一次性返回(LLM 直接读)轨迹:每步往页面 console 打
[flow:名] s03 click … → OK 340ms,LLM 可用page_logs {q:"[flow:"}自行拉取库管理:
op=list/get/save/delete,真相源是扩展本地库(chrome.storage.local.flows), 运维只需 broker + 扩展两样本地组件;${env.X}取扩展本地flowenv配置
完整 schema / 变量替换 / secret 打码 / 语义与限制见 docs/spec-flow.md;示例见 flows/demo-smoke.yaml。
cli_client.py(现成的编排示例)
python cli_client.py list # 发现当前在线页面
python cli_client.py watch # 订阅广播事件流
python cli_client.py snap github.com # 按 URL 子串找页面并看快照
python cli_client.py call <pid> "{\"action\":\"snapshot\"}"
# 一条龙:发现 → --match 校验 URL → 接入 → LLM 驱动循环直到 done
# 环境变量: OPENAI_API_KEY(必需) OPENAI_BASE_URL(可选,兼容接口) BRIDGE_MODEL(可选)
python cli_client.py run "在搜索框搜索 playwright 并打开第一个结果" --match github.com
# 跑 YAML 测试流(CI 入口;逐步打印 OK/FAIL,退出码 0/1)
python cli_client.py flow flows/demo-smoke.yaml --var user=admin --from-step s03run 的循环就是「snapshot → LLM 决策一个 JSON 命令 → POST /call → 结果回填 → 循环」,
你的 IDE/Agent 只需要复刻这个循环(或直接调 /call 接口)即可接入任何编排框架。
站点白名单
纯白名单模式:只有白名单内的页面才接入 broker(命中域名或正则即放行),其余页面不注册、不广播。
总开关(启用与否):popup 右上角与配置页标题栏右上角各有「启用」开关,优先级高于一切规则——关闭后所有页面断开 broker 且不注册(
/pages变空),重新打开自动按白名单恢复全部命中页面;状态只由开关本身表示,关闭时工具栏图标额外显示灰色OFF角标入口:点工具栏图标打开 popup —— 展示当前页是否在白名单(含命中来源:域名/正则),一键加入/移出
域名列表:只存 eTLD+1 主域名(如
github.com自动覆盖gist.github.com等所有子域名;bbc.co.uk等多级后缀正确识别),支持增删改查、搜索、导入导出(JSON/纯文本)正则规则:匹配完整 URL,保存前校验合法性,附带实时测试面板
即时生效:配置改动后已注册页面按新规则断开/恢复,无需刷新页面;当前 tab 命中白名单时工具栏图标显示角标
W详细需求与设计见
docs/spec-url-filter.md
页面工具箱(toolbox)
按白名单注入的页面内工具面板,设计原型见 docs/toolbox/(架构图 docs/toolbox-proto-map.md):
注入:页面命中白名单后,background 经
chrome.scripting把chrome-extension/toolbox/下 14 个模块注入页面主世界(MAIN world)——React fiber 反查、fetch 拦截、window.__BA_*都要在页面上下文才可见;注入不受页面 CSP 限制门控即时生效:白名单配置变更后,已注入页面经 DOM 事件
batb:gate同步显隐——移出白名单立即隐藏,重新命中自动恢复;未注入过的命中页面自动补注入入口:右下角圆形 FAB(可拖拽、位置记忆、快捷键唤起,可在「设置」中更换),六分类 37 项功能(提示 / 查找 / 样式与屏蔽 / 发给 LLM / 开发产物 / 采集)
中英双语:面板底部「EN / 中文」一键切换,默认中文,选择存
localStorage刷新后保持;分类、功能名与说明、结果卡片、提示语等全部界面文案均有英文版本采集:「网址二维码」把当前网址纯本地生成二维码(扫码在手机打开,可下载 PNG / 复制链接,内嵌 qrcode-generator MIT 裁剪版);「整页截图」滚动逐屏截取、拼接为长图并自动下载 PNG;「容器截图」拾取任意元素——可滚动容器只截其内部完整滚动范围(自动向上定位滚动祖先、逐屏裁剪拼接),普通元素截取当前可见区域——两类截图均自动处理浮动元素(fixed 临时隐藏、sticky 临时取消吸附,完成后还原),避免每屏重复;「接口调用」双层捕获页面请求——页面捕获层(
capture-main.js,document_start 包裹 fetch/XHR)抓请求体/响应体 + webRequest 观察模式抓全量请求头(含 Cookie/Authorization),按 URL+时间合并,列表点开详情可复制调试文本 / 复制 cURL 粘给 LLM(默认脱敏 Cookie/token 等鉴权字段,可手动关);截图两项均经扩展桥(content.js 中继batb:bridge→ backgroundcaptureVisibleTab)实现,需 content.js 与扩展版本一致(更新扩展后刷新页面)接口调用的 LLM 查看通道:LLM 经 broker 发
netlog命令自主查询捕获记录(list摘要 →get详情 /curl回放,无需人工点击),协议与局限详见docs/spec-net-protocol.md发给 LLM 的存储通道:结果写
localStorage["ba:ctx"]/["ba:el"],LLM 经 broker 的storage动作自取(window.__BA_*仅页面主世界可见,跨进程读取请用 storage);「复制页桥标记」复制的是网页 id(扩展在页面接入时用 JS 生成、按 tab 存在chrome.storage.session,同一标签页跨导航/刷新不变,tab 关闭才清;随 hello/hb 上报),LLM 凭GET /mark/<id>即查回 URL 与在线状态、POST /mark/<id> {"action":"snapshot"}取实时快照继续操作增删功能:改
toolbox/feats/<分类>.js里B.register([...])数组即可;模块清单/加载顺序见原型地图
eval 与 CSP(扩展版)
eval 在内容脚本里执行时会受页面 CSP 约束:GitHub、腾讯元宝等 script-src 'self' 严格站点会直接报
unsafe-eval 拦截错误。扩展版提供 userScripts 通道绕过(Chrome ≥ 135):
chrome://extensions→ Page Bridge → 详情 → 打开「允许用户脚本」(Allow user scripts) 开关重载扩展:开关生效需要 Service Worker 重启后才能拿到
chrome.userScriptsAPI(SW 常驻时开关不会实时生效),然后刷新目标页面
客户端如何感知(LLM 编排必读):
GET /pages每条页面带eval_mode字段:"userscript"— 已开启开关,eval 不受 CSP 限制,任何页面可用"fallback"— 未开启,eval 走内容脚本,严格 CSP 站点会失败
ping的返回里也带eval_mode在受限页面上调
eval失败时,error里会附带开启指引与风险提示,LLM 可原样转告用户
风险提示(请转告用户):「允许用户脚本」开启后,代理可在任何页面执行任意 JS(读写页面数据、代发请求等)。 只在自己可控的浏览器上开启;不要在不可信的编排方接入时开启。
安全说明
broker 只绑定
127.0.0.1,局域网不可见;公网机器上请务必设置BRIDGE_TOKENeval等于把页面权限完全交给接入方,只在自己可控的浏览器上启用netlog查询默认脱敏 Cookie/Authorization/token 类字段;redact:false会拿到真实凭据值,仅在可控环境按需使用(见docs/spec-net-protocol.md)用「站点过滤」配置黑白名单,限制只广播特定站点(见上文)
请勿用于未授权的网站或他人会话
已知边界
跨域 iframe 内部内容拿不到(同源策略,所有页面注入方案皆如此)
浏览器下载、多窗口管理未覆盖(需 CDP)
强 CSP 页面下未开启「允许用户脚本」时,
eval会失败(其余 DOM 动作不受影响)启用 Trusted Types 且无 default policy 的页面(部分 Google 站点)上,工具箱 UI 可能挂载失败(innerHTML 被拦截)
故障排查
现象 | 排查 |
| broker 没跑起来?扩展装了但没开过普通网页?总开关被关了?(点工具栏图标看「接入启用」)扩展详情页看 Service Worker 报错 |
页面在列表里但命令超时 | 标签页被浏览器休眠了,切换过去激活即可;或页面关闭前有未完成命令 |
| 扩展详情开启「允许访问文件网址」 |
页面右下角没出现工具箱 FAB | 页面是否在白名单(popup 查看命中);扩展详情页看 Service Worker 报错; |
工具箱「整页截图」报扩展桥无响应 | 扩展刚更新过、页面里的 content.js 还是旧版(没有桥),刷新页面即可;或扩展详情页看 Service Worker 报错 |
工具箱 FAB 出现过又自行消失 | 站点把整个文档重写了( |
工具箱 FAB 在,但点了没反应 / 面板打不开 | 同上场景的第二段:整块重写文档会连带清空 document(含 Shadow DOM)与 window 上的全部事件监听,节点与样式还在但监听没了。core.js 每 1s 用自定义事件 |
工具箱「接口调用」提示捕获层未加载 / | 扩展刚更新过:重载扩展 + 刷新页面(页面捕获层 |
| 属正常(页面 CSP 限制)。按「eval 与 CSP」章节开启扩展的「允许用户脚本」开关(开完需重载扩展);或改用其他 DOM 动作 |
| userScripts 需要 Chrome ≥ 135 且手动开启「允许用户脚本」开关( |
页面响应超时 / | 后台标签页被浏览器冻结(节流)。先 |
| 页面 DOM 变了(导航/重渲染),重新 |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Official Browserless MCP server: browser automation, scraping, screenshots and PDFs for AI agents.
Live browser debugging for AI assistants — DOM, console, network via MCP.
Control a real browser from AI agents: navigate, click, type, screenshot, read the page.
Web scraping, browser automation, screenshots and AI data extraction for AI agents via MCP.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to drive a live Chrome or Brave browser over stdio, with tools for navigation, clicking, typing, screenshots, and executing automation goals.4MIT

orchords-web-pilotofficial
FlicenseAqualityCmaintenanceEnables coding agents to drive a real Playwright-backed browser session, navigating, observing, interacting, and capturing proof on web pages via MCP tools across stdio and Streamable HTTP transports.152-- AlicenseNot gradedqualityAmaintenanceEnables an AI agent to observe, plan, and act inside a real browser session by exposing navigation, snapshot, click, type, and screenshot MCP tools over local JSON-RPC and SSE. It runs a Playwright-backed browser in-process and provides stable element references for reliable actions.MIT
- AlicenseNot gradedqualityAmaintenanceEnables MCP-compatible AI agents to control an anti-detection browser for navigation, interaction, search, extraction, downloads, multi-tab workflows, and persistent sessions. Supports stdio and HTTP transports for desktop or remote MCP clients.899 npmMIT