real-browser-mcp-server 1.0.8 → 1.0.10

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/lib/cjs/index.js CHANGED
@@ -70,13 +70,10 @@ function getDefaultHeadless() {
70
70
  return envHeadless === 'true';
71
71
  }
72
72
 
73
- function setupRealPage(browser, page, options = {}) {
73
+ function setupRealPage(browser, page) {
74
74
  if (page._setupApplied) return page;
75
75
  page._setupApplied = true;
76
76
 
77
- const headless = options.headless !== undefined ? options.headless : getDefaultHeadless();
78
- const showCursor = options.showCursor !== undefined ? options.showCursor : false;
79
-
80
77
  // Enable ad blocker
81
78
  if (adBlockerInstance) {
82
79
  adBlockerInstance.enableBlockingInPage(page).catch(() => {});
@@ -90,13 +87,11 @@ function setupRealPage(browser, page, options = {}) {
90
87
 
91
88
  // Ghost Cursor integration - Bézier curve human-like mouse movement
92
89
  try {
93
- // 5th parameter controls visual cursor (installMouseHelper under the hood)
94
- const cursorPromise = createCursor(page, undefined, false, {}, showCursor);
90
+ const cursor = createCursor(page);
95
91
  page.realCursor = {
96
92
  move: async (selector, options = {}) => {
97
93
  try {
98
- const cursor = await cursorPromise;
99
- await cursor.move(selector, options);
94
+ await cursor.actions.move(selector, options);
100
95
  } catch (e) {
101
96
  // Fallback to native hover if ghost-cursor fails
102
97
  try { await page.hover(selector); } catch (_) {}
@@ -105,8 +100,7 @@ function setupRealPage(browser, page, options = {}) {
105
100
  };
106
101
  page.realClick = async (selector, options = {}) => {
107
102
  try {
108
- const cursor = await cursorPromise;
109
- await cursor.click(selector, options);
103
+ await cursor.actions.click({ target: selector, ...options });
110
104
  } catch (e) {
111
105
  // Fallback to native click if ghost-cursor fails
112
106
  await page.click(selector, options);
@@ -234,7 +228,6 @@ async function connect({
234
228
  proxy = {},
235
229
  turnstile = false,
236
230
  executablePath = undefined,
237
- visualCursor = undefined,
238
231
  } = {}) {
239
232
  let playwrightProxy = undefined;
240
233
  if (proxy && proxy.host && proxy.port) {
@@ -335,9 +328,7 @@ async function connect({
335
328
 
336
329
  await applyUserAgentOverride(page, modifiedUa, userAgentMetadata);
337
330
 
338
- const showCursor = visualCursor !== undefined ? visualCursor : false;
339
-
340
- setupRealPage(browser, page, { headless, showCursor });
331
+ setupRealPage(browser, page);
341
332
 
342
333
  page = await pageController({
343
334
  browser,
@@ -348,7 +339,7 @@ async function connect({
348
339
 
349
340
  context.on('page', async (newPage) => {
350
341
  await applyUserAgentOverride(newPage, modifiedUa, userAgentMetadata);
351
- setupRealPage(browser, newPage, { headless, showCursor });
342
+ setupRealPage(browser, newPage);
352
343
  await pageController({
353
344
  browser,
354
345
  page: newPage,
package/lib/esm/index.mjs CHANGED
@@ -75,13 +75,10 @@ function getDefaultHeadless() {
75
75
  return envHeadless === 'true';
76
76
  }
77
77
 
78
- function setupRealPage(browser, page, options = {}) {
78
+ function setupRealPage(browser, page) {
79
79
  if (page._setupApplied) return page;
80
80
  page._setupApplied = true;
81
81
 
82
- const headless = options.headless !== undefined ? options.headless : getDefaultHeadless();
83
- const showCursor = options.showCursor !== undefined ? options.showCursor : false;
84
-
85
82
  // Enable ad blocker
86
83
  if (adBlockerInstance) {
87
84
  adBlockerInstance.enableBlockingInPage(page).catch(() => {});
@@ -95,13 +92,11 @@ function setupRealPage(browser, page, options = {}) {
95
92
 
96
93
  // Ghost Cursor integration - Bézier curve human-like mouse movement
97
94
  try {
98
- // 5th parameter controls visual cursor (installMouseHelper under the hood)
99
- const cursorPromise = createCursor(page, undefined, false, {}, showCursor);
95
+ const cursor = createCursor(page);
100
96
  page.realCursor = {
101
97
  move: async (selector, options = {}) => {
102
98
  try {
103
- const cursor = await cursorPromise;
104
- await cursor.move(selector, options);
99
+ await cursor.actions.move(selector, options);
105
100
  } catch (e) {
106
101
  // Fallback to native hover if ghost-cursor fails
107
102
  try { await page.hover(selector); } catch (_) {}
@@ -110,8 +105,7 @@ function setupRealPage(browser, page, options = {}) {
110
105
  };
111
106
  page.realClick = async (selector, options = {}) => {
112
107
  try {
113
- const cursor = await cursorPromise;
114
- await cursor.click(selector, options);
108
+ await cursor.actions.click({ target: selector, ...options });
115
109
  } catch (e) {
116
110
  // Fallback to native click if ghost-cursor fails
117
111
  await page.click(selector, options);
@@ -238,7 +232,6 @@ export async function connect({
238
232
  proxy = {},
239
233
  turnstile = false,
240
234
  executablePath = undefined,
241
- visualCursor = undefined,
242
235
  } = {}) {
243
236
  let playwrightProxy = undefined;
244
237
  if (proxy && proxy.host && proxy.port) {
@@ -339,9 +332,7 @@ export async function connect({
339
332
 
340
333
  await applyUserAgentOverride(page, modifiedUa, userAgentMetadata);
341
334
 
342
- const showCursor = visualCursor !== undefined ? visualCursor : false;
343
-
344
- setupRealPage(browser, page, { headless, showCursor });
335
+ setupRealPage(browser, page);
345
336
 
346
337
  page = await pageController({
347
338
  browser,
@@ -352,7 +343,7 @@ export async function connect({
352
343
 
353
344
  context.on('page', async (newPage) => {
354
345
  await applyUserAgentOverride(newPage, modifiedUa, userAgentMetadata);
355
- setupRealPage(browser, newPage, { headless, showCursor });
346
+ setupRealPage(browser, newPage);
356
347
  await pageController({
357
348
  browser,
358
349
  page: newPage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "real-browser-mcp-server",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
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",
package/src/ai/core.js CHANGED
@@ -90,13 +90,9 @@ class AICore {
90
90
  if (element) {
91
91
  if (humanLike) {
92
92
  try {
93
- if (page.realClick) {
94
- await page.realClick(selector);
95
- } else {
96
- const { createCursor } = require('ghost-cursor-patchright');
97
- const cursor = await createCursor(page);
98
- await cursor.click(selector);
99
- }
93
+ const { createCursor } = require('ghost-cursor-patchright');
94
+ const cursor = createCursor(page);
95
+ await cursor.click(selector);
100
96
  } catch {
101
97
  await element.click();
102
98
  }
@@ -1239,23 +1239,20 @@ const handlers = {
1239
1239
  notifyProgress('click', 'progress', 'Used force click (JS)');
1240
1240
  } else if (humanLike) {
1241
1241
  try {
1242
+ const { createCursor } = require('ghost-cursor-patchright');
1243
+ const cursor = createCursor(page);
1244
+
1242
1245
  if (context !== page) {
1243
1246
  const element = await context.$(selector);
1244
1247
  if (element) {
1245
1248
  const box = await element.boundingBox();
1246
1249
  if (box) {
1247
- if (page.realCursor) {
1248
- await page.realCursor.move({ x: box.x + box.width / 2, y: box.y + box.height / 2 });
1249
- }
1250
+ await cursor.moveTo({ x: box.x + box.width / 2, y: box.y + box.height / 2 });
1250
1251
  await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2, { clickCount, delay });
1251
1252
  }
1252
1253
  }
1253
1254
  } else {
1254
- if (page.realClick) {
1255
- await page.realClick(selector);
1256
- } else {
1257
- await context.click(selector, { clickCount, delay });
1258
- }
1255
+ await cursor.click(selector);
1259
1256
  }
1260
1257
  notifyProgress('click', 'progress', 'Used human-like cursor movement');
1261
1258
  } catch (e) {
@@ -2005,13 +2002,9 @@ const handlers = {
2005
2002
 
2006
2003
  // Click submit button with human-like behavior
2007
2004
  try {
2008
- if (page.realClick) {
2009
- await page.realClick(submitSelector);
2010
- } else {
2011
- const { createCursor } = require('ghost-cursor-patchright');
2012
- const cursor = await createCursor(page);
2013
- await cursor.click(submitSelector);
2014
- }
2005
+ const { createCursor } = require('ghost-cursor-patchright');
2006
+ const cursor = createCursor(page);
2007
+ await cursor.click(submitSelector);
2015
2008
  } catch (e) {
2016
2009
  await page.click(submitSelector);
2017
2010
  }
@@ -4773,18 +4766,13 @@ const handlers = {
4773
4766
  }
4774
4767
  }
4775
4768
  }, identity, String(value));
4769
+ } else {
4776
4770
  // Smart Type
4777
- if (page.realClick) {
4778
- await page.realClick(identity);
4779
- } else {
4780
- try {
4781
- const { createCursor } = require('ghost-cursor-patchright');
4782
- const cursor = await createCursor(page);
4783
- await cursor.click(identity);
4784
- } catch (e) {
4785
- await page.click(identity);
4786
- }
4787
- }
4771
+ const { createCursor } = require('ghost-cursor-patchright');
4772
+ const cursor = createCursor(page);
4773
+
4774
+ // Click center of element
4775
+ await cursor.click(identity);
4788
4776
 
4789
4777
  // Clear existing
4790
4778
  await page.evaluate(s => document.querySelector(s).value = '', identity);
@@ -4847,17 +4835,9 @@ const handlers = {
4847
4835
  });
4848
4836
 
4849
4837
  if (submitSelector) {
4850
- if (page.realClick) {
4851
- await page.realClick(submitSelector);
4852
- } else {
4853
- try {
4854
- const { createCursor } = require('ghost-cursor-patchright');
4855
- const cursor = await createCursor(page);
4856
- await cursor.click(submitSelector);
4857
- } catch (e) {
4858
- await page.click(submitSelector);
4859
- }
4860
- }
4838
+ const { createCursor } = require('ghost-cursor-patchright');
4839
+ const cursor = createCursor(page);
4840
+ await cursor.click(submitSelector);
4861
4841
 
4862
4842
  try {
4863
4843
  await page.waitForNavigation({ timeout: 5000, waitUntil: 'domcontentloaded' });
package/test/cjs/test.js CHANGED
@@ -4,7 +4,7 @@ const { connect } = require('../../lib/cjs/index.js');
4
4
 
5
5
  const realBrowserOption = {
6
6
  turnstile: true,
7
- headless: false,
7
+ headless: true,
8
8
  customConfig: {}
9
9
  }
10
10
 
@@ -32,9 +32,7 @@ test.after(async () => {
32
32
 
33
33
  test('DrissionPage Detector', async () => {
34
34
  await page.goto("https://web.archive.org/web/20240913054632/https://drissionpage.pages.dev/", { timeout: 60000 });
35
- await page.waitForSelector("#detector", { timeout: 20000 });
36
35
  await page.realClick("#detector")
37
- await page.waitForSelector("#isBot span", { timeout: 20000 });
38
36
  let result = await page.evaluate(() => { return document.querySelector('#isBot span').textContent.includes("not") ? true : false })
39
37
  assert.strictEqual(result, true, "DrissionPage Detector test failed!")
40
38
  })
package/test/esm/test.mjs CHANGED
@@ -4,7 +4,7 @@ import { connect } from '../../lib/esm/index.mjs';
4
4
 
5
5
  const realBrowserOption = {
6
6
  turnstile: true,
7
- headless: false,
7
+ headless: true,
8
8
  customConfig: {}
9
9
  }
10
10
 
@@ -32,9 +32,7 @@ test.after(async () => {
32
32
 
33
33
  test('DrissionPage Detector', async () => {
34
34
  await page.goto("https://web.archive.org/web/20240913054632/https://drissionpage.pages.dev/", { timeout: 70000 });
35
- await page.waitForSelector("#detector", { timeout: 20000 });
36
35
  await page.realClick("#detector")
37
- await page.waitForSelector("#isBot span", { timeout: 20000 });
38
36
  let result = await page.evaluate(() => { return document.querySelector('#isBot span').textContent.includes("not") ? true : false })
39
37
  assert.strictEqual(result, true, "DrissionPage Detector test failed!")
40
38
  })
package/typings.d.ts CHANGED
@@ -31,8 +31,6 @@ declare module "real-browser-mcp-server" {
31
31
  enableBlocker?: boolean;
32
32
  /** Blocker configuration options */
33
33
  blockerOptions?: BlockerOptions;
34
- /** Enable visual cursor arrow overlay (defaults to true in headed/visible mode, false in headless mode) */
35
- visualCursor?: boolean;
36
34
  }
37
35
 
38
36
  interface ProxyOptions {