基于ruyipage写的mcp工具
ruyipage-mcp
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 .
也可以直接把github连接给ai,让ai帮你装
配置
Claude Code
方式一: 项目级 .mcp.json(推荐)
{
"mcpServers": {
"ruyipage": {
"command": "python",
"args": ["-m", "ruyipage_mcp"]
}
}
}
Cursor / 其他 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 | 指定配置文件路径 |
工具一览 (34 个)
session — 浏览器生命周期
| 工具 | 说明 |
|------|------|
| 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 — 页面导航
| 工具 | 说明 |
|------|------|
| nav_get | 打开 URL,支持 complete / interactive / none 等待策略 |
| nav_back | 后退 |
| nav_forward | 前进 |
| nav_refresh | 刷新 |
| nav_info | 获取当前页面的 URL、标题、ready state |
dom — 元素查找与读取
| 工具 | 说明 |
|------|------|
| 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 — 元素交互
| 工具 | 说明 |
|------|------|
| 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 — 页面状态
| 工具 | 说明 |
|------|------|
| state_screenshot | 截图。支持全页面截图、元素截图、保存到文件。自动压缩,超大图自动落盘 |
| state_save_pdf | 将当前页面保存为 PDF |
| state_cookies | Cookie 管理:get / set / delete。支持按 name/domain 过滤 |
| state_storage | localStorage / sessionStorage 管理:items / get / set / delete / clear |
js — JavaScript 执行
| 工具 | 说明 |
|------|------|
| js_run | 在页面中执行 JS 代码。可作为表达式求值 (as_expr=true) 或函数体执行。可通过环境变量禁用 |
| js_preload | 管理 preload script:add(每次页面加载前注入)/ remove |
net — 网络控制
| 工具 | 说明 |
|------|------|
| 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 — 上下文管理
| 工具 | 说明 |
|------|------|
| 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)
meta — 服务器信息
| 工具 | 说明 |
|------|------|
| 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 的使用声明,仅限合法、合规、非盈利的个人研究与技术交流用途。
License
BSD-3-Clause