real-browser-mcp-server 1.0.1 → 1.0.5
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/package.json +2 -2
- package/test/cjs/test.js +6 -6
- package/test/esm/{test.js → test.mjs} +9 -10
- package/test/esm/package.json +0 -3
- package/test-ua.js +0 -47
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "real-browser-mcp-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "MCP Server for Real Browser - Patchright (undetected Playwright fork) with Stealth Mode, Ad Blocker, and Turnstile Auto-Solver for undetectable web automation.",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/esm/index.mjs",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"mcp:verbose": "node src/index.js mcp --verbose",
|
|
27
27
|
"list": "node src/index.js --list",
|
|
28
28
|
"test": "npm run cjs_test && npm run esm_test",
|
|
29
|
-
"esm_test": "node ./test/esm/test.
|
|
29
|
+
"esm_test": "node ./test/esm/test.mjs",
|
|
30
30
|
"cjs_test": "node ./test/cjs/test.js"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
package/test/cjs/test.js
CHANGED
|
@@ -38,7 +38,7 @@ test('DrissionPage Detector', async () => {
|
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
test('Sannysoft WebDriver Detector', async () => {
|
|
41
|
-
await page.goto("https://bot.sannysoft.com/", { timeout:
|
|
41
|
+
await page.goto("https://bot.sannysoft.com/", { timeout: 70000 });
|
|
42
42
|
await new Promise(r => setTimeout(r, 3000));
|
|
43
43
|
let result = await page.evaluate(() => {
|
|
44
44
|
const webdriverEl = document.getElementById('webdriver-result');
|
|
@@ -48,7 +48,7 @@ test('Sannysoft WebDriver Detector', async () => {
|
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
test('Cloudflare WAF', async () => {
|
|
51
|
-
await page.goto("https://nopecha.com/demo/cloudflare", { timeout:
|
|
51
|
+
await page.goto("https://nopecha.com/demo/cloudflare", { timeout: 70000 });
|
|
52
52
|
let verify = null
|
|
53
53
|
let startDate = Date.now()
|
|
54
54
|
// Increased timeout to 60 seconds to allow turnstile to be solved
|
|
@@ -64,7 +64,7 @@ test('Cloudflare WAF', async () => {
|
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
test('Cloudflare Turnstile', async () => {
|
|
67
|
-
await page.goto("https://2captcha.com/demo/cloudflare-turnstile", { timeout:
|
|
67
|
+
await page.goto("https://2captcha.com/demo/cloudflare-turnstile", { timeout: 70000 });
|
|
68
68
|
await page.waitForSelector('.cf-turnstile')
|
|
69
69
|
let token = null
|
|
70
70
|
let startDate = Date.now()
|
|
@@ -86,7 +86,7 @@ test('Cloudflare Turnstile', async () => {
|
|
|
86
86
|
|
|
87
87
|
test('Fingerprint JS Bot Detector', async () => {
|
|
88
88
|
// Use domcontentloaded + higher timeout to avoid timeout on heavy pages
|
|
89
|
-
await page.goto("https://fingerprint.com/products/bot-detection/", { waitUntil: 'domcontentloaded', timeout:
|
|
89
|
+
await page.goto("https://fingerprint.com/products/bot-detection/", { waitUntil: 'domcontentloaded', timeout: 70000 });
|
|
90
90
|
await new Promise(r => setTimeout(r, 5000));
|
|
91
91
|
const detect = await page.evaluate(() => {
|
|
92
92
|
// Check for bot detection result in page content
|
|
@@ -130,7 +130,7 @@ test('Fingerprint JS Bot Detector', async () => {
|
|
|
130
130
|
// Note: ReCAPTCHA V3 score depends heavily on IP reputation, browser history, and Google's algorithms.
|
|
131
131
|
// A score >= 0.3 indicates the browser is not detected as an obvious bot.
|
|
132
132
|
test('Recaptcha V3 Score', async () => {
|
|
133
|
-
await page.goto("https://antcpt.com/score_detector/", { timeout:
|
|
133
|
+
await page.goto("https://antcpt.com/score_detector/", { timeout: 70000 });
|
|
134
134
|
|
|
135
135
|
// Human-like warm-up interactions before clicking
|
|
136
136
|
// 1. Random mouse movements using realCursor (Bézier curves via ghost-cursor)
|
|
@@ -159,7 +159,7 @@ test('Recaptcha V3 Score', async () => {
|
|
|
159
159
|
// Pixelscan Fingerprint Consistency Check
|
|
160
160
|
// Checks browser fingerprint consistency, automation detection, and proxy detection
|
|
161
161
|
test('Pixelscan Fingerprint Check', async () => {
|
|
162
|
-
await page.goto("https://pixelscan.net/fingerprint-check", { waitUntil: 'domcontentloaded', timeout:
|
|
162
|
+
await page.goto("https://pixelscan.net/fingerprint-check", { waitUntil: 'domcontentloaded', timeout: 70000 });
|
|
163
163
|
|
|
164
164
|
// Poll for the final status. We look specifically at the green header and the fingerprint checker card.
|
|
165
165
|
let result = false;
|
|
@@ -31,14 +31,14 @@ test.after(async () => {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
test('DrissionPage Detector', async () => {
|
|
34
|
-
await page.goto("https://web.archive.org/web/20240913054632/https://drissionpage.pages.dev/", { timeout:
|
|
34
|
+
await page.goto("https://web.archive.org/web/20240913054632/https://drissionpage.pages.dev/", { timeout: 70000 });
|
|
35
35
|
await page.realClick("#detector")
|
|
36
36
|
let result = await page.evaluate(() => { return document.querySelector('#isBot span').textContent.includes("not") ? true : false })
|
|
37
37
|
assert.strictEqual(result, true, "DrissionPage Detector test failed!")
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
test('Sannysoft WebDriver Detector', async () => {
|
|
41
|
-
await page.goto("https://bot.sannysoft.com/", { timeout:
|
|
41
|
+
await page.goto("https://bot.sannysoft.com/", { timeout: 70000 });
|
|
42
42
|
await new Promise(r => setTimeout(r, 3000));
|
|
43
43
|
let result = await page.evaluate(() => {
|
|
44
44
|
const webdriverEl = document.getElementById('webdriver-result');
|
|
@@ -48,7 +48,7 @@ test('Sannysoft WebDriver Detector', async () => {
|
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
test('Cloudflare WAF', async () => {
|
|
51
|
-
await page.goto("https://nopecha.com/demo/cloudflare", { timeout:
|
|
51
|
+
await page.goto("https://nopecha.com/demo/cloudflare", { timeout: 70000 });
|
|
52
52
|
let verify = null
|
|
53
53
|
let startDate = Date.now()
|
|
54
54
|
while (!verify && (Date.now() - startDate) < 50000) {
|
|
@@ -62,7 +62,7 @@ test('Cloudflare WAF', async () => {
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
test('Cloudflare Turnstile', async () => {
|
|
65
|
-
await page.goto("https://2captcha.com/demo/cloudflare-turnstile", { timeout:
|
|
65
|
+
await page.goto("https://2captcha.com/demo/cloudflare-turnstile", { timeout: 70000 });
|
|
66
66
|
await page.waitForSelector('.cf-turnstile')
|
|
67
67
|
let token = null
|
|
68
68
|
let startDate = Date.now()
|
|
@@ -83,7 +83,7 @@ test('Cloudflare Turnstile', async () => {
|
|
|
83
83
|
|
|
84
84
|
|
|
85
85
|
test('Fingerprint JS Bot Detector', async () => {
|
|
86
|
-
await page.goto("https://fingerprint.com/products/bot-detection/", { waitUntil: 'domcontentloaded', timeout:
|
|
86
|
+
await page.goto("https://fingerprint.com/products/bot-detection/", { waitUntil: 'domcontentloaded', timeout: 70000 });
|
|
87
87
|
await new Promise(r => setTimeout(r, 5000));
|
|
88
88
|
const detect = await page.evaluate(() => {
|
|
89
89
|
const pageText = document.body.innerText.toLowerCase();
|
|
@@ -93,8 +93,8 @@ test('Fingerprint JS Bot Detector', async () => {
|
|
|
93
93
|
document.querySelector('h1') !== null;
|
|
94
94
|
|
|
95
95
|
const isNotBlocked = !pageText.includes('access denied') &&
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
!pageText.includes('blocked') &&
|
|
97
|
+
!pageText.includes('captcha');
|
|
98
98
|
|
|
99
99
|
const preElements = document.querySelectorAll('pre, code');
|
|
100
100
|
for (const el of preElements) {
|
|
@@ -117,7 +117,7 @@ test('Fingerprint JS Bot Detector', async () => {
|
|
|
117
117
|
})
|
|
118
118
|
|
|
119
119
|
test('Recaptcha V3 Score', async () => {
|
|
120
|
-
await page.goto("https://antcpt.com/score_detector/", { timeout:
|
|
120
|
+
await page.goto("https://antcpt.com/score_detector/", { timeout: 70000 });
|
|
121
121
|
|
|
122
122
|
await page.realCursor.move('body', { paddingPercentage: 20 });
|
|
123
123
|
await new Promise(r => setTimeout(r, 500 + Math.random() * 500));
|
|
@@ -138,7 +138,7 @@ test('Recaptcha V3 Score', async () => {
|
|
|
138
138
|
})
|
|
139
139
|
|
|
140
140
|
test('Pixelscan Fingerprint Check', async () => {
|
|
141
|
-
await page.goto("https://pixelscan.net/fingerprint-check", { waitUntil: 'domcontentloaded', timeout:
|
|
141
|
+
await page.goto("https://pixelscan.net/fingerprint-check", { waitUntil: 'domcontentloaded', timeout: 70000 });
|
|
142
142
|
|
|
143
143
|
// Poll for the final status. We look specifically at the green header and the fingerprint checker card.
|
|
144
144
|
let result = false;
|
|
@@ -173,4 +173,3 @@ test('Pixelscan Fingerprint Check', async () => {
|
|
|
173
173
|
|
|
174
174
|
assert.strictEqual(result, true, "Pixelscan Fingerprint Check failed! Browser fingerprint is inconsistent or masking was detected.");
|
|
175
175
|
})
|
|
176
|
-
|
package/test/esm/package.json
DELETED
package/test-ua.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
const { connect } = require('./lib/cjs/index.js');
|
|
2
|
-
const { chromium } = require('patchright');
|
|
3
|
-
|
|
4
|
-
async function main() {
|
|
5
|
-
console.log("Launching browser via patchright (headless: true)...");
|
|
6
|
-
const browser = await chromium.launch({
|
|
7
|
-
headless: true,
|
|
8
|
-
executablePath: "C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
const context = await browser.newContext();
|
|
12
|
-
const page = await context.newPage();
|
|
13
|
-
|
|
14
|
-
// Connect to CDP session
|
|
15
|
-
const client = await page.context().newCDPSession(page);
|
|
16
|
-
|
|
17
|
-
console.log("Sending Emulation.setUserAgentOverride via CDP...");
|
|
18
|
-
await client.send('Emulation.setUserAgentOverride', {
|
|
19
|
-
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36",
|
|
20
|
-
userAgentMetadata: {
|
|
21
|
-
brands: [
|
|
22
|
-
{ brand: "Chromium", version: "148" },
|
|
23
|
-
{ brand: "Brave", version: "148" },
|
|
24
|
-
{ brand: "Not/A)Brand", version: "99" }
|
|
25
|
-
],
|
|
26
|
-
mobile: false,
|
|
27
|
-
platform: "Windows",
|
|
28
|
-
platformVersion: "10.0.0",
|
|
29
|
-
architecture: "x86",
|
|
30
|
-
model: ""
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// Navigate to https://example.com
|
|
35
|
-
console.log("\n--- Checking on https://example.com ---");
|
|
36
|
-
await page.goto("https://example.com");
|
|
37
|
-
const isSecureExample = await page.evaluate(() => window.isSecureContext);
|
|
38
|
-
console.log("isSecureContext:", isSecureExample);
|
|
39
|
-
const uaExample = await page.evaluate(() => navigator.userAgent);
|
|
40
|
-
console.log("User Agent:", uaExample);
|
|
41
|
-
const uadExample = await page.evaluate(() => navigator.userAgentData ? navigator.userAgentData.brands : null);
|
|
42
|
-
console.log("User Agent Data Brands:", uadExample);
|
|
43
|
-
|
|
44
|
-
await browser.close();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
main().catch(console.error);
|