brave-real-browser-mcp-server 2.15.5 ā 2.15.7
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/dist/brave-installer.js +182 -0
- package/dist/browser-manager.js +22 -1
- package/dist/handlers/data-extraction-handlers.js +33 -3
- package/dist/handlers/multi-element-handlers.js +5 -67
- package/dist/handlers/navigation-handlers.js +59 -0
- package/dist/handlers/search-filter-handlers.js +0 -121
- package/dist/handlers/smart-data-extractors.js +21 -1
- package/dist/index.js +20 -62
- package/dist/tool-definitions.js +6 -218
- package/package.json +2 -2
- package/scripts/check-tool-registration.ts +66 -0
- package/scripts/full-verification.ts +98 -0
- package/scripts/live-verification.ts +61 -0
- package/scripts/verify-brave-installer.cjs +13 -0
- package/scripts/verify-fixes-custom.ts +108 -0
- package/scripts/verify-fixes-standalone.js +244 -0
- package/scripts/verify-fixes-standalone.ts +248 -0
- package/dist/handlers/data-processing-handlers.js +0 -49
- package/dist/handlers/pagination-handlers.js +0 -115
package/dist/index.js
CHANGED
|
@@ -22,21 +22,19 @@ 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
|
|
29
29
|
import { handleExtractJSON, handleScrapeMetaTags, handleExtractSchema, } from "./handlers/data-extraction-handlers.js";
|
|
30
30
|
// Import multi-element handlers
|
|
31
|
-
import { handleBatchElementScraper,
|
|
31
|
+
import { handleBatchElementScraper, handleAttributeHarvester, handleLinkHarvester, handleMediaExtractor, } from "./handlers/multi-element-handlers.js";
|
|
32
32
|
// Import pagination handlers
|
|
33
|
-
import {
|
|
34
|
-
// Import data processing handlers
|
|
35
|
-
import { handleHTMLToText, } from "./handlers/data-processing-handlers.js";
|
|
33
|
+
import { handleBreadcrumbNavigator, } from "./handlers/navigation-handlers.js";
|
|
36
34
|
// Import AI-powered handlers
|
|
37
35
|
import { handleSmartSelectorGenerator, handleContentClassification, } from "./handlers/ai-powered-handlers.js";
|
|
38
36
|
// Import search & filter handlers
|
|
39
|
-
import { handleKeywordSearch, handleRegexPatternMatcher, handleXPathSupport, handleAdvancedCSSSelectors,
|
|
37
|
+
import { handleKeywordSearch, handleRegexPatternMatcher, handleXPathSupport, handleAdvancedCSSSelectors, } from "./handlers/search-filter-handlers.js";
|
|
40
38
|
// Import data quality handlers
|
|
41
39
|
import { handleDataTypeValidator, } from "./handlers/data-quality-handlers.js";
|
|
42
40
|
// Import captcha handlers
|
|
@@ -44,13 +42,13 @@ import { handleOCREngine, handleAudioCaptchaSolver, handlePuzzleCaptchaHandler,
|
|
|
44
42
|
// Import visual tools handlers
|
|
45
43
|
import { handleElementScreenshot, handleVideoRecording, } from "./handlers/visual-tools-handlers.js";
|
|
46
44
|
// Import smart data extractors
|
|
47
|
-
import {
|
|
45
|
+
import { handleFetchXHR, handleNetworkRecorder, handleImageExtractorAdvanced, handleVideoSourceExtractor, handleUrlRedirectTracer, handleApiFinder, } from "./handlers/smart-data-extractors.js";
|
|
48
46
|
// Import dynamic session handlers
|
|
49
|
-
import {
|
|
47
|
+
import { handleAjaxContentWaiter, } from "./handlers/dynamic-session-handlers.js";
|
|
50
48
|
// Import monitoring & reporting handlers
|
|
51
49
|
import { handleProgressTracker, } from "./handlers/monitoring-reporting-handlers.js";
|
|
52
50
|
// Import advanced video & media handlers
|
|
53
|
-
import {
|
|
51
|
+
import { handleVideoPlayerFinder, handleStreamDetector, handleVideoDownloadLinkFinder, } from "./handlers/advanced-video-media-handlers.js";
|
|
54
52
|
// Import advanced extraction handlers (Ad-bypass & Obfuscation)
|
|
55
53
|
import { handleAdvancedVideoExtraction, handleDeobfuscateJS, handleMultiLayerRedirectTrace, handleAdProtectionDetector, } from "./handlers/advanced-extraction-handlers.js";
|
|
56
54
|
console.error("š [DEBUG] All modules loaded successfully");
|
|
@@ -132,6 +130,9 @@ export async function executeToolByName(name, args) {
|
|
|
132
130
|
case TOOL_NAMES.RANDOM_SCROLL:
|
|
133
131
|
result = await handleRandomScroll();
|
|
134
132
|
break;
|
|
133
|
+
case TOOL_NAMES.PRESS_KEY:
|
|
134
|
+
result = await handlePressKey(args);
|
|
135
|
+
break;
|
|
135
136
|
case TOOL_NAMES.FIND_SELECTOR:
|
|
136
137
|
result = await handleFindSelector(args);
|
|
137
138
|
break;
|
|
@@ -152,9 +153,6 @@ export async function executeToolByName(name, args) {
|
|
|
152
153
|
case TOOL_NAMES.BATCH_ELEMENT_SCRAPER:
|
|
153
154
|
result = await handleBatchElementScraper(args);
|
|
154
155
|
break;
|
|
155
|
-
case TOOL_NAMES.NESTED_DATA_EXTRACTION:
|
|
156
|
-
result = await handleNestedDataExtraction(args);
|
|
157
|
-
break;
|
|
158
156
|
case TOOL_NAMES.ATTRIBUTE_HARVESTER:
|
|
159
157
|
result = await handleAttributeHarvester(args);
|
|
160
158
|
break;
|
|
@@ -167,16 +165,12 @@ export async function executeToolByName(name, args) {
|
|
|
167
165
|
break;
|
|
168
166
|
// Pagination Tools
|
|
169
167
|
// Pagination Tools
|
|
170
|
-
|
|
171
|
-
result = await handleMultiPageScraper(args);
|
|
172
|
-
break;
|
|
168
|
+
// Pagination Tools
|
|
173
169
|
case TOOL_NAMES.BREADCRUMB_NAVIGATOR:
|
|
174
170
|
result = await handleBreadcrumbNavigator(args || {});
|
|
175
171
|
break;
|
|
176
172
|
// Data Processing Tools
|
|
177
|
-
|
|
178
|
-
result = await handleHTMLToText(args);
|
|
179
|
-
break;
|
|
173
|
+
// Data Processing Tools
|
|
180
174
|
// AI-Powered Features
|
|
181
175
|
case TOOL_NAMES.SMART_SELECTOR_GENERATOR:
|
|
182
176
|
result = await handleSmartSelectorGenerator(args);
|
|
@@ -197,9 +191,6 @@ export async function executeToolByName(name, args) {
|
|
|
197
191
|
case TOOL_NAMES.ADVANCED_CSS_SELECTORS:
|
|
198
192
|
result = await handleAdvancedCSSSelectors(args);
|
|
199
193
|
break;
|
|
200
|
-
case TOOL_NAMES.VISUAL_ELEMENT_FINDER:
|
|
201
|
-
result = await handleVisualElementFinder(args);
|
|
202
|
-
break;
|
|
203
194
|
// Data Quality & Validation
|
|
204
195
|
case TOOL_NAMES.DATA_TYPE_VALIDATOR:
|
|
205
196
|
result = await handleDataTypeValidator(args);
|
|
@@ -222,35 +213,14 @@ export async function executeToolByName(name, args) {
|
|
|
222
213
|
result = await handleVideoRecording(args);
|
|
223
214
|
break;
|
|
224
215
|
// Smart Data Extractors (Advanced)
|
|
225
|
-
case "html_elements_extractor":
|
|
226
|
-
result = await handleHtmlElementsExtractor(args || {});
|
|
227
|
-
break;
|
|
228
|
-
case "tags_finder":
|
|
229
|
-
result = await handleTagsFinder(args || {});
|
|
230
|
-
break;
|
|
231
|
-
case "links_finder":
|
|
232
|
-
result = await handleLinksFinder(args || {});
|
|
233
|
-
break;
|
|
234
|
-
case "xpath_links":
|
|
235
|
-
result = await handleXpathLinks(args || {});
|
|
236
|
-
break;
|
|
237
|
-
case "ajax_extractor":
|
|
238
|
-
result = await handleAjaxExtractor(args || {});
|
|
239
|
-
break;
|
|
240
216
|
case "fetch_xhr":
|
|
241
217
|
result = await handleFetchXHR(args || {});
|
|
242
218
|
break;
|
|
243
219
|
case "network_recorder":
|
|
244
220
|
result = await handleNetworkRecorder(args || {});
|
|
245
221
|
break;
|
|
246
|
-
case "
|
|
247
|
-
result = await
|
|
248
|
-
break;
|
|
249
|
-
case "iframe_extractor":
|
|
250
|
-
result = await handleIframeExtractor(args || {});
|
|
251
|
-
break;
|
|
252
|
-
case "embed_page_extractor":
|
|
253
|
-
result = await handleEmbedPageExtractor(args || {});
|
|
222
|
+
case "api_finder":
|
|
223
|
+
result = await handleApiFinder(args || {});
|
|
254
224
|
break;
|
|
255
225
|
case "image_extractor_advanced":
|
|
256
226
|
result = await handleImageExtractorAdvanced(args || {});
|
|
@@ -261,16 +231,7 @@ export async function executeToolByName(name, args) {
|
|
|
261
231
|
case "url_redirect_tracer":
|
|
262
232
|
result = await handleUrlRedirectTracer(args);
|
|
263
233
|
break;
|
|
264
|
-
case "user_agent_extractor":
|
|
265
|
-
result = await handleUserAgentExtractor(args || {});
|
|
266
|
-
break;
|
|
267
234
|
// Dynamic Content & Session Handling
|
|
268
|
-
case "shadow_dom_extractor":
|
|
269
|
-
result = await handleShadowDOMExtractor(args || {});
|
|
270
|
-
break;
|
|
271
|
-
case "form_auto_fill":
|
|
272
|
-
result = await handleFormAutoFill(args);
|
|
273
|
-
break;
|
|
274
235
|
case "ajax_content_waiter":
|
|
275
236
|
result = await handleAjaxContentWaiter(args);
|
|
276
237
|
break;
|
|
@@ -279,17 +240,14 @@ export async function executeToolByName(name, args) {
|
|
|
279
240
|
result = await handleProgressTracker(args || {});
|
|
280
241
|
break;
|
|
281
242
|
// Advanced Video & Media Download Tools
|
|
282
|
-
case "
|
|
283
|
-
result = await
|
|
284
|
-
break;
|
|
285
|
-
case "video_download_button":
|
|
286
|
-
result = await handleVideoDownloadButton(args);
|
|
243
|
+
case "video_player_finder":
|
|
244
|
+
result = await handleVideoPlayerFinder(args || {});
|
|
287
245
|
break;
|
|
288
|
-
case "
|
|
289
|
-
result = await
|
|
246
|
+
case "stream_detector":
|
|
247
|
+
result = await handleStreamDetector(args || {});
|
|
290
248
|
break;
|
|
291
|
-
case "
|
|
292
|
-
result = await
|
|
249
|
+
case "video_download_link_finder":
|
|
250
|
+
result = await handleVideoDownloadLinkFinder(args || {});
|
|
293
251
|
break;
|
|
294
252
|
// Advanced Extraction Tools (Ad-Bypass & Obfuscation)
|
|
295
253
|
case "advanced_video_extraction":
|
package/dist/tool-definitions.js
CHANGED
|
@@ -32,7 +32,11 @@ export const TOOLS = [
|
|
|
32
32
|
headless: {
|
|
33
33
|
type: 'boolean',
|
|
34
34
|
description: 'Run browser in headless mode',
|
|
35
|
-
|
|
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',
|
|
@@ -381,19 +385,6 @@ export const TOOLS = [
|
|
|
381
385
|
required: ['selector'],
|
|
382
386
|
},
|
|
383
387
|
},
|
|
384
|
-
{
|
|
385
|
-
name: 'nested_data_extraction',
|
|
386
|
-
description: 'Extract data maintaining parent-child relationships',
|
|
387
|
-
inputSchema: {
|
|
388
|
-
type: 'object',
|
|
389
|
-
properties: {
|
|
390
|
-
parentSelector: { type: 'string' },
|
|
391
|
-
childSelector: { type: 'string' },
|
|
392
|
-
maxParents: { type: 'number', default: 50 },
|
|
393
|
-
},
|
|
394
|
-
required: ['parentSelector', 'childSelector'],
|
|
395
|
-
},
|
|
396
|
-
},
|
|
397
388
|
{
|
|
398
389
|
name: 'attribute_harvester',
|
|
399
390
|
description: 'Collect attributes (href, src, data-*) from elements',
|
|
@@ -432,19 +423,6 @@ export const TOOLS = [
|
|
|
432
423
|
},
|
|
433
424
|
},
|
|
434
425
|
// Pagination Tools
|
|
435
|
-
{
|
|
436
|
-
name: 'multi_page_scraper',
|
|
437
|
-
description: 'Collect and merge data from multiple pages',
|
|
438
|
-
inputSchema: {
|
|
439
|
-
type: 'object',
|
|
440
|
-
properties: {
|
|
441
|
-
urls: { type: 'array', items: { type: 'string' } },
|
|
442
|
-
dataSelector: { type: 'string' },
|
|
443
|
-
waitBetweenPages: { type: 'number', default: 1000 },
|
|
444
|
-
},
|
|
445
|
-
required: ['urls', 'dataSelector'],
|
|
446
|
-
},
|
|
447
|
-
},
|
|
448
426
|
{
|
|
449
427
|
name: 'breadcrumb_navigator',
|
|
450
428
|
description: 'Extract navigation path by following site structure',
|
|
@@ -457,19 +435,7 @@ export const TOOLS = [
|
|
|
457
435
|
},
|
|
458
436
|
},
|
|
459
437
|
// Data Processing Tools
|
|
460
|
-
|
|
461
|
-
name: 'html_to_text',
|
|
462
|
-
description: 'Convert HTML content to clean text',
|
|
463
|
-
inputSchema: {
|
|
464
|
-
type: 'object',
|
|
465
|
-
properties: {
|
|
466
|
-
html: { type: 'string' },
|
|
467
|
-
preserveLinks: { type: 'boolean', default: false },
|
|
468
|
-
preserveFormatting: { type: 'boolean', default: false },
|
|
469
|
-
},
|
|
470
|
-
required: ['html'],
|
|
471
|
-
},
|
|
472
|
-
},
|
|
438
|
+
// Data Validation Tools
|
|
473
439
|
// Data Validation Tools
|
|
474
440
|
// AI-Powered Features (5 tools)
|
|
475
441
|
{
|
|
@@ -553,21 +519,6 @@ export const TOOLS = [
|
|
|
553
519
|
required: ['selector'],
|
|
554
520
|
},
|
|
555
521
|
},
|
|
556
|
-
{
|
|
557
|
-
name: 'visual_element_finder',
|
|
558
|
-
description: 'Find elements by visual properties',
|
|
559
|
-
inputSchema: {
|
|
560
|
-
type: 'object',
|
|
561
|
-
properties: {
|
|
562
|
-
url: { type: 'string' },
|
|
563
|
-
criteria: {
|
|
564
|
-
type: 'object',
|
|
565
|
-
description: 'Visual criteria (color, size, position, etc.)'
|
|
566
|
-
},
|
|
567
|
-
},
|
|
568
|
-
required: ['criteria'],
|
|
569
|
-
},
|
|
570
|
-
},
|
|
571
522
|
// Data Quality & Validation (5 tools)
|
|
572
523
|
{
|
|
573
524
|
name: 'data_type_validator',
|
|
@@ -652,60 +603,6 @@ export const TOOLS = [
|
|
|
652
603
|
},
|
|
653
604
|
},
|
|
654
605
|
// Smart Data Extractors (Advanced)
|
|
655
|
-
{
|
|
656
|
-
name: 'html_elements_extractor',
|
|
657
|
-
description: 'Extract all HTML elements with complete details',
|
|
658
|
-
inputSchema: {
|
|
659
|
-
type: 'object',
|
|
660
|
-
properties: {
|
|
661
|
-
selector: { type: 'string', default: '*' },
|
|
662
|
-
maxElements: { type: 'number', default: 100 },
|
|
663
|
-
includeStyles: { type: 'boolean', default: false },
|
|
664
|
-
},
|
|
665
|
-
},
|
|
666
|
-
},
|
|
667
|
-
{
|
|
668
|
-
name: 'tags_finder',
|
|
669
|
-
description: 'Find specific HTML tags',
|
|
670
|
-
inputSchema: {
|
|
671
|
-
type: 'object',
|
|
672
|
-
properties: {
|
|
673
|
-
tags: { type: 'array', items: { type: 'string' }, default: ['div', 'span', 'p', 'a', 'img'] },
|
|
674
|
-
},
|
|
675
|
-
},
|
|
676
|
-
},
|
|
677
|
-
{
|
|
678
|
-
name: 'links_finder',
|
|
679
|
-
description: 'Extract all links from page',
|
|
680
|
-
inputSchema: {
|
|
681
|
-
type: 'object',
|
|
682
|
-
properties: {
|
|
683
|
-
includeExternal: { type: 'boolean', default: true },
|
|
684
|
-
maxLinks: { type: 'number', default: 200 },
|
|
685
|
-
},
|
|
686
|
-
},
|
|
687
|
-
},
|
|
688
|
-
{
|
|
689
|
-
name: 'xpath_links',
|
|
690
|
-
description: 'Use XPath to find links',
|
|
691
|
-
inputSchema: {
|
|
692
|
-
type: 'object',
|
|
693
|
-
properties: {
|
|
694
|
-
xpath: { type: 'string', default: '//a[@href]' },
|
|
695
|
-
},
|
|
696
|
-
},
|
|
697
|
-
},
|
|
698
|
-
{
|
|
699
|
-
name: 'ajax_extractor',
|
|
700
|
-
description: 'Extract AJAX/XHR request data',
|
|
701
|
-
inputSchema: {
|
|
702
|
-
type: 'object',
|
|
703
|
-
properties: {
|
|
704
|
-
duration: { type: 'number', default: 15000 },
|
|
705
|
-
url: { type: 'string' },
|
|
706
|
-
},
|
|
707
|
-
},
|
|
708
|
-
},
|
|
709
606
|
{
|
|
710
607
|
name: 'fetch_xhr',
|
|
711
608
|
description: 'Capture fetch and XHR requests with responses',
|
|
@@ -737,34 +634,6 @@ export const TOOLS = [
|
|
|
737
634
|
},
|
|
738
635
|
},
|
|
739
636
|
},
|
|
740
|
-
{
|
|
741
|
-
name: 'regex_pattern_finder',
|
|
742
|
-
description: 'Find patterns using regex',
|
|
743
|
-
inputSchema: {
|
|
744
|
-
type: 'object',
|
|
745
|
-
properties: {
|
|
746
|
-
pattern: { type: 'string' },
|
|
747
|
-
flags: { type: 'string', default: 'gi' },
|
|
748
|
-
},
|
|
749
|
-
required: ['pattern'],
|
|
750
|
-
},
|
|
751
|
-
},
|
|
752
|
-
{
|
|
753
|
-
name: 'iframe_extractor',
|
|
754
|
-
description: 'Extract all iframes and their content',
|
|
755
|
-
inputSchema: {
|
|
756
|
-
type: 'object',
|
|
757
|
-
properties: {},
|
|
758
|
-
},
|
|
759
|
-
},
|
|
760
|
-
{
|
|
761
|
-
name: 'embed_page_extractor',
|
|
762
|
-
description: 'Extract embedded content (iframes, objects, embeds)',
|
|
763
|
-
inputSchema: {
|
|
764
|
-
type: 'object',
|
|
765
|
-
properties: {},
|
|
766
|
-
},
|
|
767
|
-
},
|
|
768
637
|
{
|
|
769
638
|
name: 'image_extractor_advanced',
|
|
770
639
|
description: 'Advanced image extraction with metadata',
|
|
@@ -786,37 +655,7 @@ export const TOOLS = [
|
|
|
786
655
|
required: ['url'],
|
|
787
656
|
},
|
|
788
657
|
},
|
|
789
|
-
{
|
|
790
|
-
name: 'user_agent_extractor',
|
|
791
|
-
description: 'Extract user agent information',
|
|
792
|
-
inputSchema: {
|
|
793
|
-
type: 'object',
|
|
794
|
-
properties: {},
|
|
795
|
-
},
|
|
796
|
-
},
|
|
797
658
|
// Dynamic Content & Session Handling
|
|
798
|
-
{
|
|
799
|
-
name: 'shadow_dom_extractor',
|
|
800
|
-
description: 'Extract content from Shadow DOM',
|
|
801
|
-
inputSchema: {
|
|
802
|
-
type: 'object',
|
|
803
|
-
properties: {
|
|
804
|
-
selector: { type: 'string', default: '*' },
|
|
805
|
-
},
|
|
806
|
-
},
|
|
807
|
-
},
|
|
808
|
-
{
|
|
809
|
-
name: 'form_auto_fill',
|
|
810
|
-
description: 'Automatically fill form fields',
|
|
811
|
-
inputSchema: {
|
|
812
|
-
type: 'object',
|
|
813
|
-
properties: {
|
|
814
|
-
formData: { type: 'object' },
|
|
815
|
-
submitAfterFill: { type: 'boolean', default: false },
|
|
816
|
-
submitButtonSelector: { type: 'string' },
|
|
817
|
-
},
|
|
818
|
-
},
|
|
819
|
-
},
|
|
820
659
|
{
|
|
821
660
|
name: 'ajax_content_waiter',
|
|
822
661
|
description: 'Wait for dynamic content to load',
|
|
@@ -846,45 +685,6 @@ export const TOOLS = [
|
|
|
846
685
|
},
|
|
847
686
|
},
|
|
848
687
|
// Advanced Video & Media Download Tools
|
|
849
|
-
{
|
|
850
|
-
name: 'video_link_finder',
|
|
851
|
-
description: 'Find all video links on page',
|
|
852
|
-
inputSchema: {
|
|
853
|
-
type: 'object',
|
|
854
|
-
properties: {
|
|
855
|
-
includeEmbedded: { type: 'boolean', default: true },
|
|
856
|
-
},
|
|
857
|
-
},
|
|
858
|
-
},
|
|
859
|
-
{
|
|
860
|
-
name: 'video_download_button',
|
|
861
|
-
description: 'Find and interact with video download buttons',
|
|
862
|
-
inputSchema: {
|
|
863
|
-
type: 'object',
|
|
864
|
-
properties: {
|
|
865
|
-
action: { type: 'string', enum: ['find', 'click'], default: 'find' },
|
|
866
|
-
selector: { type: 'string' },
|
|
867
|
-
},
|
|
868
|
-
},
|
|
869
|
-
},
|
|
870
|
-
{
|
|
871
|
-
name: 'video_play_push_source',
|
|
872
|
-
description: 'Capture video sources when play button is clicked',
|
|
873
|
-
inputSchema: {
|
|
874
|
-
type: 'object',
|
|
875
|
-
properties: {},
|
|
876
|
-
},
|
|
877
|
-
},
|
|
878
|
-
{
|
|
879
|
-
name: 'video_play_button_click',
|
|
880
|
-
description: 'Click video play button',
|
|
881
|
-
inputSchema: {
|
|
882
|
-
type: 'object',
|
|
883
|
-
properties: {
|
|
884
|
-
selector: { type: 'string' },
|
|
885
|
-
},
|
|
886
|
-
},
|
|
887
|
-
},
|
|
888
688
|
// Advanced Extraction Tools (Ad-Bypass & Obfuscation)
|
|
889
689
|
{
|
|
890
690
|
name: 'advanced_video_extraction',
|
|
@@ -1001,29 +801,18 @@ export const TOOL_NAMES = {
|
|
|
1001
801
|
EXTRACT_SCHEMA: 'extract_schema',
|
|
1002
802
|
// Multi-Element Extractors
|
|
1003
803
|
BATCH_ELEMENT_SCRAPER: 'batch_element_scraper',
|
|
1004
|
-
NESTED_DATA_EXTRACTION: 'nested_data_extraction',
|
|
1005
804
|
ATTRIBUTE_HARVESTER: 'attribute_harvester',
|
|
1006
805
|
// Content Type Specific
|
|
1007
806
|
LINK_HARVESTER: 'link_harvester',
|
|
1008
807
|
MEDIA_EXTRACTOR: 'media_extractor',
|
|
1009
808
|
// DOM & HTML Extraction (Phase 1)
|
|
1010
|
-
HTML_ELEMENTS_EXTRACTOR: 'html_elements_extractor',
|
|
1011
|
-
TAGS_FINDER: 'tags_finder',
|
|
1012
|
-
LINKS_FINDER: 'links_finder',
|
|
1013
|
-
XPATH_LINKS: 'xpath_links',
|
|
1014
|
-
SHADOW_DOM_EXTRACTOR: 'shadow_dom_extractor',
|
|
1015
|
-
IFRAME_EXTRACTOR: 'iframe_extractor',
|
|
1016
|
-
EMBED_PAGE_EXTRACTOR: 'embed_page_extractor',
|
|
1017
809
|
// Network Tools (Phase 1)
|
|
1018
|
-
AJAX_EXTRACTOR: 'ajax_extractor',
|
|
1019
810
|
FETCH_XHR: 'fetch_xhr',
|
|
1020
811
|
NETWORK_RECORDER: 'network_recorder',
|
|
1021
812
|
API_FINDER: 'api_finder',
|
|
1022
813
|
// Pagination Tools
|
|
1023
|
-
MULTI_PAGE_SCRAPER: 'multi_page_scraper',
|
|
1024
814
|
BREADCRUMB_NAVIGATOR: 'breadcrumb_navigator',
|
|
1025
815
|
// Data Processing
|
|
1026
|
-
HTML_TO_TEXT: 'html_to_text',
|
|
1027
816
|
// AI-Powered Features
|
|
1028
817
|
SMART_SELECTOR_GENERATOR: 'smart_selector_generator',
|
|
1029
818
|
CONTENT_CLASSIFICATION: 'content_classification',
|
|
@@ -1036,7 +825,6 @@ export const TOOL_NAMES = {
|
|
|
1036
825
|
REGEX_PATTERN_MATCHER: 'regex_pattern_matcher',
|
|
1037
826
|
XPATH_SUPPORT: 'xpath_support',
|
|
1038
827
|
ADVANCED_CSS_SELECTORS: 'advanced_css_selectors',
|
|
1039
|
-
VISUAL_ELEMENT_FINDER: 'visual_element_finder',
|
|
1040
828
|
// Data Quality & Validation
|
|
1041
829
|
DATA_TYPE_VALIDATOR: 'data_type_validator',
|
|
1042
830
|
// Advanced Captcha Handling
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-browser-mcp-server",
|
|
3
|
-
"version": "2.15.
|
|
3
|
+
"version": "2.15.7",
|
|
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",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"test:brave:cleanup": "taskkill /F /IM brave.exe || pkill -f brave || true"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@modelcontextprotocol/sdk": "^1.25.
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
38
38
|
"@types/turndown": "^5.0.6",
|
|
39
39
|
"ajv": "^8.12.0",
|
|
40
40
|
"axios": "^1.6.5",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
|
|
5
|
+
// Simple regex parser since we can't easily import the typescript modules directly in a node script without compilation steps
|
|
6
|
+
function checkRegistration() {
|
|
7
|
+
const rootDir = path.resolve(__dirname, '..');
|
|
8
|
+
const toolDefsPath = path.join(rootDir, 'src', 'tool-definitions.ts');
|
|
9
|
+
const indexPath = path.join(rootDir, 'src', 'index.ts');
|
|
10
|
+
|
|
11
|
+
console.log(`Checking definitions in: ${toolDefsPath}`);
|
|
12
|
+
console.log(`Checking registration in: ${indexPath}`);
|
|
13
|
+
|
|
14
|
+
const toolDefsContent = fs.readFileSync(toolDefsPath, 'utf8');
|
|
15
|
+
const indexContent = fs.readFileSync(indexPath, 'utf8');
|
|
16
|
+
|
|
17
|
+
// Extract TOOL_NAMES constants
|
|
18
|
+
// Looks like: BROWSER_INIT: 'browser_init',
|
|
19
|
+
const toolNameRegex = /([A-Z_]+):\s*'([^']+)'/g;
|
|
20
|
+
const definedTools = new Map();
|
|
21
|
+
let match;
|
|
22
|
+
|
|
23
|
+
// We only want the ones inside "export const TOOL_NAMES = {" block
|
|
24
|
+
// So let's isolate that block roughly
|
|
25
|
+
const toolsBlockMatch = toolDefsContent.match(/export const TOOL_NAMES = \{([\s\S]*?)\}/);
|
|
26
|
+
if (!toolsBlockMatch) {
|
|
27
|
+
console.error("Could not find TOOL_NAMES block in definitions!");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const toolsBlock = toolsBlockMatch[1];
|
|
31
|
+
|
|
32
|
+
while ((match = toolNameRegex.exec(toolsBlock)) !== null) {
|
|
33
|
+
// match[1] is Key (BROWSER_INIT), match[2] is Value (browser_init)
|
|
34
|
+
const key = match[1];
|
|
35
|
+
const value = match[2];
|
|
36
|
+
definedTools.set(key, value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
console.log(`Found ${definedTools.size} defined tools.`);
|
|
40
|
+
|
|
41
|
+
// Check index.ts for cases
|
|
42
|
+
// We look for `case TOOL_NAMES.KEY:` or `case "value":`
|
|
43
|
+
const missingTools = [];
|
|
44
|
+
|
|
45
|
+
for (const [key, value] of definedTools.entries()) {
|
|
46
|
+
const keyPattern = `case TOOL_NAMES.${key}`;
|
|
47
|
+
const valuePattern = `case "${value}"`;
|
|
48
|
+
const valuePatternSingle = `case '${value}'`;
|
|
49
|
+
|
|
50
|
+
if (!indexContent.includes(keyPattern) &&
|
|
51
|
+
!indexContent.includes(valuePattern) &&
|
|
52
|
+
!indexContent.includes(valuePatternSingle)) {
|
|
53
|
+
missingTools.push({ key, value });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (missingTools.length > 0) {
|
|
58
|
+
console.error("ā The following tools are MISSING in index.ts:");
|
|
59
|
+
missingTools.forEach(t => console.error(` - ${t.key} (${t.value})`));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
} else {
|
|
62
|
+
console.log("ā
All tools appear to be registered in index.ts!");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
checkRegistration();
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
|
|
2
|
+
import { handleBrowserInit, handleBrowserClose } from '../src/handlers/browser-handlers.js';
|
|
3
|
+
import { handleNavigate, handleWait } from '../src/handlers/navigation-handlers.js';
|
|
4
|
+
import { handleGetContent, handleFindSelector } from '../src/handlers/content-handlers.js';
|
|
5
|
+
import { handleBreadcrumbNavigator } from '../src/handlers/navigation-handlers.js';
|
|
6
|
+
import {
|
|
7
|
+
handleBatchElementScraper,
|
|
8
|
+
handleAttributeHarvester,
|
|
9
|
+
handleLinkHarvester,
|
|
10
|
+
handleMediaExtractor
|
|
11
|
+
} from '../src/handlers/multi-element-handlers.js';
|
|
12
|
+
import {
|
|
13
|
+
handleKeywordSearch,
|
|
14
|
+
handleRegexPatternMatcher,
|
|
15
|
+
handleXPathSupport,
|
|
16
|
+
handleAdvancedCSSSelectors
|
|
17
|
+
} from '../src/handlers/search-filter-handlers.js';
|
|
18
|
+
import { handleRandomScroll } from '../src/handlers/interaction-handlers.js';
|
|
19
|
+
import { handleScrapeMetaTags, handleExtractSchema } from '../src/handlers/data-extraction-handlers.js';
|
|
20
|
+
|
|
21
|
+
async function runFullVerification() {
|
|
22
|
+
console.log('š Starting Comprehensive Tool Verification...');
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
await handleBrowserInit({ headless: true });
|
|
26
|
+
|
|
27
|
+
// Testing on one site primarily to save time, then brief check on second
|
|
28
|
+
const url = 'https://moviesdrive.forum/';
|
|
29
|
+
console.log(`\n--------------------------------------------------`);
|
|
30
|
+
console.log(`š Targeting: ${url}`);
|
|
31
|
+
console.log(`--------------------------------------------------`);
|
|
32
|
+
|
|
33
|
+
// --- Navigation & Basic ---
|
|
34
|
+
console.log(`\n[1/12] š¢ Testing Navigation & Wait...`);
|
|
35
|
+
await handleNavigate({ url });
|
|
36
|
+
await handleWait({ type: 'timeout', value: '2000' });
|
|
37
|
+
console.log(' ā
Navigation complete.');
|
|
38
|
+
|
|
39
|
+
// --- Interaction ---
|
|
40
|
+
console.log(`\n[2/12] š¢ Testing Random Scroll...`);
|
|
41
|
+
await handleRandomScroll({});
|
|
42
|
+
console.log(' ā
Scroll complete.');
|
|
43
|
+
|
|
44
|
+
// --- Content Handlers ---
|
|
45
|
+
console.log(`\n[3/12] š¢ Testing Find Selector (Text search)...`);
|
|
46
|
+
const findRes = await handleFindSelector({ text: 'Movie' }); // Assuming "Movie" exists
|
|
47
|
+
console.log(` Result: Found ${findRes.content[0].text.length > 50 ? 'matches' : 'no matches'} (Length: ${findRes.content[0].text.length})`);
|
|
48
|
+
|
|
49
|
+
// --- Multi-Element Handlers (The file we kept) ---
|
|
50
|
+
console.log(`\n[4/12] š¢ Testing Batch Element Scraper...`);
|
|
51
|
+
const batchRes = await handleBatchElementScraper({ selector: 'a', maxElements: 3 });
|
|
52
|
+
console.log(` Result: ${batchRes.content[0].text.substring(0, 100)}...`);
|
|
53
|
+
|
|
54
|
+
console.log(`\n[5/12] š¢ Testing Attribute Harvester...`);
|
|
55
|
+
const attrRes = await handleAttributeHarvester({ selector: 'img', attributes: ['src'], maxElements: 3 });
|
|
56
|
+
console.log(` Result: ${attrRes.content[0].text.substring(0, 100)}...`);
|
|
57
|
+
|
|
58
|
+
console.log(`\n[6/12] š¢ Testing Media Extractor...`); // Might be empty on home page but runs logic
|
|
59
|
+
const mediaRes = await handleMediaExtractor({ types: ['video', 'iframe'] });
|
|
60
|
+
console.log(` Result: ${mediaRes.content[0].text.substring(0, 100)}...`);
|
|
61
|
+
|
|
62
|
+
// --- Search & Filter Handlers (The file we kept) ---
|
|
63
|
+
console.log(`\n[7/12] š¢ Testing Keyword Search...`);
|
|
64
|
+
const keyRes = await handleKeywordSearch({ keywords: ['Bollywood', 'Hollywood'] });
|
|
65
|
+
console.log(` Result: ${keyRes.content[0].text.substring(0, 100)}...`);
|
|
66
|
+
|
|
67
|
+
console.log(`\n[8/12] š¢ Testing Regex Pattern Matcher...`);
|
|
68
|
+
const regexRes = await handleRegexPatternMatcher({ pattern: 'https?://[^\\s"\']+' });
|
|
69
|
+
console.log(` Result: ${regexRes.content[0].text.substring(0, 100)}...`);
|
|
70
|
+
|
|
71
|
+
console.log(`\n[9/12] š¢ Testing XPath Support...`);
|
|
72
|
+
const xpathRes = await handleXPathSupport({ xpath: '//body//div' });
|
|
73
|
+
console.log(` Result: ${xpathRes.content[0].text.substring(0, 100)}...`);
|
|
74
|
+
|
|
75
|
+
console.log(`\n[10/12] š¢ Testing Advanced CSS Selectors...`);
|
|
76
|
+
const cssRes = await handleAdvancedCSSSelectors({ selector: 'div > a', operation: 'query' });
|
|
77
|
+
console.log(` Result: ${cssRes.content[0].text.substring(0, 100)}...`);
|
|
78
|
+
|
|
79
|
+
// --- Data Extraction ---
|
|
80
|
+
console.log(`\n[11/12] š¢ Testing Schema Extraction...`);
|
|
81
|
+
const schemaRes = await handleExtractSchema({});
|
|
82
|
+
console.log(` Result: ${schemaRes.content[0].text.substring(0, 100)}...`);
|
|
83
|
+
|
|
84
|
+
// --- Pagination (Refactored) ---
|
|
85
|
+
console.log(`\n[12/12] š¢ Testing Breadcrumb Navigator...`);
|
|
86
|
+
const breadRes = await handleBreadcrumbNavigator({});
|
|
87
|
+
console.log(` Result: ${breadRes.content[0].text.substring(0, 100)}...`);
|
|
88
|
+
|
|
89
|
+
console.log('\nā
All primary handler categories verified successfully.');
|
|
90
|
+
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error('\nā Verification Failed:', error);
|
|
93
|
+
} finally {
|
|
94
|
+
await handleBrowserClose({});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
runFullVerification();
|