brave-real-browser-mcp-server 2.15.6 → 2.16.0

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,182 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import { exec, spawn } from 'child_process';
5
+ import axios from 'axios';
6
+ import { promisify } from 'util';
7
+ const execAsync = promisify(exec);
8
+ export class BraveInstaller {
9
+ static WINDOWS_INSTALLER_URL = 'https://laptop-updates.brave.com/latest/winx64';
10
+ static MAC_INSTALLER_URL = 'https://laptop-updates.brave.com/latest/osx';
11
+ /**
12
+ * Install Brave Browser based on the current platform with Silent/Auto options
13
+ */
14
+ static async install() {
15
+ const platform = process.platform;
16
+ console.error(`⬇️ Attempting to install Brave Browser for ${platform} (Silent Mode)...`);
17
+ try {
18
+ if (platform === 'win32') {
19
+ return await this.installOnWindows();
20
+ }
21
+ else if (platform === 'darwin') {
22
+ return await this.installOnMac();
23
+ }
24
+ else if (platform === 'linux') {
25
+ return await this.installOnLinux();
26
+ }
27
+ return false;
28
+ }
29
+ catch (error) {
30
+ console.error(`❌ Failed to install Brave: ${error.message}`);
31
+ return false;
32
+ }
33
+ }
34
+ /**
35
+ * Install Brave on Windows (Silent Install)
36
+ */
37
+ static async installOnWindows() {
38
+ const tempDir = os.tmpdir();
39
+ const installerPath = path.join(tempDir, 'BraveBrowserSetup.exe');
40
+ console.error('1️⃣ Downloading Brave Installer...');
41
+ try {
42
+ await this.downloadFile(this.WINDOWS_INSTALLER_URL, installerPath);
43
+ }
44
+ catch (e) {
45
+ console.error(` Download failed: ${e.message}`);
46
+ return false;
47
+ }
48
+ console.error('2️⃣ Running Installer (Silent Mode)...');
49
+ try {
50
+ // /silent and /install are standard for Brave/Chrome
51
+ // Triggers UAC prompt if not already elevated, but handles the UI silently
52
+ const installCmd = `"${installerPath}" --silent --install`;
53
+ await execAsync(installCmd);
54
+ console.error('⏳ Waiting for installation to complete...');
55
+ // Wait multiple intervals to ensure filesystem sync
56
+ await new Promise(resolve => setTimeout(resolve, 30000));
57
+ return true;
58
+ }
59
+ catch (error) {
60
+ console.error(' Silent install failed, attempting interactive fallback...');
61
+ try {
62
+ // Fallback: Launch normally so user can interact
63
+ const child = spawn(installerPath, { detached: true, stdio: 'ignore' });
64
+ child.unref();
65
+ return true;
66
+ }
67
+ catch (e) {
68
+ console.error(` Failed to launch installer: ${error.message}`);
69
+ return false;
70
+ }
71
+ }
72
+ }
73
+ /**
74
+ * Install Brave on Mac (Silent/Automated Install via DMG)
75
+ */
76
+ static async installOnMac() {
77
+ const tempDir = os.tmpdir();
78
+ const dmgPath = path.join(tempDir, 'Brave-Browser.dmg');
79
+ console.error('1️⃣ Downloading Brave DMG...');
80
+ try {
81
+ await this.downloadFile(this.MAC_INSTALLER_URL, dmgPath);
82
+ }
83
+ catch (e) {
84
+ console.error(` Download failed: ${e.message}`);
85
+ return false;
86
+ }
87
+ console.error('2️⃣ Mounting DMG...');
88
+ try {
89
+ // Attach huge image quietly
90
+ await execAsync(`hdiutil attach "${dmgPath}" -nobrowse -quiet`);
91
+ console.error('3️⃣ Copying to Applications...');
92
+ // Copy the app bundle
93
+ try {
94
+ await execAsync(`cp -R "/Volumes/Brave Browser/Brave Browser.app" /Applications/`);
95
+ // Cleanup: Detach
96
+ try {
97
+ await execAsync(`hdiutil detach "/Volumes/Brave Browser" -quiet`);
98
+ }
99
+ catch (e) { }
100
+ // Force attribute update to remove quarantine (avoids 'downloaded from internet' popup)
101
+ try {
102
+ await execAsync(`xattr -r -d com.apple.quarantine "/Applications/Brave Browser.app"`);
103
+ }
104
+ catch (e) { }
105
+ return true;
106
+ }
107
+ catch (e) {
108
+ console.error(' Copy failed (Permission denied?). Opening DMG for user manually...');
109
+ await execAsync(`open "${dmgPath}"`);
110
+ return true;
111
+ }
112
+ }
113
+ catch (error) {
114
+ console.error(` Install failed: ${error.message}`);
115
+ return false;
116
+ }
117
+ }
118
+ /**
119
+ * Install Brave on Linux (Debian/Ubuntu/Fedora support)
120
+ */
121
+ static async installOnLinux() {
122
+ console.error('1️⃣ Detecting Linux distribution...');
123
+ try {
124
+ let dist = 'unknown';
125
+ if (fs.existsSync('/etc/debian_version'))
126
+ dist = 'debian';
127
+ else if (fs.existsSync('/etc/fedora-release'))
128
+ dist = 'fedora';
129
+ // Can extend for Arch/openSUSE if needed
130
+ console.error(` Detected family: ${dist}`);
131
+ if (dist === 'debian') {
132
+ console.error('2️⃣ Installing for Debian/Ubuntu (Attempting sudo)...');
133
+ // Basic check if we are root or can sudo
134
+ const cmd = `
135
+ sudo apt install -y curl &&
136
+ sudo curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg &&
137
+ echo "deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] https://brave-browser-apt-release.s3.brave.com/ stable main" | sudo tee /etc/apt/sources.list.d/brave-browser-release.list &&
138
+ sudo apt update &&
139
+ sudo apt install -y brave-browser
140
+ `;
141
+ await execAsync(cmd);
142
+ return true;
143
+ }
144
+ else if (dist === 'fedora') {
145
+ console.error('2️⃣ Installing for Fedora/CentOS (Attempting sudo)...');
146
+ const cmd = `
147
+ sudo dnf install -y dnf-plugins-core &&
148
+ sudo dnf config-manager --add-repo https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo &&
149
+ sudo rpm --import https://brave-browser-rpm-release.s3.brave.com/brave-core.asc &&
150
+ sudo dnf install -y brave-browser
151
+ `;
152
+ await execAsync(cmd);
153
+ return true;
154
+ }
155
+ else {
156
+ console.error(' Unsupported Linux distribution for auto-install.');
157
+ return false;
158
+ }
159
+ }
160
+ catch (error) {
161
+ console.error(` Linux install failed: ${error.message}`);
162
+ console.error(' Note: This requires sudo/root access without password or interactive terminal.');
163
+ return false;
164
+ }
165
+ }
166
+ /**
167
+ * Download a file from URL to destination
168
+ */
169
+ static async downloadFile(url, dest) {
170
+ const writer = fs.createWriteStream(dest);
171
+ const response = await axios({
172
+ url,
173
+ method: 'GET',
174
+ responseType: 'stream'
175
+ });
176
+ response.data.pipe(writer);
177
+ return new Promise((resolve, reject) => {
178
+ writer.on('finish', resolve);
179
+ writer.on('error', reject);
180
+ });
181
+ }
182
+ }
@@ -4,6 +4,7 @@ import * as path from 'path';
4
4
  import * as net from 'net';
