brave-real-browser-mcp-server 2.23.7 → 2.23.9

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.
@@ -44,15 +44,31 @@ export async function handleClick(args) {
44
44
  strategyMessage = `\nšŸ”„ Self-healing: Used ${strategy} fallback selector: ${usedSelector}`;
45
45
  tracker.setProgress(50, `šŸ”„ Using fallback selector: ${usedSelector}`);
46
46
  }
47
+ // Text-based strategies have special __TEXT__: prefix or are strategy-identified
48
+ // These have invalid CSS selectors, so we skip waitForSelector and use element directly
49
+ const isTextBasedStrategy = ['text-content', 'implicit-text-match', 'text', 'text-exact', 'text-partial', 'tag-text'].includes(strategy) ||
50
+ usedSelector.startsWith('__TEXT__:');
51
+ // Clean display selector for output (remove __TEXT__: prefix)
52
+ const displaySelector = usedSelector.startsWith('__TEXT__:')
53
+ ? usedSelector.replace('__TEXT__:', 'text:')
54
+ : usedSelector;
47
55
  try {
48
56
  tracker.setProgress(60, 'ā³ Waiting for element to be ready...');
49
- // Wait for element to be ready
50
- await pageInstance.waitForSelector(usedSelector, { timeout: 5000 });
57
+ // Only wait for selector if it's a valid CSS selector (not text-based)
58
+ if (!isTextBasedStrategy) {
59
+ await pageInstance.waitForSelector(usedSelector, { timeout: 5000 });
60
+ }
51
61
  // Check element visibility and interaction options
52
62
  const boundingBox = await element.boundingBox();
53
63
  if (!boundingBox) {
54
64
  tracker.setProgress(70, 'šŸ”§ No bounding box, using JavaScript click...');
55
- await pageInstance.$eval(usedSelector, (el) => el.click());
65
+ // For text-based strategies, use element.evaluate to click
66
+ if (isTextBasedStrategy) {
67
+ await element.evaluate((el) => el.click());
68
+ }
69
+ else {
70
+ await pageInstance.$eval(usedSelector, (el) => el.click());
71
+ }
56
72
  }
57
73
  else {
58
74
  tracker.setProgress(70, 'šŸ–±ļø Clicking element...');
@@ -60,12 +76,13 @@ export async function handleClick(args) {
60
76
  tracker.setProgress(75, 'šŸ”„ Clicking and waiting for navigation...');
61
77
  await Promise.all([
62
78
  pageInstance.waitForNavigation({ waitUntil: 'networkidle2' }),
63
- pageInstance.click(usedSelector),
79
+ element.click(), // Use element.click() for all strategies
64
80
  ]);
65
81
  tracker.setProgress(90, 'āœ… Navigation completed');
66
82
  }
67
83
  else {
68
- await pageInstance.click(usedSelector);
84
+ // Use element.click() directly - works for all strategies
85
+ await element.click();
69
86
  }
70
87
  }
71
88
  tracker.complete('šŸŽ‰ Click completed successfully');
@@ -82,7 +99,13 @@ export async function handleClick(args) {
82
99
  tracker.setProgress(85, 'āš ļø Click failed, trying JavaScript fallback...');
83
100
  // Final fallback: JavaScript click
84
101
  try {
85
- await pageInstance.$eval(usedSelector, (el) => el.click());
102
+ // For text-based strategies, use element.evaluate instead of $eval
103
+ if (isTextBasedStrategy) {
104
+ await element.evaluate((el) => el.click());
105
+ }
106
+ else {
107
+ await pageInstance.$eval(usedSelector, (el) => el.click());
108
+ }
86
109
  tracker.complete('šŸŽ‰ Click completed via JavaScript fallback');
87
110
  return {
88
111
  content: [
package/dist/index.js CHANGED
@@ -63,7 +63,7 @@ handleM3u8Parser, handleCookieManager,
63
63
  // Download tools
64
64
  handleFileDownloader,
65
65
  // Enhanced streaming/download tools
66
- handleIframeHandler, handlePopupHandler, handleStreamExtractor, } from './handlers/advanced-tools.js';
66
+ handleIframeHandler, handleStreamExtractor, } from './handlers/advanced-tools.js';
67
67
  // State for video recording
68
68
  const recorderState = new Map();
69
69
  debug('All modules loaded successfully');
@@ -259,10 +259,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
259
259
  if (!page)
260
260
  throw new Error('Browser not initialized. Call browser_init first.');
261
261
  return { content: [{ type: 'text', text: JSON.stringify(await handleIframeHandler(page, args)) }] };
262
- case TOOL_NAMES.POPUP_HANDLER:
263
- if (!page)
264
- throw new Error('Browser not initialized. Call browser_init first.');
265
- return { content: [{ type: 'text', text: JSON.stringify(await handlePopupHandler(page, args)) }] };
266
262
  case TOOL_NAMES.STREAM_EXTRACTOR:
267
263
  if (!page)
268
264
  throw new Error('Browser not initialized. Call browser_init first.');
@@ -323,15 +323,6 @@ const TOOL_DEFINITIONS = {
323
323
  { name: 'selector', type: 'string', description: 'CSS selector of target iframe', required: false },
324
324
  ],
325
325
  },
326
- popup_handler: {
327
- name: 'popup_handler',
328
- description: 'Handle popups, new tabs, and ad overlays during navigation',
329
- category: 'Advanced',
330
- parameters: [
331
- { name: 'action', type: 'string', description: 'Popup handling action', required: false, enum: ['block', 'allow', 'close', 'switch', 'list', 'closeAll'] },
332
- { name: 'autoCloseAds', type: 'boolean', description: 'Automatically close detected ad popups', required: false, default: true },
333
- ],
334
- },
335
326
  };
336
327
  // ============================================================
337
328
  // LSP SERVER
@@ -145,7 +145,7 @@ export class SelfHealingLocators {
145
145
  if (element) {
146
146
  return {
147
147
  element,
148
- usedSelector: `${textSelector.tagName || '*'}[text*="${textSelector.text}"]`,
148
+ usedSelector: `__TEXT__:${textSelector.tagName || '*'}:${textSelector.text}`,
149
149
  strategy: 'text-content'
150
150
  };
151
151
  }
@@ -171,7 +171,7 @@ export class SelfHealingLocators {
171
171
  if (textElement) {
172
172
  return {
173
173
  element: textElement,
174
- usedSelector: `//*[text()[contains(., "${primarySelector}")]]`,
174
+ usedSelector: `__TEXT__:*:${primarySelector}`,
175
175
  strategy: 'implicit-text-match'
176
176
  };
177
177
  }
@@ -626,21 +626,6 @@ export const TOOLS = [
626
626
  },
627
627
  },
628
628
  },
629
- {
630
- name: 'popup_handler',
631
- description: 'Handle popups, new tabs, and ad overlays during navigation',
632
- inputSchema: {
633
- type: 'object',
634
- additionalProperties: false,
635
- properties: {
636
- action: { type: 'string', enum: ['block', 'allow', 'close', 'switch', 'list', 'closeAll'], description: 'Popup handling action' },
637
- autoCloseAds: { type: 'boolean', description: 'Automatically close detected ad popups', default: true },
638
- waitForTarget: { type: 'boolean', description: 'Wait for new tab/popup to open', default: false },
639
- targetIndex: { type: 'number', description: 'Index of tab to switch to' },
640
- timeout: { type: 'number', description: 'Timeout for waiting operations in ms', default: 10000 },
641
- },
642
- },
643
- },
644
629
  {
645
630
  name: 'stream_extractor',
646
631
  description: 'Master tool: Extract direct download/stream URLs from any page with automatic redirect following, countdown waiting, and format detection',
@@ -698,7 +683,6 @@ export const TOOL_NAMES = {
698
683
  FILE_DOWNLOADER: 'file_downloader',
699
684
  // Enhanced tools
700
685
  IFRAME_HANDLER: 'iframe_handler',
701
- POPUP_HANDLER: 'popup_handler',
702
686
  STREAM_EXTRACTOR: 'stream_extractor',
703
687
  };
704
688
  // Tool categories for organization
@@ -536,7 +536,6 @@ async function main() {
536
536
  console.error(' šŸŖ cookie_manager - Manage cookies');
537
537
  console.error(' šŸ“„ file_downloader - Download files');
538
538
  console.error(' šŸ–¼ļø iframe_handler - Handle iframes');
539
- console.error(' 🚫 popup_handler - Handle popups/ads');
540
539
  console.error('');
541
540
  console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
542
541
  console.error('');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brave-real-browser-mcp-server",
3
- "version": "2.23.7",
3
+ "version": "2.23.9",
4
4
  "description": "🦁 MCP server for Brave Real Browser - NPM Workspaces Monorepo with anti-detection features, SSE streaming, and LSP compatibility",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -50,7 +50,7 @@
50
50
  "dependencies": {
51
51
  "@modelcontextprotocol/sdk": "latest",
52
52
  "@types/turndown": "latest",
53
- "brave-real-browser": "^2.4.7",
53
+ "brave-real-browser": "^2.4.9",
54
54
  "turndown": "latest",
55
55
  "vscode-languageserver": "^9.0.1",
56
56
  "vscode-languageserver-textdocument": "^1.0.12"