MCP Server for ruyiPage Firefox Automation
将 ruyiPage 的 Firefox BiDi 自动化能力,通过 MCP (Model Context Protocol) 暴露为 AI 可调用的工具集。
支持 Claude Code、Cursor 等任意 MCP 客户端。
- 34 个工具,覆盖浏览器自动化全流程:启动/接管浏览器、页面导航、DOM 查找与交互、截图/PDF、Cookie/Storage、JS 执行、网络拦截/监听/数据采集、标签页管理、设备模拟、BiDi 事件订阅
- 原生 BiDi 动作优先 — 点击、输入、拖拽等操作保持
isTrusted=true,更适合高风控场景 - 支持接管指纹浏览器 — 可自动探测并接管 ADS / FlowerBrowser 等 Firefox 内核指纹浏览器
- 智能元素管理 — LRU 元素注册表,自动回收 + 过期元素自动重查
- 截图自动压缩 — 超宽图片自动缩放,JPEG 压缩,大图自动落盘
- stdio 传输 — 标准 JSON-RPC 2.0,开箱即用
- Python >= 3.10
- ruyiPage >= 1.1.0
- Firefox 浏览器(推荐使用 ruyiPage 配套的 Firefox 内核)
git clone https://github.com/LoseNine/ruyipage-mcp.git
cd ruyipage-mcp
pip install -e .方式一: 项目级 .mcp.json(推荐)
{
"mcpServers": {
"ruyipage": {
"command": "python",
"args": ["-m", "ruyipage_mcp"]
}
}
}在对应 MCP 配置文件中添加:
{
"mcpServers": {
"ruyipage": {
"command": "python",
"args": ["-m", "ruyipage_mcp"]
}
}
}python -m ruyipage_mcp服务器通过 stdin/stdout 传输 JSON-RPC 消息,日志输出到 stderr。
将 ruyipage_mcp.example.json 复制为 ruyipage_mcp.json,按需修改:
cp ruyipage_mcp.example.json ruyipage_mcp.json{
"browser_path": "E:\\ruyi_firefox\\firefox.exe",
"disable_run_js": false,
"disable_extensions": false,
"browser_path_whitelist": [],
"max_elements": 512,
"event_buffer_size": 500,
"wait_timeout_ceiling": 60
}配置文件查找顺序:
RUYIPAGE_MCP_CONFIG环境变量指定的路径- 当前工作目录下的
ruyipage_mcp.json - 若未找到配置文件,使用内置默认值
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
browser_path |
string | E:\ruyi_firefox\firefox.exe |
Firefox 可执行文件路径 |
disable_run_js |
bool | false |
设为 true 禁用 js_run 工具 |
disable_extensions |
bool | false |
设为 true 禁用扩展相关能力 |
browser_path_whitelist |
list | [] (允许任意路径) |
允许的浏览器路径列表 |
max_elements |
int | 512 |
每个会话的元素注册表 LRU 容量 |
event_buffer_size |
int | 500 |
BiDi 事件缓冲区大小 |
wait_timeout_ceiling |
int | 60 |
所有等待类工具的超时上限(秒) |
环境变量优先级高于配置文件,适合 CI 或临时覆盖场景:
| 环境变量 | 对应配置项 |
|---|---|
RUYIPAGE_MCP_BROWSER_PATH |
browser_path |
RUYIPAGE_MCP_DISABLE_RUN_JS |
disable_run_js (1 = true) |
RUYIPAGE_MCP_DISABLE_EXTENSIONS |
disable_extensions (1 = true) |
RUYIPAGE_MCP_BROWSER_PATH_WHITELIST |
browser_path_whitelist (逗号分隔) |
RUYIPAGE_MCP_MAX_ELEMENTS |
max_elements |
RUYIPAGE_MCP_EVENT_BUFFER_SIZE |
event_buffer_size |
RUYIPAGE_MCP_WAIT_TIMEOUT_CEILING |
wait_timeout_ceiling |
RUYIPAGE_MCP_CONFIG |
指定配置文件路径 |
| 工具 | 说明 |
|---|---|
session_launch |
启动新 Firefox 浏览器。支持自定义端口、无头模式、隐私模式、XPath Picker、窗口大小等 |
session_attach |
通过 host:port 接管已运行的 Firefox |
session_auto_attach |
按进程特征自动探测并接管 Firefox / ADS / FlowerBrowser |
session_quit |
关闭浏览器会话。owned 会话直接关闭进程,attached 会话仅释放连接 |
典型流程:
session_launch(port=9222)
→ 操作页面...
→ session_quit()
# 接管已打开的指纹浏览器
session_auto_attach(latest_tab=true)
→ 操作页面...
→ session_quit() # 仅释放连接,浏览器继续运行
| 工具 | 说明 |
|---|---|
nav_get |
打开 URL,支持 complete / interactive / none 等待策略 |
nav_back |
后退 |
nav_forward |
前进 |
nav_refresh |
刷新 |
nav_info |
获取当前页面的 URL、标题、ready state |
| 工具 | 说明 |
|---|---|
dom_find |
查找单个元素,返回 element_id。支持 #id、css:、xpath:、text:、tag: 定位 |
dom_find_all |
查找所有匹配元素,返回列表(默认上限 20,最大 100) |
dom_read |
读取元素属性:text / html / inner_html / outer_html / value / attrs / rect / all |
dom_query_in |
在已有元素内部继续查找子元素 |
dom_wait_for |
等待元素出现(带超时) |
dom_release |
释放元素句柄,回收注册表空间 |
定位器格式:
| 格式 | 示例 | 说明 |
|---|---|---|
#id |
#search-box |
ID 选择器 |
css: |
css:div.card > a |
CSS 选择器 |
xpath: |
xpath://button[text()='Login'] |
XPath |
text: |
text:登录 |
文本匹配 |
tag: |
tag:input |
标签名 |
| 工具 | 说明 |
|---|---|
act_click |
点击元素。支持左键 / 右键 / 双击,可选 JS 点击。默认使用原生 BiDi 动作 (isTrusted=true) |
act_input |
输入文本。原生 BiDi 键盘输入,可选清空已有内容。支持 JS 回退 |
act_simple |
简单操作:hover / clear / focus / scroll_into_view |
act_chain |
执行 BiDi 动作链(JSON 数组),支持按键、点击、移动、拖拽、滚轮、暂停等 |
act_chain 支持的动作:
[
{"action": "press", "key": "Enter"},
{"action": "click"},
{"action": "click", "element_id": "el_abc123"},
{"action": "move_to", "element_id": "el_abc123"},
{"action": "move_to", "x": 100, "y": 200},
{"action": "double_click"},
{"action": "right_click"},
{"action": "key_down", "key": "Shift"},
{"action": "key_up", "key": "Shift"},
{"action": "type", "text": "hello"},
{"action": "scroll", "x": 0, "y": -300},
{"action": "pause", "duration": 500}
]| 工具 | 说明 |
|---|---|
state_screenshot |
截图。支持全页面截图、元素截图、保存到文件。自动压缩,超大图自动落盘 |
state_save_pdf |
将当前页面保存为 PDF |
state_cookies |
Cookie 管理:get / set / delete。支持按 name/domain 过滤 |
state_storage |
localStorage / sessionStorage 管理:items / get / set / delete / clear |
| 工具 | 说明 |
|---|---|
js_run |
在页面中执行 JS 代码。可作为表达式求值 (as_expr=true) 或函数体执行。可通过环境变量禁用 |
js_preload |
管理 preload script:add(每次页面加载前注入)/ remove |
| 工具 | 说明 |
|---|---|
net_intercept |
请求拦截:start → wait_and_resolve(continue/mock/fail)→ stop |
net_listen |
网络监听:start → wait(按 URL/method 过滤)→ stop |
net_collector |
数据采集器:add → get(按 request_id 获取请求/响应体)→ remove |
net_headers |
设置/清除额外请求头 |
net_cache |
设置缓存行为:default(正常缓存)/ bypass(强制重新请求) |
请求拦截典型流程:
net_intercept(op="start", url_patterns="api/login")
→ 触发页面操作
→ net_intercept(op="wait_and_resolve", action='{"mode":"mock","status":200,"body":"{}"}')
→ net_intercept(op="stop")
网络监听典型流程:
net_listen(op="start", targets="api/data", method="POST")
→ 触发页面操作
→ net_listen(op="wait", timeout=10)
→ net_listen(op="stop")
| 工具 | 说明 |
|---|---|
ctx_tabs |
标签页管理:list / create / close / activate / reload |
ctx_emulation |
设备模拟:地理位置、时区、语言、移动设备预设、离线模式、JS 开关 |
ctx_events |
BiDi 事件订阅:统一入口管理 page.events / page.navigation / page.downloads |
模拟操作示例:
ctx_emulation(op="set_geolocation", latitude=39.9, longitude=116.4)
ctx_emulation(op="set_timezone", timezone_id="Asia/Tokyo")
ctx_emulation(op="set_locale", locales="ja-JP,ja")
ctx_emulation(op="apply_mobile_preset", width=390, height=844, device_pixel_ratio=3)
ctx_emulation(op="set_offline", enabled=true)
ctx_emulation(op="set_offline", enabled=false)
| 工具 | 说明 |
|---|---|
ruyipage_describe_capabilities |
返回当前服务器状态:活跃会话、元素数量、配置开关、工具命名空间列表 |
每个浏览器连接对应一个 session,以 host:port(如 127.0.0.1:9222)作为标识。
- 当只有一个活跃 session 时,所有工具的
session_id参数可省略,自动解析 - 有多个 session 时,需要显式传入
session_id session_launch创建的是 owned 会话,session_quit会终止浏览器进程session_attach/session_auto_attach创建的是 attached 会话,session_quit仅释放连接
通过 dom_find / dom_find_all 查到的元素会被注册到当前 session 的元素注册表中,返回一个短 ID(如 el_a3f2b1)。
- LRU 回收 — 达到容量上限(默认 512)时,最久未使用的元素自动回收
- 过期自动恢复 — 访问过期元素时,自动尝试用原始定位器重新查找
- 元素 ID 可传给
act_click、act_input、dom_read、act_chain等所有需要元素引用的工具 - 所有接受
target参数的工具也可直接传入定位器字符串(如css:button.submit),无需先调用dom_find
所有工具(state_screenshot 除外)返回统一 JSON 信封:
// 成功
{"ok": true, "data": ...}
// 失败
{"ok": false, "error": "error message"}state_screenshot 在截图体积允许时直接返回 MCP Image 对象;超过 800KB 时落盘返回文件路径。
- ruyiPage — 核心 Firefox BiDi 自动化库
- ruyipage-skill — AI 自动化分析运行 Skill
- Firefox 指纹浏览器 — 配套 Firefox 指纹环境
python -m ruyipage_mcp
→ __main__.py → server.run()
→ 导入 tools/*.py(触发 @mcp.tool() 注册 34 个工具)
→ 注册 atexit 清理(退出时关闭 owned 浏览器)
→ mcp.run(transport="stdio")
ruyipage_mcp/
├── app.py # FastMCP("ruyipage-mcp") 单例
├── config.py # 环境变量配置
├── registries.py # SessionRegistry + ElementRegistry (LRU)
├── runtime.py # async/sync 桥接 + 响应封装 + 元素解析
├── server.py # 入口 + atexit 清理
└── tools/
├── session.py # 浏览器启动/接管/关闭
├── nav.py # 页面导航
├── dom.py # 元素查找/读取
├── act.py # 元素交互/动作链
├── state.py # 截图/PDF/Cookie/Storage
├── js.py # JS 执行/预加载脚本
├── net.py # 网络拦截/监听/采集
├── ctx.py # 标签页/模拟/事件
└── meta.py # 服务器状态
ruyiPage 是同步库,MCP FastMCP 是 asyncio。所有 ruyiPage 调用通过 asyncio.to_thread() 桥接,确保 MCP 事件循环不被阻塞。
本项目遵循 ruyiPage 的使用声明,仅限合法、合规、非盈利的个人研究与技术交流用途。
BSD-3-Clause