5
5
  import { execSync, spawn } from 'child_process';
6
6
  import { config as dotenvConfig } from 'dotenv';
7
+ import { BraveInstaller } from './brave-installer.js';
7
8
  // Load environment variables from .env file
8
9
  // Silence dotenv output
9
10
  const originalWrite = process.stdout.write;
@@ -25,6 +26,12 @@ export var BrowserErrorType;
25
26
  // Store browser instance
26
27
  let browserInstance = null;
27
28
  let pageInstance = null;
29
+ export function setBrowser(browser) {
30
+ browserInstance = browser;
31
+ }
32
+ export function setPage(page) {
33
+ pageInstance = page;
34
+ }
28
35
  // Check environment variable for testing override
29
36
  const disableContentPriority = process.env.DISABLE_CONTENT_PRIORITY === 'true' || process.env.NODE_ENV === 'test';
30
37
  let contentPriorityConfig = {
@@ -431,7 +438,21 @@ export async function initializeBrowser(options) {
431
438
  await closeBrowser();
432
439
  }
433
440
  }
434
- const detectedBravePath = detectBravePath();
441
+ let detectedBravePath = detectBravePath();
442
+ const autoInstall = options?.autoInstall ?? true;
443
+ if (!detectedBravePath && autoInstall) {
444
+ console.error('⚠️ Brave Browser not found. autoInstall is enabled.');
445
+ const installed = await BraveInstaller.install();
446
+ if (installed) {
447
+ console.error('✅ Installation triggered. Retrying detection...');
448
+ // Wait a bit to ensure it's registered
449
+ await new Promise(r => setTimeout(r, 2000));
450
+ detectedBravePath = detectBravePath();
451
+ }
452
+ }
453
+ if (!detectedBravePath && !options?.customConfig?.chromePath) {
454
+ throw new Error('Brave Browser not found and auto-install failed or disabled. Please install Brave Browser manually: https://brave.com/download/');
455
+ }
435
456
  const customConfig = options?.customConfig ?? {};
