nexus-browser-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 pai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,181 @@
1
+ Metadata-Version: 2.4
2
+ Name: nexus-browser-mcp
3
+ Version: 0.1.0
4
+ Summary: 事件驱动确定性快照的浏览器操控 MCP 服务器 (Playwright + Accessibility Tree)
5
+ Author: pai
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/paipaipai666/nexus-broswer-mcp
8
+ Project-URL: Repository, https://github.com/paipaipai666/nexus-broswer-mcp
9
+ Project-URL: Issues, https://github.com/paipaipai666/nexus-broswer-mcp/issues
10
+ Keywords: mcp,browser,playwright,llm,agent,automation,accessibility-tree
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: mcp>=1.0
22
+ Requires-Dist: playwright>=1.59
23
+ Requires-Dist: pydantic<3,>=2.10
24
+ Requires-Dist: pydantic-settings>=2
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=8; extra == "dev"
27
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
28
+ Requires-Dist: pytest-mock>=3; extra == "dev"
29
+ Requires-Dist: ruff>=0.3; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # nexus-browser-mcp
33
+
34
+ **事件驱动确定性快照的浏览器操控 MCP 服务器。**
35
+
36
+ 基于 Playwright,通过 Accessibility Tree(无障碍树)让 LLM 驱动浏览器——导航、点击、输入、读取、表单、多标签。与市面同类产品(Playwright MCP 等)的核心差异:
37
+
38
+ 1. **确定性快照**:不靠固定间隔 `sleep` 硬等,而是注入 `MutationObserver` 记录最后一次 DOM 变异,由浏览器自身的 `requestAnimationFrame` 循环判定"页面已静默 `STABLE_WINDOW_MS`(默认 800ms)"后才提取快照。杜绝"快照抓在动画/加载中"的竞态。
39
+ 2. **内嵌治理门**:HITL 规则(如点击"支付/确认"需人工)、`browser_evaluate` 默认禁用+无条件确认、JSONL 审计(含敏感参数脱敏)。
40
+ 3. **多 task 隔离**:一个 MCP 连接(session)内可建多个独立 `task_id`,各自独立 BrowserContext(登录态互不污染),TTL 空闲回收、回收后再次使用时自动重建并恢复上次页面。
41
+ 4. **死亡可观测 + 自愈**:标签页/浏览器被外部关闭或崩溃后,下次调用自动重建(持久化 profile 登录态不丢),并在工具返回前置 `[状态变更]` 通知,明确告知"恢复了什么、丢了什么",不再泄漏 Playwright 底层异常。
42
+
43
+ ## 安装
44
+
45
+ ```bash
46
+ pip install nexus-browser-mcp
47
+ # 或
48
+ uvx nexus-browser-mcp
49
+ ```
50
+
51
+ 安装后提供 `nexus-browser-mcp` / `nexus-browser` 两个可执行入口;兜底启动方式(一定可用):`python -m nexus_browser.server`。
52
+
53
+ 依赖 `playwright` 及其浏览器内核:
54
+
55
+ ```bash
56
+ pip install playwright && playwright install chromium
57
+ ```
58
+
59
+ ## 接入(任意 MCP 客户端)
60
+
61
+ **opencode**(`~/.config/opencode/opencode.json`):
62
+
63
+ ```json
64
+ {
65
+ "mcp": {
66
+ "browser": {
67
+ "type": "local",
68
+ "command": ["uvx", "nexus-browser-mcp"],
69
+ "enabled": true
70
+ }
71
+ }
72
+ }
73
+ ```
74
+
75
+ **Claude Code**(`.mcp.json`,项目根):
76
+
77
+ ```json
78
+ {
79
+ "mcpServers": {
80
+ "browser": {
81
+ "type": "stdio",
82
+ "command": "uvx",
83
+ "args": ["nexus-browser-mcp"]
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ **Pi Coding Agent**:读取标准 MCP 配置 —— 项目 `.mcp.json` 或用户全局 `~/.config/mcp/mcp.json`,stdio 默认 transport:
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "browser": {
95
+ "command": "uvx",
96
+ "args": ["nexus-browser-mcp"]
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ 详细见 `docs/INTEGRATE.md`。
103
+
104
+ ## 使用你自己的浏览器(带登录态)
105
+
106
+ 默认 `isolated` 模式启动 Playwright 内置 Chromium,**不带你的 cookie/登录态**。要用你自己的浏览器,二选一:
107
+
108
+ **方式 A — 直接加载你的浏览器 profile(推荐,最省事)**
109
+
110
+ 用系统 Chrome 加载你平时的用户数据目录(Cookie/登录态/书签都在):
111
+
112
+ ```
113
+ BROWSER_CHANNEL=chrome
114
+ BROWSER_USER_DATA_DIR="C:\Users\你的用户名\AppData\Local\Google\Chrome\User Data"
115
+ ```
116
+
117
+ > 注意:用自己的 User Data 时,进程会占用浏览器,期间你自己开 Chrome 会冲突。建议复制一份 profile 或用独立的 `--user-data-dir` 指向一个专用目录。
118
+
119
+ **推荐做法:工具专用 profile(不与日常浏览器冲突)**
120
+
121
+ 用 `BROWSER_CHANNEL=chrome` + 指向一个专用 user data 目录(如 `C:\Users\<你>\.nexus-browser\chrome-profile`):
122
+
123
+ ```
124
+ BROWSER_CHANNEL=chrome
125
+ BROWSER_USER_DATA_DIR="C:\Users\你的用户名\.nexus-browser\chrome-profile"
126
+ ```
127
+
128
+ 首次使用需要在 agent 调浏览器工具时弹出的专用 Chrome 里**登录一次**目标网站,之后 cookie 永久保存在该 profile,agent 从此自带登录态;且与你日常浏览器完全隔离,互不干扰。
129
+
130
+ **方式 B — CDP 连接运行中的 Chrome**
131
+
132
+ 先启动: `chrome --remote-debugging-port=9222`,然后 `BROWSER_MODE=cdp`。
133
+
134
+ > 若 CDP 连接失败,服务器现在会**明确报错**(不再静默启动全新浏览器),提示你先启动调试端口浏览器。
135
+
136
+ ## 配置(环境变量)
137
+
138
+ 所有可选项通过 `BROWSER_` 前缀环境变量覆盖:
139
+
140
+ | 变量 | 默认 | 说明 |
141
+ |---|---|---|
142
+ | `BROWSER_MODE` | `isolated` | `isolated`(隔离新浏览器) / `cdp`(连你的 Chrome) |
143
+ | `BROWSER_CDP_ENDPOINT` | `http://localhost:9222` | CDP 地址 |
144
+ | `BROWSER_CHANNEL` | `""` | 系统浏览器通道: `chrome`/`msedge` 等(空=Playwright 内置 Chromium) |
145
+ | `BROWSER_USER_DATA_DIR` | `""` | 用户数据目录(带登录态)。设置后为共享登录态的 persistent context, 多 task 共享。空=全新 profile |
146
+ | `BROWSER_HEADLESS` | `false` | 无头模式(仅 isolated) |
147
+ | `BROWSER_DEFAULT_TIMEOUT_MS` | `30000` | Playwright 单次操作超时(导航等) |
148
+ | `BROWSER_TOOL_TIMEOUT_MS` | `60000` | 单次工具调用的外层超时护栏(超时返回 ERROR, 不挂死) |
149
+ | `BROWSER_STABLE_WINDOW_MS` | `800` | DOM 静默窗口: 无变异持续多久判"稳定" |
150
+ | `BROWSER_STABLE_REQUIRED` | `2` | 稳定后连拍确认快照数(防纯动画/非 DOM 变化) |
151
+ | `BROWSER_STABLE_TIMEOUT_MS` | `3000` | 稳定性等待总超时, 超时优雅降级 |
152
+ | `BROWSER_SNAPSHOT_MAX_NODES` | `100` | 快照最大节点数 |
153
+ | `BROWSER_CONTEXT_TTL_SEC` | `600` | 空闲 task 自动回收(秒) |
154
+ | `BROWSER_STREAM_CHAR_CAP` | `16000` | 单条流式缓冲最大字符数(溢出丢最旧,保留丢弃标记) |
155
+ | `BROWSER_STREAM_PAGE_CAP` | `64000` | 单页面全部流的总字符上限 |
156
+ | `BROWSER_ALLOW_JS_EXECUTION` | `false` | 是否允许 `browser_evaluate`(开启后无条件 HITL) |
157
+ | `BROWSER_HITL_RULES` | `[]` | JSON 数组: HITL 规则, 如 `[{"action":"click","name_pattern":"支付|确认"}]` |
158
+ | `BROWSER_AUDIT_PATH` | `~/.nexus-browser/audit.jsonl` | 审计日志路径 |
159
+
160
+ ## 工具
161
+
162
+ 20 个工具:`browser_navigate`、`browser_snapshot`、`browser_click`、`browser_type`、`browser_read`、`browser_screenshot`、`browser_evaluate`、`browser_wait`、`browser_wait_stable`、`browser_wait_ms`、`browser_scroll`、`browser_scroll_to`、`browser_wait_navigation`、`browser_dismiss_popup`、`browser_list_pages`、`browser_switch_page` 及 4 个生命周期工具 `browser_tasks`、`browser_close_task`、`browser_list_sessions`、`browser_close_session`。
163
+
164
+ 流式内容(AI 回复等):`browser_read(wait_stable=true)` 等 DOM 静默后一次读全;`browser_read(selector=..., follow=true)` 增量跟踪,每次只回新增部分,`full=true` 取缓冲全文。`browser_wait_stable` / `browser_wait_ms` 提供事件驱动等待与纯等待两种原语。
165
+
166
+ 多数工具接受可选 `task_id`(不传则用默认 task)。见 `docs/` 中的用法指南。
167
+
168
+ ## 开发
169
+
170
+ ```bash
171
+ uv venv
172
+ uv pip install -e ".[dev]"
173
+ python -m pytest tests -q
174
+ ruff check src tests
175
+ python -m smokes.test_e2e # 真实浏览器冒烟
176
+ python -m smokes.test_e2e_interact # 表单 + 多 task 冒烟
177
+ ```
178
+
179
+ ## License
180
+
181
+ MIT
@@ -0,0 +1,150 @@
1
+ # nexus-browser-mcp
2
+
3
+ **事件驱动确定性快照的浏览器操控 MCP 服务器。**
4
+
5
+ 基于 Playwright,通过 Accessibility Tree(无障碍树)让 LLM 驱动浏览器——导航、点击、输入、读取、表单、多标签。与市面同类产品(Playwright MCP 等)的核心差异:
6
+
7
+ 1. **确定性快照**:不靠固定间隔 `sleep` 硬等,而是注入 `MutationObserver` 记录最后一次 DOM 变异,由浏览器自身的 `requestAnimationFrame` 循环判定"页面已静默 `STABLE_WINDOW_MS`(默认 800ms)"后才提取快照。杜绝"快照抓在动画/加载中"的竞态。
8
+ 2. **内嵌治理门**:HITL 规则(如点击"支付/确认"需人工)、`browser_evaluate` 默认禁用+无条件确认、JSONL 审计(含敏感参数脱敏)。
9
+ 3. **多 task 隔离**:一个 MCP 连接(session)内可建多个独立 `task_id`,各自独立 BrowserContext(登录态互不污染),TTL 空闲回收、回收后再次使用时自动重建并恢复上次页面。
10
+ 4. **死亡可观测 + 自愈**:标签页/浏览器被外部关闭或崩溃后,下次调用自动重建(持久化 profile 登录态不丢),并在工具返回前置 `[状态变更]` 通知,明确告知"恢复了什么、丢了什么",不再泄漏 Playwright 底层异常。
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ pip install nexus-browser-mcp
16
+ # 或
17
+ uvx nexus-browser-mcp
18
+ ```
19
+
20
+ 安装后提供 `nexus-browser-mcp` / `nexus-browser` 两个可执行入口;兜底启动方式(一定可用):`python -m nexus_browser.server`。
21
+
22
+ 依赖 `playwright` 及其浏览器内核:
23
+
24
+ ```bash
25
+ pip install playwright && playwright install chromium
26
+ ```
27
+
28
+ ## 接入(任意 MCP 客户端)
29
+
30
+ **opencode**(`~/.config/opencode/opencode.json`):
31
+
32
+ ```json
33
+ {
34
+ "mcp": {
35
+ "browser": {
36
+ "type": "local",
37
+ "command": ["uvx", "nexus-browser-mcp"],
38
+ "enabled": true
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ **Claude Code**(`.mcp.json`,项目根):
45
+
46
+ ```json
47
+ {
48
+ "mcpServers": {
49
+ "browser": {
50
+ "type": "stdio",
51
+ "command": "uvx",
52
+ "args": ["nexus-browser-mcp"]
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ **Pi Coding Agent**:读取标准 MCP 配置 —— 项目 `.mcp.json` 或用户全局 `~/.config/mcp/mcp.json`,stdio 默认 transport:
59
+
60
+ ```json
61
+ {
62
+ "mcpServers": {
63
+ "browser": {
64
+ "command": "uvx",
65
+ "args": ["nexus-browser-mcp"]
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ 详细见 `docs/INTEGRATE.md`。
72
+
73
+ ## 使用你自己的浏览器(带登录态)
74
+
75
+ 默认 `isolated` 模式启动 Playwright 内置 Chromium,**不带你的 cookie/登录态**。要用你自己的浏览器,二选一:
76
+
77
+ **方式 A — 直接加载你的浏览器 profile(推荐,最省事)**
78
+
79
+ 用系统 Chrome 加载你平时的用户数据目录(Cookie/登录态/书签都在):
80
+
81
+ ```
82
+ BROWSER_CHANNEL=chrome
83
+ BROWSER_USER_DATA_DIR="C:\Users\你的用户名\AppData\Local\Google\Chrome\User Data"
84
+ ```
85
+
86
+ > 注意:用自己的 User Data 时,进程会占用浏览器,期间你自己开 Chrome 会冲突。建议复制一份 profile 或用独立的 `--user-data-dir` 指向一个专用目录。
87
+
88
+ **推荐做法:工具专用 profile(不与日常浏览器冲突)**
89
+
90
+ 用 `BROWSER_CHANNEL=chrome` + 指向一个专用 user data 目录(如 `C:\Users\<你>\.nexus-browser\chrome-profile`):
91
+
92
+ ```
93
+ BROWSER_CHANNEL=chrome
94
+ BROWSER_USER_DATA_DIR="C:\Users\你的用户名\.nexus-browser\chrome-profile"
95
+ ```
96
+
97
+ 首次使用需要在 agent 调浏览器工具时弹出的专用 Chrome 里**登录一次**目标网站,之后 cookie 永久保存在该 profile,agent 从此自带登录态;且与你日常浏览器完全隔离,互不干扰。
98
+
99
+ **方式 B — CDP 连接运行中的 Chrome**
100
+
101
+ 先启动: `chrome --remote-debugging-port=9222`,然后 `BROWSER_MODE=cdp`。
102
+
103
+ > 若 CDP 连接失败,服务器现在会**明确报错**(不再静默启动全新浏览器),提示你先启动调试端口浏览器。
104
+
105
+ ## 配置(环境变量)
106
+
107
+ 所有可选项通过 `BROWSER_` 前缀环境变量覆盖:
108
+
109
+ | 变量 | 默认 | 说明 |
110
+ |---|---|---|
111
+ | `BROWSER_MODE` | `isolated` | `isolated`(隔离新浏览器) / `cdp`(连你的 Chrome) |
112
+ | `BROWSER_CDP_ENDPOINT` | `http://localhost:9222` | CDP 地址 |
113
+ | `BROWSER_CHANNEL` | `""` | 系统浏览器通道: `chrome`/`msedge` 等(空=Playwright 内置 Chromium) |
114
+ | `BROWSER_USER_DATA_DIR` | `""` | 用户数据目录(带登录态)。设置后为共享登录态的 persistent context, 多 task 共享。空=全新 profile |
115
+ | `BROWSER_HEADLESS` | `false` | 无头模式(仅 isolated) |
116
+ | `BROWSER_DEFAULT_TIMEOUT_MS` | `30000` | Playwright 单次操作超时(导航等) |
117
+ | `BROWSER_TOOL_TIMEOUT_MS` | `60000` | 单次工具调用的外层超时护栏(超时返回 ERROR, 不挂死) |
118
+ | `BROWSER_STABLE_WINDOW_MS` | `800` | DOM 静默窗口: 无变异持续多久判"稳定" |
119
+ | `BROWSER_STABLE_REQUIRED` | `2` | 稳定后连拍确认快照数(防纯动画/非 DOM 变化) |
120
+ | `BROWSER_STABLE_TIMEOUT_MS` | `3000` | 稳定性等待总超时, 超时优雅降级 |
121
+ | `BROWSER_SNAPSHOT_MAX_NODES` | `100` | 快照最大节点数 |
122
+ | `BROWSER_CONTEXT_TTL_SEC` | `600` | 空闲 task 自动回收(秒) |
123
+ | `BROWSER_STREAM_CHAR_CAP` | `16000` | 单条流式缓冲最大字符数(溢出丢最旧,保留丢弃标记) |
124
+ | `BROWSER_STREAM_PAGE_CAP` | `64000` | 单页面全部流的总字符上限 |
125
+ | `BROWSER_ALLOW_JS_EXECUTION` | `false` | 是否允许 `browser_evaluate`(开启后无条件 HITL) |
126
+ | `BROWSER_HITL_RULES` | `[]` | JSON 数组: HITL 规则, 如 `[{"action":"click","name_pattern":"支付|确认"}]` |
127
+ | `BROWSER_AUDIT_PATH` | `~/.nexus-browser/audit.jsonl` | 审计日志路径 |
128
+
129
+ ## 工具
130
+
131
+ 20 个工具:`browser_navigate`、`browser_snapshot`、`browser_click`、`browser_type`、`browser_read`、`browser_screenshot`、`browser_evaluate`、`browser_wait`、`browser_wait_stable`、`browser_wait_ms`、`browser_scroll`、`browser_scroll_to`、`browser_wait_navigation`、`browser_dismiss_popup`、`browser_list_pages`、`browser_switch_page` 及 4 个生命周期工具 `browser_tasks`、`browser_close_task`、`browser_list_sessions`、`browser_close_session`。
132
+
133
+ 流式内容(AI 回复等):`browser_read(wait_stable=true)` 等 DOM 静默后一次读全;`browser_read(selector=..., follow=true)` 增量跟踪,每次只回新增部分,`full=true` 取缓冲全文。`browser_wait_stable` / `browser_wait_ms` 提供事件驱动等待与纯等待两种原语。
134
+
135
+ 多数工具接受可选 `task_id`(不传则用默认 task)。见 `docs/` 中的用法指南。
136
+
137
+ ## 开发
138
+
139
+ ```bash
140
+ uv venv
141
+ uv pip install -e ".[dev]"
142
+ python -m pytest tests -q
143
+ ruff check src tests
144
+ python -m smokes.test_e2e # 真实浏览器冒烟
145
+ python -m smokes.test_e2e_interact # 表单 + 多 task 冒烟
146
+ ```
147
+
148
+ ## License
149
+
150
+ MIT
@@ -0,0 +1,56 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "nexus-browser-mcp"
7
+ version = "0.1.0"
8
+ description = "事件驱动确定性快照的浏览器操控 MCP 服务器 (Playwright + Accessibility Tree)"
9
+ license = {text = "MIT"}
10
+ readme = "README.md"
11
+ authors = [{name = "pai"}]
12
+ keywords = ["mcp", "browser", "playwright", "llm", "agent", "automation", "accessibility-tree"]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ ]
22
+ requires-python = ">=3.11"
23
+ dependencies = [
24
+ "mcp>=1.0",
25
+ "playwright>=1.59",
26
+ "pydantic>=2.10,<3",
27
+ "pydantic-settings>=2",
28
+ ]
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/paipaipai666/nexus-broswer-mcp"
32
+ Repository = "https://github.com/paipaipai666/nexus-broswer-mcp"
33
+ Issues = "https://github.com/paipaipai666/nexus-broswer-mcp/issues"
34
+
35
+ [project.scripts]
36
+ nexus-browser-mcp = "nexus_browser.server:main"
37
+ nexus-browser = "nexus_browser.server:main"
38
+
39
+ [project.optional-dependencies]
40
+ dev = ["pytest>=8", "pytest-asyncio>=0.23", "pytest-mock>=3", "ruff>=0.3"]
41
+
42
+ [tool.setuptools.packages.find]
43
+ where = ["src"]
44
+
45
+ [tool.pytest.ini_options]
46
+ testpaths = ["tests"]
47
+ pythonpath = ["src"]
48
+ asyncio_mode = "auto"
49
+
50
+ [tool.ruff]
51
+ line-length = 120
52
+ target-version = "py311"
53
+
54
+ [tool.ruff.lint]
55
+ select = ["E", "F", "I", "W"]
56
+ ignore = ["E402", "E501"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """nexus-browser-mcp: 事件驱动确定性快照的浏览器操控 MCP 服务器。"""
2
+
3
+ __version__ = "0.1.0"