Browser MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Browser MCPopen news.ycombinator.com, snapshot the page, and click the top story"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 为准)
┌─ 浏览器(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) |
| 本机生效的 MCP 接入配置(stdio 方式,MCP 客户端自动拉起 broker) |
| 可复制的 MCP 配置模板,把 |
| 外部 CLI 接入示例(纯标准库):发现 → 校验 URL → 接入 → LLM 驱动循环 |
| 接入端(唯一方案):Chrome 扩展 MV3 |
├ | 扩展清单:权限、注入规则( |
├ | Service Worker:每个标签页维持一条到 broker 的 WebSocket;命令路由(DOM 动作转发给 content,截图/标签管理自己执行);站点白名单过滤;webRequest 观察模式接口捕获(URL/请求头/请求体/响应头) |
├ | 白名单核心:配置存储、eTLD+1 主域名提取、匹配引擎(SW/popup/options 共用) |
├ | 工具栏弹窗:接入总开关、当前页白名单状态、一键加入/移出 |
├ | 完整配置页:域名列表与正则规则的增删改查、导入导出、正则实时测试面板 |
├ | 页面捕获层( |
├ | 内容脚本:每个标签页一个实例,负责 DOM 快照与动作执行(click/type/eval 等);并为页面工具箱转发扩展桥消息( |
└ | 页面工具箱(设计原型 |
| 早期油猴脚本版,已停止维护、仅作存档;接入请一律使用 Chrome 扩展 |
| 早期调研笔记(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 实例会报错退出,此时改用方式二
不要把
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),带 |
page 可传标记 id 或 pid;只有一个在线页面时可省略。工具调用与 /call 走同一条转发链路,超时上限同样 120s。
HTTP API(不走 MCP 的直接接入)
MCP 工具底层就是这套 HTTP 接口;自己写脚本/编排框架、或不想用 MCP 的客户端可以直接调(无需 SDK,curl 即可验证)。
接口 | 用途 |
| 发现:在线页面列表(id / url / title / mode / ago / eval_mode) |
| 订阅广播(SSE): |
| 执行一条命令:body 为命令 JSON, |
| 列出全部页桥标记: |
| 按标记查网页:返回在线状态、 |
| 按标记执行命令(body 同 |
| 长连接:收广播 + 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) |
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.comrun 的循环就是「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(可拖拽、位置记忆、
Alt+Shift+D唤起),六分类 36 项功能(提示 / 查找 / 样式与屏蔽 / 发给 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 变了(导航/重渲染),重新 |
This server cannot be deployed
Maintenance
Related MCP Connectors
A real Chromium browser agents pay for per action in USDC via x402 — hosted MCP, free local stdio.
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.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables MCP clients to drive a live Chrome or Brave browser over stdio, with tools for navigation, clicking, typing, screenshots, and executing automation goals.3MIT

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-- AlicenseAqualityCmaintenanceEnables any MCP-capable agent to drive a real Chrome browser through stdio or HTTP, supporting navigation, page reading, interaction, scrolling, JavaScript execution, and replaying saved step-by-step recipes.24Apache 2.0
- 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