436
457
  const platform = process.platform;
437
458
  const getOptimalBraveFlags = (isWindows, isRetry = false) => {
@@ -25,11 +25,11 @@ export async function handleExtractJSON(args) {
25
25
  const defaultSelector = selector || 'script[type="application/json"], script[type="application/ld+json"], script';
26
26
  const scripts = document.querySelectorAll(defaultSelector);
27
27
  scripts.forEach((script, index) => {
28
+ const content = script.textContent || '';
28
29
  try {
29
- const content = script.textContent || '';
30
+ // 1. Try direct parsing first
30
31
  const data = JSON.parse(content);
31
32
  if (filter) {
32
- // Simple filter check
33
33
  const filterLower = filter.toLowerCase();
34
34
  const dataStr = JSON.stringify(data).toLowerCase();
35
35
  if (!dataStr.includes(filterLower))
@@ -42,7 +42,37 @@ export async function handleExtractJSON(args) {
42
42
  });
43
43
  }
44
44
  catch (e) {
45
- // Invalid JSON, skip
45
+ // 2. Fallback: Try to find JSON objects using regex
46
+ // Matches { "key": ... } or [ ... ] structures
47
+ const jsonRegex = /({[\s\S]*?}|\[[\s\S]*?\])/g;
48
+ let match;
49
+ while ((match = jsonRegex.exec(content)) !== null) {
50
+ const potentialJson = match[0];
51
+ // Basic heuristic to avoid trying to parse tiny fragments
52
+ if (potentialJson.length < 20)
53
+ continue;
54
+ try {
55
+ const data = JSON.parse(potentialJson);
56
+ // Check filter
57
+ if (filter) {
58
+ const filterLower = filter.toLowerCase();
59
+ const dataStr = JSON.stringify(data).toLowerCase();
60
+ if (!dataStr.includes(filterLower))
61
+ continue;
62
+ }
63
+ // Basic check to ensure it's a nontrivial object/array
64
+ if ((Array.isArray(data) && data.length > 0) || (typeof data === 'object' && data !== null && Object.keys(data).length > 0)) {
65
+ results.push({
66
+ data,
67
+ source: 'script',
68
+ path: `script[${index}]_regex_match`,
69
+ });
70
+ }
71
+ }
72
+ catch (e2) {
73
+ // Not valid JSON
74
+ }
75
+ }
46
76
  }
47
77
  });
48
78
  }
@@ -146,6 +146,10 @@ export async function handleLinkHarvester(args) {
146
146
  const results = [];
147
147
  links.forEach((link, index) => {
148
148
  const href = link.href;
149
+ // Skip if no href (e.g. button without href)
150
+ if (!href) {
151
+ return;
152
+ }
149
153
  // Skip anchors if not included
150
154
  if (!includeAnchors && href.startsWith('#')) {
151
155
  return;
@@ -177,6 +181,7 @@ export async function handleLinkHarvester(args) {
177
181
  }
178
182
  catch (e) {
179
183
  linkInfo.type = 'invalid';
184
+ linkInfo.domain = 'unknown'; // Ensure domain exists even if invalid
180
185
  }
181
186
  }
182
187
  // Additional attributes
@@ -307,7 +307,18 @@ export async function handleFetchXHR(args) {
307
307
  });
308
308
  const page = getCurrentPage();
309
309
  const duration = args.duration || 15000;
310
+ const forceReload = args.forceReload !== false; // Default true to capture initial requests
310
311
  const xhrData = [];
312
+ // Capture requests too for completeness
313
+ const requestHandler = (request) => {
314
+ try {
315
+ const resourceType = request.resourceType();
316
+ if (resourceType === 'xhr' || resourceType === 'fetch') {
317
+ // Optional: Log request if needed, but for now we focus on responses with bodies
318
+ }
319
+ }
320
+ catch (e) { }
321
+ };
311
322
  const responseHandler = async (response) => {
312
323
  const request = response.request();
313
324
  const resourceType = request.resourceType();
@@ -320,7 +331,8 @@ export async function handleFetchXHR(args) {
320
331
  statusText: response.statusText(),
321
332
  headers: response.headers(),
322
333
  method: request.method(),
323
- body: body.substring(0, 1000), // First 1000 chars
334
+ postData: request.postData(),
335
+ body: body.substring(0, 5000), // Increased limit
324
336
  timestamp: new Date().toISOString(),
325
337
  });
326
338
  }
@@ -330,6 +342,14 @@ export async function handleFetchXHR(args) {
330
342
  }
331
343
  };
332
344
  page.on('response', responseHandler);
345
+ if (forceReload) {
346
+ try {
347
+ await page.reload({ waitUntil: 'networkidle2', timeout: 30000 });
348
+ }
349
+ catch (e) {
350
+ // Continue even if reload times out
351
+ }
352
+ }
333
353
  await sleep(duration);
334
354
  page.off('response', responseHandler);
335
355
  return {
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ import { setupProcessCleanup, } from "./core-infrastructure.js";
22
22
  console.error("🔍 [DEBUG] Loading handlers...");
23
23
  import { handleBrowserInit, handleBrowserClose, } from "./handlers/browser-handlers.js";
24
24
  import { handleNavigate, handleWait } from "./handlers/navigation-handlers.js";
25
- import { handleClick, handleType, handleSolveCaptcha, handleRandomScroll, } from "./handlers/interaction-handlers.js";
25
+ import { handleClick, handleType, handleSolveCaptcha, handleRandomScroll, handlePressKey, } from "./handlers/interaction-handlers.js";
26
26
  import { handleGetContent, handleFindSelector, } from "./handlers/content-handlers.js";
27
27
  import { handleSaveContentAsMarkdown } from "./handlers/file-handlers.js";
28
28
  // Import new data extraction handlers
@@ -42,13 +42,13 @@ import { handleOCREngine, handleAudioCaptchaSolver, handlePuzzleCaptchaHandler,
42
42
  // Import visual tools handlers
43
43
  import { handleElementScreenshot, handleVideoRecording, } from "./handlers/visual-tools-handlers.js";
44
44
  // Import smart data extractors
45
- import { handleHtmlElementsExtractor, handleTagsFinder, handleLinksFinder, handleXpathLinks, handleAjaxExtractor, handleFetchXHR, handleNetworkRecorder, handleRegexPatternFinder, handleIframeExtractor, handleEmbedPageExtractor, handleImageExtractorAdvanced, handleVideoSourceExtractor, handleUrlRedirectTracer, handleUserAgentExtractor, } from "./handlers/smart-data-extractors.js";
45
+ import { handleFetchXHR, handleNetworkRecorder, handleImageExtractorAdvanced, handleVideoSourceExtractor, handleUrlRedirectTracer, handleApiFinder, } from "./handlers/smart-data-extractors.js";
46
46
  // Import dynamic session handlers
47
- import { handleShadowDOMExtractor, handleFormAutoFill, handleAjaxContentWaiter, } from "./handlers/dynamic-session-handlers.js";
47
+ import { handleAjaxContentWaiter, } from "./handlers/dynamic-session-handlers.js";
48
48
  // Import monitoring & reporting handlers
49
49
  import { handleProgressTracker, } from "./handlers/monitoring-reporting-handlers.js";
50
50
  // Import advanced video & media handlers
51
- import { handleVideoLinkFinder, handleVideoDownloadButton, handleVideoPlayPushSource, handleVideoPlayButtonClick, } from "./handlers/advanced-video-media-handlers.js";
51
+ import { handleVideoPlayerFinder, handleStreamDetector, handleVideoDownloadLinkFinder, } from "./handlers/advanced-video-media-handlers.js";
52
52
  // Import advanced extraction handlers (Ad-bypass & Obfuscation)
53
53
  import { handleAdvancedVideoExtraction, handleDeobfuscateJS, handleMultiLayerRedirectTrace, handleAdProtectionDetector, } from "./handlers/advanced-extraction-handlers.js";
54
54
  console.error("🔍 [DEBUG] All modules loaded successfully");
@@ -130,6 +130,9 @@ export async function executeToolByName(name, args) {
130
130
  case TOOL_NAMES.RANDOM_SCROLL:
131
131
  result = await handleRandomScroll();
132
132
  break;
133
+ case TOOL_NAMES.PRESS_KEY:
134
+ result = await handlePressKey(args);
135
+ break;
133
136
  case TOOL_NAMES.FIND_SELECTOR:
134
137
  result = await handleFindSelector(args);
135
138
  break;
@@ -210,35 +213,14 @@ export async function executeToolByName(name, args) {
210
213
  result = await handleVideoRecording(args);
211
214
  break;
212
215
  // Smart Data Extractors (Advanced)
213
- case "html_elements_extractor":
214
- result = await handleHtmlElementsExtractor(args || {});
215
- break;
216
- case "tags_finder":
217
- result = await handleTagsFinder(args || {});
218
- break;
219
- case "links_finder":
220
- result = await handleLinksFinder(args || {});
221
- break;
222
- case "xpath_links":
223
- result = await handleXpathLinks(args || {});
224
- break;
225
- case "ajax_extractor":
226
- result = await handleAjaxExtractor(args || {});
227
- break;
228
216
  case "fetch_xhr":
229
217
  result = await handleFetchXHR(args || {});
230
218
  break;
231
219
  case "network_recorder":
232
220
  result = await handleNetworkRecorder(args || {});
233
221
  break;
234
- case "regex_pattern_finder":
235
- result = await handleRegexPatternFinder(args);
236
- break;
237
- case "iframe_extractor":
238
- result = await handleIframeExtractor(args || {});
239
- break;
240
- case "embed_page_extractor":
241
- result = await handleEmbedPageExtractor(args || {});
222
+ case "api_finder":
223
+ result = await handleApiFinder(args || {});
242
224
  break;
243
225
  case "image_extractor_advanced":
244
226
  result = await handleImageExtractorAdvanced(args || {});
@@ -249,16 +231,7 @@ export async function executeToolByName(name, args) {
249
231
  case "url_redirect_tracer":
250
232
  result = await handleUrlRedirectTracer(args);
251
233
  break;
252
- case "user_agent_extractor":
253
- result = await handleUserAgentExtractor(args || {});
254
- break;
255
234
  // Dynamic Content & Session Handling
256
- case "shadow_dom_extractor":
257
- result = await handleShadowDOMExtractor(args || {});
258
- break;
259
- case "form_auto_fill":
260
- result = await handleFormAutoFill(args);
261
- break;
262
235
  case "ajax_content_waiter":
263
236
  result = await handleAjaxContentWaiter(args);
264
237
  break;
@@ -267,17 +240,14 @@ export async function executeToolByName(name, args) {
267
240
  result = await handleProgressTracker(args || {});
268
241
  break;
269
242
  // Advanced Video & Media Download Tools
270
- case "video_link_finder":
271
- result = await handleVideoLinkFinder(args || {});
272
- break;
273
- case "video_download_button":
274
- result = await handleVideoDownloadButton(args);
243
+ case "video_player_finder":
244
+ result = await handleVideoPlayerFinder(args || {});
275
245
  break;
276
- case "video_play_push_source":
277
- result = await handleVideoPlayPushSource(args || {});
246
+ case "stream_detector":
247
+ result = await handleStreamDetector(args || {});
278
248
  break;
279
- case "video_play_button_click":
280
- result = await handleVideoPlayButtonClick(args || {});
249
+ case "video_download_link_finder":
250
+ result = await handleVideoDownloadLinkFinder(args || {});
281
251
  break;
282
252
  // Advanced Extraction Tools (Ad-Bypass & Obfuscation)
283
253
  case "advanced_video_extraction":
@@ -32,7 +32,11 @@ export const TOOLS = [
32
32
  headless: {
33
33
  type: 'boolean',
34
34
  description: 'Run browser in headless mode',
35
- default: false,
35
+ },
36
+ autoInstall: {
37
+ type: 'boolean',
38
+ description: 'Automatically install Brave Browser if not found (Default: true)',
39
+ default: true,
36
40
  },
37
41
  disableXvfb: {
38
42
  type: 'boolean',
@@ -599,60 +603,6 @@ export const TOOLS = [
599
603
  },
600
604
  },
601
605
  // Smart Data Extractors (Advanced)
602
- {
603
- name: 'html_elements_extractor',
604
- description: 'Extract all HTML elements with complete details',
605
- inputSchema: {
606
- type: 'object',
607
- properties: {
608
- selector: { type: 'string', default: '*' },
609
- maxElements: { type: 'number', default: 100 },
610
- includeStyles: { type: 'boolean', default: false },
611
- },
612
- },
613
- },
614
- {
615
- name: 'tags_finder',
616
- description: 'Find specific HTML tags',
617
- inputSchema: {
618
- type: 'object',
619
- properties: {
620
- tags: { type: 'array', items: { type: 'string' }, default: ['div', 'span', 'p', 'a', 'img'] },
621
- },
622
- },
623
- },
624
- {
625
- name: 'links_finder',
626
- description: 'Extract all links from page',
627
- inputSchema: {
628
- type: 'object',
629
- properties: {
630
- includeExternal: { type: 'boolean', default: true },
631
- maxLinks: { type: 'number', default: 200 },
632
- },
633
- },
634
- },
635
- {
636
- name: 'xpath_links',
637
- description: 'Use XPath to find links',
638
- inputSchema: {
639
- type: 'object',
640
- properties: {
641
- xpath: { type: 'string', default: '//a[@href]' },
642
- },
643
- },
644
- },
645
- {
646
- name: 'ajax_extractor',
647
- description: 'Extract AJAX/XHR request data',
648
- inputSchema: {
649
- type: 'object',
650
- properties: {
651
- duration: { type: 'number', default: 15000 },
652
- url: { type: 'string' },
653
- },
654
- },
655
- },
656
606
  {
657
607
  name: 'fetch_xhr',
658
608
  description: 'Capture fetch and XHR requests with responses',
@@ -684,34 +634,6 @@ export const TOOLS = [
684
634
  },
685
635
  },
686
636
  },
687
- {
688
- name: 'regex_pattern_finder',
689
- description: 'Find patterns using regex',
690
- inputSchema: {
691
- type: 'object',
692
- properties: {
693
- pattern: { type: 'string' },
694
- flags: { type: 'string', default: 'gi' },
695
- },
696
- required: ['pattern'],
697
- },
698
- },
699
- {
700
- name: 'iframe_extractor',
701
- description: 'Extract all iframes and their content',
702
- inputSchema: {
703
- type: 'object',
704
- properties: {},
705
- },
706
- },
707
- {
708
- name: 'embed_page_extractor',
709
- description: 'Extract embedded content (iframes, objects, embeds)',
710
- inputSchema: {
711
- type: 'object',
712
- properties: {},
713
- },
714
- },
715
637
  {
716
638
  name: 'image_extractor_advanced',
717
639
  description: 'Advanced image extraction with metadata',
@@ -733,37 +655,7 @@ export const TOOLS = [
733
655
  required: ['url'],
734
656
  },
735
657
  },
736
- {
737
- name: 'user_agent_extractor',
738
- description: 'Extract user agent information',
739
- inputSchema: {
740
- type: 'object',
741
- properties: {},
742
- },
743
- },
744
658
  // Dynamic Content & Session Handling
745
- {
746
- name: 'shadow_dom_extractor',
747
- description: 'Extract content from Shadow DOM',
748
- inputSchema: {
749
- type: 'object',
750
- properties: {
751
- selector: { type: 'string', default: '*' },
752
- },
753
- },
754
- },
755
- {
756
- name: 'form_auto_fill',
757
- description: 'Automatically fill form fields',
758
- inputSchema: {
759
- type: 'object',
760
- properties: {
761
- formData: { type: 'object' },
762
- submitAfterFill: { type: 'boolean', default: false },
763
- submitButtonSelector: { type: 'string' },
764
- },
765
- },
766
- },
767
659
  {
768
660
  name: 'ajax_content_waiter',
769
661
  description: 'Wait for dynamic content to load',
@@ -793,45 +685,6 @@ export const TOOLS = [
793
685
  },
794
686
  },
795
687
  // Advanced Video & Media Download Tools
796
- {
797
- name: 'video_link_finder',
798
- description: 'Find all video links on page',
799
- inputSchema: {
800
- type: 'object',
801
- properties: {
802
- includeEmbedded: { type: 'boolean', default: true },
803
- },
804
- },
805
- },
806
- {
807
- name: 'video_download_button',
808
- description: 'Find and interact with video download buttons',
809
- inputSchema: {
810
- type: 'object',
811
- properties: {
812
- action: { type: 'string', enum: ['find', 'click'], default: 'find' },
813
- selector: { type: 'string' },
814
- },
815
- },
816
- },
817
- {
818
- name: 'video_play_push_source',
819
- description: 'Capture video sources when play button is clicked',
820
- inputSchema: {
821
- type: 'object',
822
- properties: {},
823
- },
824
- },
825
- {
826
- name: 'video_play_button_click',
827
- description: 'Click video play button',
828
- inputSchema: {
829
- type: 'object',
830
- properties: {
831
- selector: { type: 'string' },
832
- },
833
- },
834
- },
835
688
  // Advanced Extraction Tools (Ad-Bypass & Obfuscation)
836
689
  {
837
690
  name: 'advanced_video_extraction',
@@ -953,15 +806,7 @@ export const TOOL_NAMES = {
953
806
  LINK_HARVESTER: 'link_harvester',
954
807
  MEDIA_EXTRACTOR: 'media_extractor',
955
808
  // DOM & HTML Extraction (Phase 1)
956
- HTML_ELEMENTS_EXTRACTOR: 'html_elements_extractor',
957
- TAGS_FINDER: 'tags_finder',
958
- LINKS_FINDER: 'links_finder',
959
- XPATH_LINKS: 'xpath_links',
960
- SHADOW_DOM_EXTRACTOR: 'shadow_dom_extractor',
961
- IFRAME_EXTRACTOR: 'iframe_extractor',
962
- EMBED_PAGE_EXTRACTOR: 'embed_page_extractor',
963
809
  // Network Tools (Phase 1)
964
- AJAX_EXTRACTOR: 'ajax_extractor',
965
810
  FETCH_XHR: 'fetch_xhr',
966
811
  NETWORK_RECORDER: 'network_recorder',
967
812
  API_FINDER: 'api_finder',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brave-real-browser-mcp-server",
3
- "version": "2.15.6",
3
+ "version": "2.16.0",
4
4
  "description": "Universal AI IDE MCP Server - Auto-detects and supports all AI IDEs (Claude Desktop, Cursor, Windsurf, Cline, Zed, VSCode, Qoder AI, etc.) with Brave browser automation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",