@pyrokine/mcp-chrome 1.7.0 → 2.0.1
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.
- package/README.md +71 -31
- package/dist/anti-detection/behavior.d.ts.map +1 -1
- package/dist/anti-detection/behavior.js.map +1 -1
- package/dist/anti-detection/index.d.ts +1 -1
- package/dist/anti-detection/index.d.ts.map +1 -1
- package/dist/anti-detection/index.js +1 -1
- package/dist/anti-detection/index.js.map +1 -1
- package/dist/anti-detection/injection.d.ts +6 -2
- package/dist/anti-detection/injection.d.ts.map +1 -1
- package/dist/anti-detection/injection.js +34 -80
- package/dist/anti-detection/injection.js.map +1 -1
- package/dist/cdp/client.d.ts +2 -2
- package/dist/cdp/client.d.ts.map +1 -1
- package/dist/cdp/client.js +8 -10
- package/dist/cdp/client.js.map +1 -1
- package/dist/cdp/index.d.ts.map +1 -1
- package/dist/cdp/index.js.map +1 -1
- package/dist/cdp/launcher.d.ts.map +1 -1
- package/dist/cdp/launcher.js +40 -13
- package/dist/cdp/launcher.js.map +1 -1
- package/dist/core/auto-wait.d.ts +2 -2
- package/dist/core/auto-wait.d.ts.map +1 -1
- package/dist/core/auto-wait.js +2 -2
- package/dist/core/auto-wait.js.map +1 -1
- package/dist/core/browser-driver.d.ts +307 -0
- package/dist/core/browser-driver.d.ts.map +1 -0
- package/dist/core/browser-driver.js +21 -0
- package/dist/core/browser-driver.js.map +1 -0
- package/dist/core/error-sanitizer.d.ts +25 -0
- package/dist/core/error-sanitizer.d.ts.map +1 -0
- package/dist/core/error-sanitizer.js +66 -0
- package/dist/core/error-sanitizer.js.map +1 -0
- package/dist/core/errors.d.ts +10 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +17 -4
- package/dist/core/errors.js.map +1 -1
- package/dist/core/extension-errors.d.ts +20 -0
- package/dist/core/extension-errors.d.ts.map +1 -0
- package/dist/core/extension-errors.js +40 -0
- package/dist/core/extension-errors.js.map +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/locator.d.ts +2 -2
- package/dist/core/locator.d.ts.map +1 -1
- package/dist/core/locator.js +25 -65
- package/dist/core/locator.js.map +1 -1
- package/dist/core/retry.d.ts +2 -2
- package/dist/core/retry.d.ts.map +1 -1
- package/dist/core/retry.js +2 -2
- package/dist/core/retry.js.map +1 -1
- package/dist/core/session.d.ts +149 -46
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +673 -181
- package/dist/core/session.js.map +1 -1
- package/dist/core/types.d.ts +9 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +13 -6
- package/dist/core/types.js.map +1 -1
- package/dist/core/unified-session.d.ts +46 -85
- package/dist/core/unified-session.d.ts.map +1 -1
- package/dist/core/unified-session.js +341 -650
- package/dist/core/unified-session.js.map +1 -1
- package/dist/core/utils.d.ts +7 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/core/utils.js +33 -0
- package/dist/core/utils.js.map +1 -0
- package/dist/extension/bridge.d.ts +69 -52
- package/dist/extension/bridge.d.ts.map +1 -1
- package/dist/extension/bridge.js +242 -111
- package/dist/extension/bridge.js.map +1 -1
- package/dist/extension/http-server.d.ts +6 -4
- package/dist/extension/http-server.d.ts.map +1 -1
- package/dist/extension/http-server.js +45 -31
- package/dist/extension/http-server.js.map +1 -1
- package/dist/extension/index.d.ts.map +1 -1
- package/dist/extension/index.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/browse.d.ts.map +1 -1
- package/dist/tools/browse.js +32 -34
- package/dist/tools/browse.js.map +1 -1
- package/dist/tools/cookies.d.ts.map +1 -1
- package/dist/tools/cookies.js +38 -16
- package/dist/tools/cookies.js.map +1 -1
- package/dist/tools/evaluate.d.ts.map +1 -1
- package/dist/tools/evaluate.js +54 -23
- package/dist/tools/evaluate.js.map +1 -1
- package/dist/tools/extract.d.ts.map +1 -1
- package/dist/tools/extract.js +221 -153
- package/dist/tools/extract.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/input.d.ts.map +1 -1
- package/dist/tools/input.js +281 -89
- package/dist/tools/input.js.map +1 -1
- package/dist/tools/logs.d.ts.map +1 -1
- package/dist/tools/logs.js +31 -17
- package/dist/tools/logs.js.map +1 -1
- package/dist/tools/manage.d.ts.map +1 -1
- package/dist/tools/manage.js +25 -28
- package/dist/tools/manage.js.map +1 -1
- package/dist/tools/schema.d.ts +1 -1
- package/dist/tools/schema.d.ts.map +1 -1
- package/dist/tools/schema.js +31 -55
- package/dist/tools/schema.js.map +1 -1
- package/dist/tools/wait.d.ts.map +1 -1
- package/dist/tools/wait.js +19 -16
- package/dist/tools/wait.js.map +1 -1
- package/package.json +48 -40
package/README.md
CHANGED
|
@@ -75,7 +75,9 @@ claude mcp add chrome -- node /path/to/mcp-chrome/dist/index.js
|
|
|
75
75
|
"mcpServers": {
|
|
76
76
|
"chrome": {
|
|
77
77
|
"command": "node",
|
|
78
|
-
"args": [
|
|
78
|
+
"args": [
|
|
79
|
+
"/path/to/mcp-chrome/dist/index.js"
|
|
80
|
+
]
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
}
|
|
@@ -135,18 +137,26 @@ Extension-specific: `list` returns additional fields: `managed` (whether tab is
|
|
|
135
137
|
|
|
136
138
|
Event sequence model supporting arbitrary combinations:
|
|
137
139
|
|
|
138
|
-
| Event Type | Description
|
|
139
|
-
|
|
140
|
-
| `keydown` / `keyup` | Key press/release
|
|
141
|
-
| `click` | Click with actionability checks (visible, enabled, not-covered, auto-scroll)
|
|
142
|
-
| `mousedown` / `mouseup` | Mouse button press/release
|
|
143
|
-
| `mousemove` | Mouse movement
|
|
144
|
-
| `wheel` | Mouse wheel scroll
|
|
145
|
-
| `touchstart` / `touchmove` / `touchend` | Touch events
|
|
146
|
-
| `type` | Type text
|
|
147
|
-
| `wait` | Pause between events
|
|
148
|
-
| `select` | Select text by content (mouse sim)
|
|
149
|
-
| `replace` | Find and replace text
|
|
140
|
+
| Event Type | Description |
|
|
141
|
+
|-----------------------------------------|-----------------------------------------------------------------------------------|
|
|
142
|
+
| `keydown` / `keyup` | Key press/release |
|
|
143
|
+
| `click` | Click with actionability checks (visible, enabled, not-covered, auto-scroll) |
|
|
144
|
+
| `mousedown` / `mouseup` | Mouse button press/release |
|
|
145
|
+
| `mousemove` | Mouse movement |
|
|
146
|
+
| `wheel` | Mouse wheel scroll |
|
|
147
|
+
| `touchstart` / `touchmove` / `touchend` | Touch events |
|
|
148
|
+
| `type` | Type text (with optional `delay`, `dispatch` for React/Vue) |
|
|
149
|
+
| `wait` | Pause between events |
|
|
150
|
+
| `select` | Select text by content (mouse sim) |
|
|
151
|
+
| `replace` | Find and replace text |
|
|
152
|
+
| `drag` | HTML5 drag-and-drop (DragEvent in MAIN world, with `target` source + `to` target) |
|
|
153
|
+
|
|
154
|
+
Special-case parameters:
|
|
155
|
+
|
|
156
|
+
- `keydown` accepts `commands` (e.g. `["selectAll"]`, `["copy"]`, `["paste"]`, `["cut"]`, `["undo"]`, `["redo"]`) to
|
|
157
|
+
trigger native browser editing commands. `commands` is precise-mode only — stealth mode will throw because the
|
|
158
|
+
CDP commands API has no JS-event equivalent.
|
|
159
|
+
- `keydown` on a key already held emits `rawKeyDown` with `autoRepeat: true` (Puppeteer-compatible long-press).
|
|
150
160
|
|
|
151
161
|
Parameters: `humanize` enables Bézier curve movement and random delays. `tabId` targets a specific tab. `frame` targets
|
|
152
162
|
an iframe (CSS selector or index). Both Extension mode only.
|
|
@@ -174,6 +184,8 @@ metadata or data alongside HTML. `tabId` targets a specific tab. `frame` targets
|
|
|
174
184
|
`output` to save to file).
|
|
175
185
|
|
|
176
186
|
**`state`-specific**: `depth` controls DOM traversal depth (default 15). Reduce to limit response size on large pages.
|
|
187
|
+
`mode` selects the underlying source — `accessibility` (default, derived from the a11y tree) or `domsnapshot` (raw CDP
|
|
188
|
+
`DOMSnapshot.captureSnapshot`, CDP-only; returns a flat node array with computed styles for advanced post-processing).
|
|
177
189
|
|
|
178
190
|
### wait - Wait for Conditions
|
|
179
191
|
|
|
@@ -212,17 +224,23 @@ Results >100KB are auto-saved to `/tmp/` with a structured hint returned.
|
|
|
212
224
|
|
|
213
225
|
### manage - Page & Environment Management
|
|
214
226
|
|
|
215
|
-
| Action | Description
|
|
216
|
-
|
|
217
|
-
| `newPage` | Create new page/tab
|
|
218
|
-
| `closePage` | Close page
|
|
219
|
-
| `clearCache` | Clear cache/cookies
|
|
220
|
-
| `viewport` | Set viewport size
|
|
221
|
-
| `userAgent` | Set User-Agent
|
|
222
|
-
| `emulate` | Device emulation (iPhone, iPad, etc.)
|
|
223
|
-
| `inputMode` | Query or set input mode (`precise` / `stealth`)
|
|
224
|
-
| `stealth` | Inject anti-detection scripts
|
|
225
|
-
| `cdp` | Send raw CDP command (advanced, e.g. `Runtime.evaluate`)
|
|
227
|
+
| Action | Description |
|
|
228
|
+
|--------------|-----------------------------------------------------------|
|
|
229
|
+
| `newPage` | Create new page/tab |
|
|
230
|
+
| `closePage` | Close page |
|
|
231
|
+
| `clearCache` | Clear cache/storage (use `cookies` tool to clear cookies) |
|
|
232
|
+
| `viewport` | Set viewport size |
|
|
233
|
+
| `userAgent` | Set User-Agent |
|
|
234
|
+
| `emulate` | Device emulation (iPhone, iPad, etc.) |
|
|
235
|
+
| `inputMode` | Query or set input mode (`precise` / `stealth`) |
|
|
236
|
+
| `stealth` | Inject anti-detection scripts |
|
|
237
|
+
| `cdp` | Send raw CDP command (advanced, e.g. `Runtime.evaluate`) |
|
|
238
|
+
|
|
239
|
+
**Stealth mode levels** (CDP launch parameter, set via `browse action=launch stealth=...`):
|
|
240
|
+
|
|
241
|
+
- `off` — no anti-detection (clean mode for tests/CI)
|
|
242
|
+
- `safe` (default) — minimal patches (remove `navigator.webdriver`, clean CDP traces)
|
|
243
|
+
- `aggressive` — adds a few WebGL/plugin/language fingerprint patches (does NOT equal full masking)
|
|
226
244
|
|
|
227
245
|
### logs - Browser Logs
|
|
228
246
|
|
|
@@ -236,12 +254,15 @@ for logs.
|
|
|
236
254
|
|
|
237
255
|
### cookies - Cookie Management
|
|
238
256
|
|
|
239
|
-
| Action | Description
|
|
240
|
-
|
|
241
|
-
| `get` | Get cookies
|
|
242
|
-
| `set` | Set cookie
|
|
243
|
-
| `delete` | Delete cookie
|
|
244
|
-
| `clear` |
|
|
257
|
+
| Action | Description |
|
|
258
|
+
|----------|---------------------------------------------------------------|
|
|
259
|
+
| `get` | Get cookies |
|
|
260
|
+
| `set` | Set cookie |
|
|
261
|
+
| `delete` | Delete cookie |
|
|
262
|
+
| `clear` | Delete cookies by filter (`name`/`domain`/`url`, ≥1 required) |
|
|
263
|
+
|
|
264
|
+
**Note**: `clear` requires at least one of `name`, `domain`, or `url` to filter — calling without any filter is rejected
|
|
265
|
+
to avoid wiping the user's login cookies.
|
|
245
266
|
|
|
246
267
|
## Target: Unified Element Locator
|
|
247
268
|
|
|
@@ -445,12 +466,15 @@ mcp-chrome/
|
|
|
445
466
|
│ │ └── schema.ts # Shared JSON Schema (Target oneOf)
|
|
446
467
|
│ ├── core/ # Core abstractions
|
|
447
468
|
│ │ ├── unified-session.ts # Dual-mode session (Extension + CDP)
|
|
469
|
+
│ │ ├── browser-driver.ts # IBrowserDriver abstraction
|
|
448
470
|
│ │ ├── session.ts # CDP session management
|
|
449
471
|
│ │ ├── locator.ts # Element locator (deadline-based timeout)
|
|
450
472
|
│ │ ├── auto-wait.ts # Auto-wait mechanism
|
|
451
473
|
│ │ ├── retry.ts # Retry logic
|
|
452
474
|
│ │ ├── types.ts # Type definitions
|
|
453
|
-
│ │
|
|
475
|
+
│ │ ├── utils.ts # Shared helpers
|
|
476
|
+
│ │ ├── errors.ts # Error types
|
|
477
|
+
│ │ └── index.ts # Module entry
|
|
454
478
|
│ ├── extension/ # Extension bridge
|
|
455
479
|
│ │ ├── bridge.ts # High-level Extension API
|
|
456
480
|
│ │ └── http-server.ts # HTTP + WebSocket server
|
|
@@ -475,6 +499,11 @@ mcp-chrome/
|
|
|
475
499
|
|
|
476
500
|
## Security Notes
|
|
477
501
|
|
|
502
|
+
- **Trust boundary**: This server has no application-layer authentication — it relies on `127.0.0.1` binding plus
|
|
503
|
+
same-UID trust, matching the model used by Playwright, Puppeteer, and chrome-launcher. Do NOT run on multi-user
|
|
504
|
+
systems, CI runners, or containers with `--net=host` where untrusted code can reach `127.0.0.1:19222-19299`. WebSocket
|
|
505
|
+
upgrades require a `chrome-extension://` Origin header, which blocks browser pages and curl, but does not stop a
|
|
506
|
+
malicious local process running as the same user.
|
|
478
507
|
- Extension mode: shares your browser sessions — only use on trusted machines
|
|
479
508
|
- CDP mode: provides full browser control via DevTools Protocol
|
|
480
509
|
- Default ports bind to 127.0.0.1 only (localhost)
|
|
@@ -482,6 +511,17 @@ mcp-chrome/
|
|
|
482
511
|
- The `manage cdp` action can send arbitrary CDP commands
|
|
483
512
|
- Network logs may contain sensitive information
|
|
484
513
|
|
|
514
|
+
### Anti-detection (stealth) — what it actually does
|
|
515
|
+
|
|
516
|
+
The `stealth` mode (`safe` / `aggressive`) only patches a small set of fingerprinting surfaces:
|
|
517
|
+
|
|
518
|
+
- **Covers**: `navigator.webdriver`, `cdc_*` properties, User-Agent string, a few WebGL vendor/renderer values, Chrome
|
|
519
|
+
runtime properties
|
|
520
|
+
- **Does NOT cover**: Canvas fingerprinting, AudioContext fingerprinting, Font enumeration, TLS-level fingerprints (
|
|
521
|
+
JA3/JA4), CDP attach banner ("Chrome is being controlled by automated software"), Extension presence detection
|
|
522
|
+
- **Warning**: Do NOT rely on this to bypass commercial anti-bot services (Cloudflare Turnstile, Akamai, DataDome,
|
|
523
|
+
PerimeterX). Real bot detection happens at multiple layers we cannot patch from inside the page
|
|
524
|
+
|
|
485
525
|
## Known Limitations
|
|
486
526
|
|
|
487
527
|
- **Chrome only**: Only supports Chrome/Chromium browsers (no Firefox/Safari)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"behavior.d.ts","sourceRoot":"","sources":["../../src/anti-detection/behavior.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"behavior.d.ts","sourceRoot":"","sources":["../../src/anti-detection/behavior.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAE7C;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,CA0BlF;AAkBD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,GAAE,MAAY,GAAG,MAAM,CAI9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,eAAe,CAAwB;IAE/C;;OAEG;IACH,kBAAkB,IAAI,KAAK;IAI3B;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAGzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"behavior.js","sourceRoot":"","sources":["../../src/anti-detection/behavior.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,GAAW;IAChD,MAAM,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;IAC5C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAC5D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,
|
|
1
|
+
{"version":3,"file":"behavior.js","sourceRoot":"","sources":["../../src/anti-detection/behavior.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* 反检测模块导出
|
|
3
3
|
*/
|
|
4
4
|
export { getAntiDetectionScript } from './injection.js';
|
|
5
|
-
export { randomDelay, generateBezierPath, getTypingDelay, getMouseMoveDelay, BehaviorSimulator
|
|
5
|
+
export { randomDelay, generateBezierPath, getTypingDelay, getMouseMoveDelay, BehaviorSimulator } from './behavior.js';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/anti-detection/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/anti-detection/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* 反检测模块导出
|
|
3
3
|
*/
|
|
4
4
|
export { getAntiDetectionScript } from './injection.js';
|
|
5
|
-
export { randomDelay, generateBezierPath, getTypingDelay, getMouseMoveDelay, BehaviorSimulator
|
|
5
|
+
export { randomDelay, generateBezierPath, getTypingDelay, getMouseMoveDelay, BehaviorSimulator } from './behavior.js';
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/anti-detection/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/anti-detection/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -6,9 +6,13 @@
|
|
|
6
6
|
* - 清理 CDP 痕迹
|
|
7
7
|
* - 模拟真实浏览器指纹
|
|
8
8
|
*
|
|
9
|
+
* 覆盖范围:navigator.webdriver、cdc_*、UA、若干 WebGL vendor/renderer、Chrome runtime
|
|
10
|
+
* 不覆盖:Canvas/Audio/Font 指纹、TLS 层指纹、CDP attach 横幅、扩展存在性探测
|
|
11
|
+
* 警告:禁止依赖此能力绕过商业 anti-bot 服务
|
|
12
|
+
*
|
|
9
13
|
* 模式:
|
|
10
|
-
* - safe:
|
|
11
|
-
* - aggressive:
|
|
14
|
+
* - safe: 基础修补(移除 webdriver、清理 CDP 痕迹、UA 标识修正)
|
|
15
|
+
* - aggressive: 在 safe 基础上追加 plugins、languages、chrome、permissions、WebGL 修补
|
|
12
16
|
*/
|
|
13
17
|
type StealthMode = 'safe' | 'aggressive';
|
|
14
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injection.d.ts","sourceRoot":"","sources":["../../src/anti-detection/injection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"injection.d.ts","sourceRoot":"","sources":["../../src/anti-detection/injection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,KAAK,WAAW,GAAG,MAAM,GAAG,YAAY,CAAA;AA+MxC;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,GAAE,WAAoB,GAAG,MAAM,CAEzE"}
|
|
@@ -6,22 +6,16 @@
|
|
|
6
6
|
* - 清理 CDP 痕迹
|
|
7
7
|
* - 模拟真实浏览器指纹
|
|
8
8
|
*
|
|
9
|
+
* 覆盖范围:navigator.webdriver、cdc_*、UA、若干 WebGL vendor/renderer、Chrome runtime
|
|
10
|
+
* 不覆盖:Canvas/Audio/Font 指纹、TLS 层指纹、CDP attach 横幅、扩展存在性探测
|
|
11
|
+
* 警告:禁止依赖此能力绕过商业 anti-bot 服务
|
|
12
|
+
*
|
|
9
13
|
* 模式:
|
|
10
|
-
* - safe:
|
|
11
|
-
* - aggressive:
|
|
14
|
+
* - safe: 基础修补(移除 webdriver、清理 CDP 痕迹、UA 标识修正)
|
|
15
|
+
* - aggressive: 在 safe 基础上追加 plugins、languages、chrome、permissions、WebGL 修补
|
|
12
16
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*/
|
|
16
|
-
export function getAntiDetectionScript(mode = 'safe') {
|
|
17
|
-
const safeScript = `
|
|
18
|
-
(function() {
|
|
19
|
-
'use strict';
|
|
20
|
-
|
|
21
|
-
// 如果已经注入过,跳过
|
|
22
|
-
if (window.__mcp_chrome_injected__) return;
|
|
23
|
-
window.__mcp_chrome_injected__ = true;
|
|
24
|
-
|
|
17
|
+
// 公共 body:三块基础修补,base 与 full 共享
|
|
18
|
+
const COMMON_BODY = `
|
|
25
19
|
// ============================================
|
|
26
20
|
// 1. 移除 navigator.webdriver
|
|
27
21
|
// ============================================
|
|
@@ -70,52 +64,11 @@ export function getAntiDetectionScript(mode = 'safe') {
|
|
|
70
64
|
} catch {
|
|
71
65
|
// 静默处理
|
|
72
66
|
}
|
|
73
|
-
})();
|
|
74
67
|
`;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
'use strict';
|
|
78
|
-
|
|
79
|
-
// 如果已经注入过,跳过
|
|
80
|
-
if (window.__mcp_chrome_injected__) return;
|
|
81
|
-
window.__mcp_chrome_injected__ = true;
|
|
82
|
-
|
|
83
|
-
// ============================================
|
|
84
|
-
// 1. 移除 navigator.webdriver
|
|
85
|
-
// ============================================
|
|
86
|
-
try {
|
|
87
|
-
Object.defineProperty(navigator, 'webdriver', {
|
|
88
|
-
get: () => undefined,
|
|
89
|
-
configurable: true,
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// 删除 webdriver 检测相关属性
|
|
93
|
-
delete navigator.__proto__.webdriver;
|
|
94
|
-
} catch {
|
|
95
|
-
// 静默处理,避免污染站点控制台
|
|
96
|
-
}
|
|
97
|
-
|
|
68
|
+
// aggressive 追加 body:plugins / languages / chrome / permissions / WebGL
|
|
69
|
+
const AGGRESSIVE_EXTRA_BODY = `
|
|
98
70
|
// ============================================
|
|
99
|
-
//
|
|
100
|
-
// ============================================
|
|
101
|
-
try {
|
|
102
|
-
// 清理 window.cdc_* 变量(Chrome DevTools 特征)
|
|
103
|
-
const cdcKeys = Object.keys(window).filter(key => key.startsWith('cdc_'));
|
|
104
|
-
for (const key of cdcKeys) {
|
|
105
|
-
delete window[key];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// 清理 document.cdc_* 变量
|
|
109
|
-
const docCdcKeys = Object.keys(document).filter(key => key.startsWith('cdc_'));
|
|
110
|
-
for (const key of docCdcKeys) {
|
|
111
|
-
delete document[key];
|
|
112
|
-
}
|
|
113
|
-
} catch {
|
|
114
|
-
// 静默处理
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// ============================================
|
|
118
|
-
// 3. 模拟真实插件列表
|
|
71
|
+
// 4. 模拟真实插件列表
|
|
119
72
|
// ============================================
|
|
120
73
|
try {
|
|
121
74
|
Object.defineProperty(navigator, 'plugins', {
|
|
@@ -164,7 +117,7 @@ export function getAntiDetectionScript(mode = 'safe') {
|
|
|
164
117
|
}
|
|
165
118
|
|
|
166
119
|
// ============================================
|
|
167
|
-
//
|
|
120
|
+
// 5. 模拟真实语言设置
|
|
168
121
|
// ============================================
|
|
169
122
|
try {
|
|
170
123
|
Object.defineProperty(navigator, 'languages', {
|
|
@@ -176,11 +129,12 @@ export function getAntiDetectionScript(mode = 'safe') {
|
|
|
176
129
|
}
|
|
177
130
|
|
|
178
131
|
// ============================================
|
|
179
|
-
//
|
|
132
|
+
// 6. 修复 Chrome 特有属性
|
|
180
133
|
// ============================================
|
|
181
134
|
try {
|
|
182
135
|
// chrome.runtime 检测
|
|
183
|
-
|
|
136
|
+
const chromeDescriptor = Object.getOwnPropertyDescriptor(window, 'chrome');
|
|
137
|
+
if (window.chrome === undefined && (!chromeDescriptor || chromeDescriptor.configurable)) {
|
|
184
138
|
Object.defineProperty(window, 'chrome', {
|
|
185
139
|
value: {
|
|
186
140
|
runtime: {},
|
|
@@ -200,7 +154,7 @@ export function getAntiDetectionScript(mode = 'safe') {
|
|
|
200
154
|
}
|
|
201
155
|
|
|
202
156
|
// ============================================
|
|
203
|
-
//
|
|
157
|
+
// 7. 修复 Permissions API
|
|
204
158
|
// ============================================
|
|
205
159
|
try {
|
|
206
160
|
const originalQuery = window.navigator.permissions?.query;
|
|
@@ -217,22 +171,6 @@ export function getAntiDetectionScript(mode = 'safe') {
|
|
|
217
171
|
// 静默处理
|
|
218
172
|
}
|
|
219
173
|
|
|
220
|
-
// ============================================
|
|
221
|
-
// 7. 隐藏自动化检测特征
|
|
222
|
-
// ============================================
|
|
223
|
-
try {
|
|
224
|
-
// 修改 navigator.userAgent 中的 Headless 标识
|
|
225
|
-
const originalUserAgent = navigator.userAgent;
|
|
226
|
-
if (originalUserAgent.includes('HeadlessChrome')) {
|
|
227
|
-
Object.defineProperty(navigator, 'userAgent', {
|
|
228
|
-
get: () => originalUserAgent.replace('HeadlessChrome', 'Chrome'),
|
|
229
|
-
configurable: true,
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
} catch {
|
|
233
|
-
// 静默处理
|
|
234
|
-
}
|
|
235
|
-
|
|
236
174
|
// ============================================
|
|
237
175
|
// 8. 修复 WebGL 渲染器信息
|
|
238
176
|
// ============================================
|
|
@@ -263,8 +201,24 @@ export function getAntiDetectionScript(mode = 'safe') {
|
|
|
263
201
|
} catch {
|
|
264
202
|
// 静默处理
|
|
265
203
|
}
|
|
266
|
-
})();
|
|
267
204
|
`;
|
|
268
|
-
|
|
205
|
+
function wrapStealthBody(body) {
|
|
206
|
+
return `
|
|
207
|
+
(function() {
|
|
208
|
+
'use strict';
|
|
209
|
+
|
|
210
|
+
// 如果已经注入过,跳过
|
|
211
|
+
if (window.__mcp_chrome_injected__) return;
|
|
212
|
+
window.__mcp_chrome_injected__ = true;
|
|
213
|
+
${body}})();
|
|
214
|
+
`;
|
|
215
|
+
}
|
|
216
|
+
const baseStealthScript = wrapStealthBody(COMMON_BODY);
|
|
217
|
+
const fullStealthScript = wrapStealthBody(COMMON_BODY + AGGRESSIVE_EXTRA_BODY);
|
|
218
|
+
/**
|
|
219
|
+
* 获取反检测注入脚本
|
|
220
|
+
*/
|
|
221
|
+
export function getAntiDetectionScript(mode = 'safe') {
|
|
222
|
+
return mode === 'aggressive' ? fullStealthScript : baseStealthScript;
|
|
269
223
|
}
|
|
270
224
|
//# sourceMappingURL=injection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injection.js","sourceRoot":"","sources":["../../src/anti-detection/injection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"injection.js","sourceRoot":"","sources":["../../src/anti-detection/injection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,gCAAgC;AAChC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDnB,CAAA;AAED,wEAAwE;AACxE,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuI7B,CAAA;AAED,SAAS,eAAe,CAAC,IAAY;IACjC,OAAO;;;;;;;EAOT,IAAI;CACL,CAAA;AACD,CAAC;AAED,MAAM,iBAAiB,GAAG,eAAe,CAAC,WAAW,CAAC,CAAA;AACtD,MAAM,iBAAiB,GAAG,eAAe,CAAC,WAAW,GAAG,qBAAqB,CAAC,CAAA;AAE9E;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAoB,MAAM;IAC7D,OAAO,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAA;AACxE,CAAC"}
|
package/dist/cdp/client.d.ts
CHANGED
|
@@ -40,14 +40,14 @@ export declare class CDPClient extends EventEmitter {
|
|
|
40
40
|
/**
|
|
41
41
|
* 等待特定事件
|
|
42
42
|
*
|
|
43
|
-
* close()/handleClose() 会立即 reject 所有活跃的等待者,不必等 timer
|
|
43
|
+
* close()/handleClose() 会立即 reject 所有活跃的等待者,不必等 timer 超时
|
|
44
44
|
*/
|
|
45
45
|
waitForEvent<T = unknown>(event: string, predicate?: (params: T) => boolean, timeout?: number): Promise<T>;
|
|
46
46
|
/**
|
|
47
47
|
* 关闭连接
|
|
48
48
|
*
|
|
49
49
|
* 立即 reject 所有 pending callbacks 和 waitForEvent,
|
|
50
|
-
* 然后发出 'disconnected' 信号供外部等待者(如 waitForAnyEvent
|
|
50
|
+
* 然后发出 'disconnected' 信号供外部等待者(如 waitForAnyEvent)清理
|
|
51
51
|
*/
|
|
52
52
|
close(): void;
|
|
53
53
|
/**
|
package/dist/cdp/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cdp/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cdp/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAwBrC;;GAEG;AACH,KAAK,gBAAgB,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;AAEjD;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAY;IACvC,aAAa;IACb,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAkB;IACjE,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,cAAc,CAA2C;IACjE,OAAO,CAAC,kBAAkB,CAAyB;IAEnD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IA8CzE;;OAEG;IACG,IAAI,CAAC,CAAC,GAAG,OAAO,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,MAA0C,GACpD,OAAO,CAAC,CAAC,CAAC;IA+Cb;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAOxD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAOzD;;;;OAIG;IACH,YAAY,CAAC,CAAC,GAAG,OAAO,EACpB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,EAClC,OAAO,SAAkB,GAC1B,OAAO,CAAC,CAAC,CAAC;IA8Bb;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAYb;;OAEG;IACH,OAAO,CAAC,aAAa;IA+CrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;OAEG;IACH,OAAO,CAAC,WAAW;CAStB;AAgCD;;GAEG;AACH,wBAAsB,oBAAoB,CACtC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAA6B,GACvC,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAA6B,GACvC,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAExG"}
|
package/dist/cdp/client.js
CHANGED
|
@@ -33,12 +33,12 @@ export class CDPClient extends EventEmitter {
|
|
|
33
33
|
try {
|
|
34
34
|
this.ws = new WebSocket(endpoint);
|
|
35
35
|
}
|
|
36
|
-
catch
|
|
36
|
+
catch {
|
|
37
37
|
clearTimeout(timer);
|
|
38
38
|
// 解析 host 和 port
|
|
39
|
-
const match = endpoint.match(/ws:\/\/([^:]+):(
|
|
39
|
+
const match = endpoint.match(/ws:\/\/(?<host>[^:]+):(?<port>\d+)/);
|
|
40
40
|
if (match) {
|
|
41
|
-
reject(new ConnectionRefusedError(match
|
|
41
|
+
reject(new ConnectionRefusedError(match.groups.host, parseInt(match.groups.port, 10)));
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
44
44
|
reject(new CDPError(`无法连接到 ${endpoint}`));
|
|
@@ -52,9 +52,9 @@ export class CDPClient extends EventEmitter {
|
|
|
52
52
|
this.ws.on('error', (error) => {
|
|
53
53
|
clearTimeout(timer);
|
|
54
54
|
// 解析 host 和 port
|
|
55
|
-
const match = endpoint.match(/ws:\/\/([^:]+):(
|
|
55
|
+
const match = endpoint.match(/ws:\/\/(?<host>[^:]+):(?<port>\d+)/);
|
|
56
56
|
if (match && error.message.includes('ECONNREFUSED')) {
|
|
57
|
-
reject(new ConnectionRefusedError(match
|
|
57
|
+
reject(new ConnectionRefusedError(match.groups.host, parseInt(match.groups.port, 10)));
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
60
60
|
reject(new CDPError(error.message));
|
|
@@ -105,9 +105,7 @@ export class CDPClient extends EventEmitter {
|
|
|
105
105
|
catch (err) {
|
|
106
106
|
clearTimeout(timeoutId);
|
|
107
107
|
this.callbacks.delete(id);
|
|
108
|
-
reject(new CDPError(`Failed to send CDP command ${method}: ${err instanceof Error ?
|
|
109
|
-
err.message :
|
|
110
|
-
'Unknown error'}`));
|
|
108
|
+
reject(new CDPError(`Failed to send CDP command ${method}: ${err instanceof Error ? err.message : 'Unknown error'}`));
|
|
111
109
|
}
|
|
112
110
|
});
|
|
113
111
|
}
|
|
@@ -132,7 +130,7 @@ export class CDPClient extends EventEmitter {
|
|
|
132
130
|
/**
|
|
133
131
|
* 等待特定事件
|
|
134
132
|
*
|
|
135
|
-
* close()/handleClose() 会立即 reject 所有活跃的等待者,不必等 timer
|
|
133
|
+
* close()/handleClose() 会立即 reject 所有活跃的等待者,不必等 timer 超时
|
|
136
134
|
*/
|
|
137
135
|
waitForEvent(event, predicate, timeout = DEFAULT_TIMEOUT) {
|
|
138
136
|
return new Promise((resolve, reject) => {
|
|
@@ -164,7 +162,7 @@ export class CDPClient extends EventEmitter {
|
|
|
164
162
|
* 关闭连接
|
|
165
163
|
*
|
|
166
164
|
* 立即 reject 所有 pending callbacks 和 waitForEvent,
|
|
167
|
-
* 然后发出 'disconnected' 信号供外部等待者(如 waitForAnyEvent
|
|
165
|
+
* 然后发出 'disconnected' 信号供外部等待者(如 waitForAnyEvent)清理
|
|
168
166
|
*/
|
|
169
167
|
close() {
|
|
170
168
|
this.rejectAllPending('连接主动关闭');
|
package/dist/cdp/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cdp/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cdp/client.ts"],"names":[],"mappings":"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"}
|
package/dist/cdp/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cdp/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cdp/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACzE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/cdp/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cdp/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cdp/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACzE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../../src/cdp/launcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,
|
|
1
|
+
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../../src/cdp/launcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAA;AA6BtE;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAU1C;AAED;;GAEG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,KAAK,CAAY;IAEzB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACG,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAwD1D;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,OAAO,CAAC,SAAS;IA0DjB;;OAEG;IACH,OAAO,CAAC,eAAe;CA0D1B"}
|