brave-real-browser-mcp-server 2.15.4 → 2.15.6
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/README.md +21 -40
- package/dist/handlers/data-extraction-handlers.js +0 -76
- package/dist/handlers/data-quality-handlers.js +0 -141
- package/dist/handlers/dynamic-session-handlers.js +0 -75
- package/dist/handlers/monitoring-reporting-handlers.js +0 -83
- package/dist/handlers/multi-element-handlers.js +0 -67
- package/dist/handlers/navigation-handlers.js +59 -0
- package/dist/handlers/search-filter-handlers.js +0 -121
- package/dist/handlers/visual-tools-handlers.js +0 -52
- package/dist/index.js +10 -40
- package/dist/tool-definitions.js +1 -150
- package/package.json +2 -2
- package/scripts/full-verification.ts +98 -0
- package/scripts/live-verification.ts +61 -0
- package/dist/handlers/data-processing-handlers.js +0 -91
- package/dist/handlers/pagination-handlers.js +0 -115
|
@@ -143,3 +143,62 @@ async function withWorkflowValidation(toolName, args, operation) {
|
|
|
143
143
|
throw error;
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Site structure follow करके pages scrape करता है
|
|
148
|
+
*/
|
|
149
|
+
export async function handleBreadcrumbNavigator(args) {
|
|
150
|
+
return await withWorkflowValidation('breadcrumb_navigator', args, async () => {
|
|
151
|
+
return await withErrorHandling(async () => {
|
|
152
|
+
const page = getPageInstance();
|
|
153
|
+
if (!page) {
|
|
154
|
+
throw new Error('Browser not initialized. Call browser_init first.');
|
|
155
|
+
}
|
|
156
|
+
const breadcrumbSelector = args.breadcrumbSelector || '.breadcrumb, nav[aria-label="breadcrumb"], .breadcrumbs';
|
|
157
|
+
const followLinks = args.followLinks || false;
|
|
158
|
+
const breadcrumbData = await page.evaluate((selector) => {
|
|
159
|
+
const breadcrumbs = document.querySelectorAll(selector);
|
|
160
|
+
const results = [];
|
|
161
|
+
breadcrumbs.forEach((breadcrumb) => {
|
|
162
|
+
const links = breadcrumb.querySelectorAll('a');
|
|
163
|
+
const items = [];
|
|
164
|
+
links.forEach((link, index) => {
|
|
165
|
+
items.push({
|
|
166
|
+
text: link.textContent?.trim() || '',
|
|
167
|
+
href: link.href,
|
|
168
|
+
level: index,
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
if (items.length > 0) {
|
|
172
|
+
results.push({
|
|
173
|
+
path: items.map((i) => i.text).join(' > '),
|
|
174
|
+
links: items,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
return results;
|
|
179
|
+
}, breadcrumbSelector);
|
|
180
|
+
if (breadcrumbData.length === 0) {
|
|
181
|
+
return {
|
|
182
|
+
content: [
|
|
183
|
+
{
|
|
184
|
+
type: 'text',
|
|
185
|
+
text: '❌ No breadcrumbs found on page',
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
let additionalData = '';
|
|
191
|
+
if (followLinks && breadcrumbData[0]?.links) {
|
|
192
|
+
additionalData = `\n\n📌 To scrape breadcrumb pages, use multi_page_scraper with URLs: ${JSON.stringify(breadcrumbData[0].links.map((l) => l.href))}`;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
content: [
|
|
196
|
+
{
|
|
197
|
+
type: 'text',
|
|
198
|
+
text: `✅ Found ${breadcrumbData.length} breadcrumb trail(s)\n\n${JSON.stringify(breadcrumbData, null, 2)}${additionalData}`,
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
};
|
|
202
|
+
}, 'Failed to navigate breadcrumbs');
|
|
203
|
+
});
|
|
204
|
+
}
|
|
@@ -262,124 +262,3 @@ export async function handleAdvancedCSSSelectors(args) {
|
|
|
262
262
|
return { content: [{ type: 'text', text: `❌ CSS selector query failed: ${error.message}` }], isError: true };
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
|
-
/**
|
|
266
|
-
* Visual Element Finder - Find elements by visual properties
|
|
267
|
-
*/
|
|
268
|
-
export async function handleVisualElementFinder(args) {
|
|
269
|
-
const { url, criteria } = args;
|
|
270
|
-
try {
|
|
271
|
-
const page = getPageInstance();
|
|
272
|
-
if (!page) {
|
|
273
|
-
throw new Error('Browser not initialized. Call browser_init first.');
|
|
274
|
-
}
|
|
275
|
-
if (url && page.url() !== url) {
|
|
276
|
-
await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
|
|
277
|
-
}
|
|
278
|
-
const results = await page.evaluate((crit) => {
|
|
279
|
-
const allElements = Array.from(document.querySelectorAll('*'));
|
|
280
|
-
const matches = [];
|
|
281
|
-
allElements.forEach(element => {
|
|
282
|
-
const computed = window.getComputedStyle(element);
|
|
283
|
-
const rect = element.getBoundingClientRect();
|
|
284
|
-
let matchScore = 0;
|
|
285
|
-
const reasons = [];
|
|
286
|
-
// Check visibility
|
|
287
|
-
if (crit.visible !== undefined) {
|
|
288
|
-
const isVisible = computed.display !== 'none' &&
|
|
289
|
-
computed.visibility !== 'hidden' &&
|
|
290
|
-
rect.width > 0 &&
|
|
291
|
-
rect.height > 0;
|
|
292
|
-
if (isVisible === crit.visible) {
|
|
293
|
-
matchScore += 10;
|
|
294
|
-
reasons.push('visibility');
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
// Check color
|
|
298
|
-
if (crit.color) {
|
|
299
|
-
if (computed.color.includes(crit.color) || computed.backgroundColor.includes(crit.color)) {
|
|
300
|
-
matchScore += 5;
|
|
301
|
-
reasons.push('color');
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
// Check size
|
|
305
|
-
if (crit.minWidth && rect.width >= crit.minWidth) {
|
|
306
|
-
matchScore += 3;
|
|
307
|
-
reasons.push('minWidth');
|
|
308
|
-
}
|
|
309
|
-
if (crit.maxWidth && rect.width <= crit.maxWidth) {
|
|
310
|
-
matchScore += 3;
|
|
311
|
-
reasons.push('maxWidth');
|
|
312
|
-
}
|
|
313
|
-
if (crit.minHeight && rect.height >= crit.minHeight) {
|
|
314
|
-
matchScore += 3;
|
|
315
|
-
reasons.push('minHeight');
|
|
316
|
-
}
|
|
317
|
-
if (crit.maxHeight && rect.height <= crit.maxHeight) {
|
|
318
|
-
matchScore += 3;
|
|
319
|
-
reasons.push('maxHeight');
|
|
320
|
-
}
|
|
321
|
-
// Check position
|
|
322
|
-
if (crit.position) {
|
|
323
|
-
if (computed.position === crit.position) {
|
|
324
|
-
matchScore += 5;
|
|
325
|
-
reasons.push('position');
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
// Check text content
|
|
329
|
-
if (crit.hasText !== undefined) {
|
|
330
|
-
const hasText = (element.textContent?.trim().length || 0) > 0;
|
|
331
|
-
if (hasText === crit.hasText) {
|
|
332
|
-
matchScore += 5;
|
|
333
|
-
reasons.push('hasText');
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
// Check if element is in viewport
|
|
337
|
-
if (crit.inViewport !== undefined) {
|
|
338
|
-
const inViewport = rect.top >= 0 &&
|
|
339
|
-
rect.left >= 0 &&
|
|
340
|
-
rect.bottom <= window.innerHeight &&
|
|
341
|
-
rect.right <= window.innerWidth;
|
|
342
|
-
if (inViewport === crit.inViewport) {
|
|
343
|
-
matchScore += 5;
|
|
344
|
-
reasons.push('inViewport');
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
if (matchScore > 0) {
|
|
348
|
-
matches.push({
|
|
349
|
-
element: {
|
|
350
|
-
tagName: element.tagName.toLowerCase(),
|
|
351
|
-
id: element.id,
|
|
352
|
-
className: element.className,
|
|
353
|
-
text: element.textContent?.substring(0, 100)
|
|
354
|
-
},
|
|
355
|
-
score: matchScore,
|
|
356
|
-
matchedCriteria: reasons,
|
|
357
|
-
visualProperties: {
|
|
358
|
-
display: computed.display,
|
|
359
|
-
visibility: computed.visibility,
|
|
360
|
-
position: computed.position,
|
|
361
|
-
color: computed.color,
|
|
362
|
-
backgroundColor: computed.backgroundColor,
|
|
363
|
-
width: rect.width,
|
|
364
|
-
height: rect.height,
|
|
365
|
-
top: rect.top,
|
|
366
|
-
left: rect.left
|
|
367
|
-
}
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
matches.sort((a, b) => b.score - a.score);
|
|
372
|
-
return {
|
|
373
|
-
totalMatches: matches.length,
|
|
374
|
-
topMatches: matches.slice(0, 20)
|
|
375
|
-
};
|
|
376
|
-
}, criteria);
|
|
377
|
-
const resultText = `✅ Visual Element Finder Results\n\nCriteria: ${JSON.stringify(criteria, null, 2)}\nTotal Matches: ${results.totalMatches}\n\nTop Matches:\n${JSON.stringify(results.topMatches, null, 2)}`;
|
|
378
|
-
return {
|
|
379
|
-
content: [{ type: 'text', text: resultText }],
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
catch (error) {
|
|
383
|
-
return { content: [{ type: 'text', text: `❌ Visual element finder failed: ${error.message}` }], isError: true };
|
|
384
|
-
}
|
|
385
|
-
}
|
|
@@ -6,58 +6,6 @@ import { sleep } from '../system-utils.js';
|
|
|
6
6
|
/**
|
|
7
7
|
* Full Page Screenshot - Capture entire page
|
|
8
8
|
*/
|
|
9
|
-
export async function handleFullPageScreenshot(args) {
|
|
10
|
-
const { url, outputPath, format = 'png', quality = 90, fullPage = true } = args;
|
|
11
|
-
try {
|
|
12
|
-
const page = getPageInstance();
|
|
13
|
-
if (!page) {
|
|
14
|
-
throw new Error('Browser not initialized. Call browser_init first.');
|
|
15
|
-
}
|
|
16
|
-
if (url && page.url() !== url) {
|
|
17
|
-
await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
|
|
18
|
-
}
|
|
19
|
-
// Ensure output directory exists
|
|
20
|
-
if (outputPath) {
|
|
21
|
-
const dir = path.dirname(outputPath);
|
|
22
|
-
await fs.mkdir(dir, { recursive: true });
|
|
23
|
-
}
|
|
24
|
-
const screenshotOptions = {
|
|
25
|
-
path: outputPath,
|
|
26
|
-
type: format,
|
|
27
|
-
fullPage
|
|
28
|
-
};
|
|
29
|
-
if (format === 'jpeg') {
|
|
30
|
-
screenshotOptions.quality = quality;
|
|
31
|
-
}
|
|
32
|
-
await page.screenshot(screenshotOptions);
|
|
33
|
-
// Get file stats if saved
|
|
34
|
-
let fileSize = 0;
|
|
35
|
-
if (outputPath) {
|
|
36
|
-
const stats = await fs.stat(outputPath);
|
|
37
|
-
fileSize = stats.size;
|
|
38
|
-
}
|
|
39
|
-
const resultText = `✅ Screenshot captured successfully\n\nPath: ${outputPath}\nFormat: ${format}\nFull Page: ${fullPage}\nFile Size: ${(fileSize / 1024).toFixed(2)} KB\nTimestamp: ${new Date().toISOString()}`;
|
|
40
|
-
return {
|
|
41
|
-
content: [
|
|
42
|
-
{
|
|
43
|
-
type: 'text',
|
|
44
|
-
text: resultText,
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
return {
|
|
51
|
-
content: [
|
|
52
|
-
{
|
|
53
|
-
type: 'text',
|
|
54
|
-
text: `❌ Screenshot failed: ${error.message}`,
|
|
55
|
-
},
|
|
56
|
-
],
|
|
57
|
-
isError: true,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
9
|
/**
|
|
62
10
|
* Element Screenshot - Capture specific element
|
|
63
11
|
*/
|
package/dist/index.js
CHANGED
|
@@ -26,29 +26,27 @@ import { handleClick, handleType, handleSolveCaptcha, handleRandomScroll, } from
|
|
|
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
|
-
import {
|
|
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, handleDuplicateRemover, } 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
|
-
import {
|
|
39
|
+
import { handleDataTypeValidator, } from "./handlers/data-quality-handlers.js";
|
|
42
40
|
// Import captcha handlers
|
|
43
41
|
import { handleOCREngine, handleAudioCaptchaSolver, handlePuzzleCaptchaHandler, } from "./handlers/captcha-handlers.js";
|
|
44
42
|
// Import visual tools handlers
|
|
45
|
-
import {
|
|
43
|
+
import { handleElementScreenshot, handleVideoRecording, } from "./handlers/visual-tools-handlers.js";
|
|
46
44
|
// Import smart data extractors
|
|
47
45
|
import { handleHtmlElementsExtractor, handleTagsFinder, handleLinksFinder, handleXpathLinks, handleAjaxExtractor, handleFetchXHR, handleNetworkRecorder, handleRegexPatternFinder, handleIframeExtractor, handleEmbedPageExtractor, handleImageExtractorAdvanced, handleVideoSourceExtractor, handleUrlRedirectTracer, handleUserAgentExtractor, } from "./handlers/smart-data-extractors.js";
|
|
48
46
|
// Import dynamic session handlers
|
|
49
|
-
import { handleShadowDOMExtractor,
|
|
47
|
+
import { handleShadowDOMExtractor, handleFormAutoFill, handleAjaxContentWaiter, } from "./handlers/dynamic-session-handlers.js";
|
|
50
48
|
// Import monitoring & reporting handlers
|
|
51
|
-
import { handleProgressTracker,
|
|
49
|
+
import { handleProgressTracker, } from "./handlers/monitoring-reporting-handlers.js";
|
|
52
50
|
// Import advanced video & media handlers
|
|
53
51
|
import { handleVideoLinkFinder, handleVideoDownloadButton, handleVideoPlayPushSource, handleVideoPlayButtonClick, } from "./handlers/advanced-video-media-handlers.js";
|
|
54
52
|
// Import advanced extraction handlers (Ad-bypass & Obfuscation)
|
|
@@ -139,9 +137,6 @@ export async function executeToolByName(name, args) {
|
|
|
139
137
|
result = await handleSaveContentAsMarkdown(args);
|
|
140
138
|
break;
|
|
141
139
|
// Smart Data Extractors
|
|
142
|
-
case TOOL_NAMES.EXTRACT_LIST:
|
|
143
|
-
result = await handleExtractList(args || {});
|
|
144
|
-
break;
|
|
145
140
|
case TOOL_NAMES.EXTRACT_JSON:
|
|
146
141
|
result = await handleExtractJSON(args || {});
|
|
147
142
|
break;
|
|
@@ -155,9 +150,6 @@ export async function executeToolByName(name, args) {
|
|
|
155
150
|
case TOOL_NAMES.BATCH_ELEMENT_SCRAPER:
|
|
156
151
|
result = await handleBatchElementScraper(args);
|
|
157
152
|
break;
|
|
158
|
-
case TOOL_NAMES.NESTED_DATA_EXTRACTION:
|
|
159
|
-
result = await handleNestedDataExtraction(args);
|
|
160
|
-
break;
|
|
161
153
|
case TOOL_NAMES.ATTRIBUTE_HARVESTER:
|
|
162
154
|
result = await handleAttributeHarvester(args);
|
|
163
155
|
break;
|
|
@@ -170,19 +162,12 @@ export async function executeToolByName(name, args) {
|
|
|
170
162
|
break;
|
|
171
163
|
// Pagination Tools
|
|
172
164
|
// Pagination Tools
|
|
173
|
-
|
|
174
|
-
result = await handleMultiPageScraper(args);
|
|
175
|
-
break;
|
|
165
|
+
// Pagination Tools
|
|
176
166
|
case TOOL_NAMES.BREADCRUMB_NAVIGATOR:
|
|
177
167
|
result = await handleBreadcrumbNavigator(args || {});
|
|
178
168
|
break;
|
|
179
169
|
// Data Processing Tools
|
|
180
|
-
|
|
181
|
-
result = await handleHTMLToText(args);
|
|
182
|
-
break;
|
|
183
|
-
case TOOL_NAMES.DUPLICATE_REMOVER:
|
|
184
|
-
result = await handleDuplicateRemover(args);
|
|
185
|
-
break;
|
|
170
|
+
// Data Processing Tools
|
|
186
171
|
// AI-Powered Features
|
|
187
172
|
case TOOL_NAMES.SMART_SELECTOR_GENERATOR:
|
|
188
173
|
result = await handleSmartSelectorGenerator(args);
|
|
@@ -203,13 +188,7 @@ export async function executeToolByName(name, args) {
|
|
|
203
188
|
case TOOL_NAMES.ADVANCED_CSS_SELECTORS:
|
|
204
189
|
result = await handleAdvancedCSSSelectors(args);
|
|
205
190
|
break;
|
|
206
|
-
case TOOL_NAMES.VISUAL_ELEMENT_FINDER:
|
|
207
|
-
result = await handleVisualElementFinder(args);
|
|
208
|
-
break;
|
|
209
191
|
// Data Quality & Validation
|
|
210
|
-
case TOOL_NAMES.DATA_DEDUPLICATION:
|
|
211
|
-
result = await handleDataDeduplication(args);
|
|
212
|
-
break;
|
|
213
192
|
case TOOL_NAMES.DATA_TYPE_VALIDATOR:
|
|
214
193
|
result = await handleDataTypeValidator(args);
|
|
215
194
|
break;
|
|
@@ -224,9 +203,6 @@ export async function executeToolByName(name, args) {
|
|
|
224
203
|
result = await handlePuzzleCaptchaHandler(args);
|
|
225
204
|
break;
|
|
226
205
|
// Screenshot & Visual Tools
|
|
227
|
-
case TOOL_NAMES.FULL_PAGE_SCREENSHOT:
|
|
228
|
-
result = await handleFullPageScreenshot(args);
|
|
229
|
-
break;
|
|
230
206
|
case TOOL_NAMES.ELEMENT_SCREENSHOT:
|
|
231
207
|
result = await handleElementScreenshot(args);
|
|
232
208
|
break;
|
|
@@ -280,9 +256,6 @@ export async function executeToolByName(name, args) {
|
|
|
280
256
|
case "shadow_dom_extractor":
|
|
281
257
|
result = await handleShadowDOMExtractor(args || {});
|
|
282
258
|
break;
|
|
283
|
-
case "cookie_manager":
|
|
284
|
-
result = await handleCookieManager(args);
|
|
285
|
-
break;
|
|
286
259
|
case "form_auto_fill":
|
|
287
260
|
result = await handleFormAutoFill(args);
|
|
288
261
|
break;
|
|
@@ -293,9 +266,6 @@ export async function executeToolByName(name, args) {
|
|
|
293
266
|
case "progress_tracker":
|
|
294
267
|
result = await handleProgressTracker(args || {});
|
|
295
268
|
break;
|
|
296
|
-
case "data_quality_metrics":
|
|
297
|
-
result = await handleDataQualityMetrics(args || {});
|
|
298
|
-
break;
|
|
299
269
|
// Advanced Video & Media Download Tools
|
|
300
270
|
case "video_link_finder":
|
|
301
271
|
result = await handleVideoLinkFinder(args || {});
|
package/dist/tool-definitions.js
CHANGED
|
@@ -331,18 +331,6 @@ export const TOOLS = [
|
|
|
331
331
|
},
|
|
332
332
|
},
|
|
333
333
|
// Smart Data Extractors
|
|
334
|
-
{
|
|
335
|
-
name: 'extract_list',
|
|
336
|
-
description: 'Extract data from bullet lists and numbered lists',
|
|
337
|
-
inputSchema: {
|
|
338
|
-
type: 'object',
|
|
339
|
-
properties: {
|
|
340
|
-
selector: { type: 'string', default: 'ul, ol' },
|
|
341
|
-
includeNested: { type: 'boolean', default: true },
|
|
342
|
-
maxItems: { type: 'number', default: 500 },
|
|
343
|
-
},
|
|
344
|
-
},
|
|
345
|
-
},
|
|
346
334
|
{
|
|
347
335
|
name: 'extract_json',
|
|
348
336
|
description: 'Extract embedded JSON/API data from the page',
|
|
@@ -393,19 +381,6 @@ export const TOOLS = [
|
|
|
393
381
|
required: ['selector'],
|
|
394
382
|
},
|
|
395
383
|
},
|
|
396
|
-
{
|
|
397
|
-
name: 'nested_data_extraction',
|
|
398
|
-
description: 'Extract data maintaining parent-child relationships',
|
|
399
|
-
inputSchema: {
|
|
400
|
-
type: 'object',
|
|
401
|
-
properties: {
|
|
402
|
-
parentSelector: { type: 'string' },
|
|
403
|
-
childSelector: { type: 'string' },
|
|
404
|
-
maxParents: { type: 'number', default: 50 },
|
|
405
|
-
},
|
|
406
|
-
required: ['parentSelector', 'childSelector'],
|
|
407
|
-
},
|
|
408
|
-
},
|
|
409
384
|
{
|
|
410
385
|
name: 'attribute_harvester',
|
|
411
386
|
description: 'Collect attributes (href, src, data-*) from elements',
|
|
@@ -444,19 +419,6 @@ export const TOOLS = [
|
|
|
444
419
|
},
|
|
445
420
|
},
|
|
446
421
|
// Pagination Tools
|
|
447
|
-
{
|
|
448
|
-
name: 'multi_page_scraper',
|
|
449
|
-
description: 'Collect and merge data from multiple pages',
|
|
450
|
-
inputSchema: {
|
|
451
|
-
type: 'object',
|
|
452
|
-
properties: {
|
|
453
|
-
urls: { type: 'array', items: { type: 'string' } },
|
|
454
|
-
dataSelector: { type: 'string' },
|
|
455
|
-
waitBetweenPages: { type: 'number', default: 1000 },
|
|
456
|
-
},
|
|
457
|
-
required: ['urls', 'dataSelector'],
|
|
458
|
-
},
|
|
459
|
-
},
|
|
460
422
|
{
|
|
461
423
|
name: 'breadcrumb_navigator',
|
|
462
424
|
description: 'Extract navigation path by following site structure',
|
|
@@ -469,32 +431,8 @@ export const TOOLS = [
|
|
|
469
431
|
},
|
|
470
432
|
},
|
|
471
433
|
// Data Processing Tools
|
|
472
|
-
{
|
|
473
|
-
name: 'html_to_text',
|
|
474
|
-
description: 'Convert HTML content to clean text',
|
|
475
|
-
inputSchema: {
|
|
476
|
-
type: 'object',
|
|
477
|
-
properties: {
|
|
478
|
-
html: { type: 'string' },
|
|
479
|
-
preserveLinks: { type: 'boolean', default: false },
|
|
480
|
-
preserveFormatting: { type: 'boolean', default: false },
|
|
481
|
-
},
|
|
482
|
-
required: ['html'],
|
|
483
|
-
},
|
|
484
|
-
},
|
|
485
434
|
// Data Validation Tools
|
|
486
|
-
|
|
487
|
-
name: 'duplicate_remover',
|
|
488
|
-
description: 'Remove duplicate items from an array',
|
|
489
|
-
inputSchema: {
|
|
490
|
-
type: 'object',
|
|
491
|
-
properties: {
|
|
492
|
-
data: { type: 'array' },
|
|
493
|
-
uniqueKey: { type: 'string' },
|
|
494
|
-
},
|
|
495
|
-
required: ['data'],
|
|
496
|
-
},
|
|
497
|
-
},
|
|
435
|
+
// Data Validation Tools
|
|
498
436
|
// AI-Powered Features (5 tools)
|
|
499
437
|
{
|
|
500
438
|
name: 'smart_selector_generator',
|
|
@@ -577,36 +515,7 @@ export const TOOLS = [
|
|
|
577
515
|
required: ['selector'],
|
|
578
516
|
},
|
|
579
517
|
},
|
|
580
|
-
{
|
|
581
|
-
name: 'visual_element_finder',
|
|
582
|
-
description: 'Find elements by visual properties',
|
|
583
|
-
inputSchema: {
|
|
584
|
-
type: 'object',
|
|
585
|
-
properties: {
|
|
586
|
-
url: { type: 'string' },
|
|
587
|
-
criteria: {
|
|
588
|
-
type: 'object',
|
|
589
|
-
description: 'Visual criteria (color, size, position, etc.)'
|
|
590
|
-
},
|
|
591
|
-
},
|
|
592
|
-
required: ['criteria'],
|
|
593
|
-
},
|
|
594
|
-
},
|
|
595
518
|
// Data Quality & Validation (5 tools)
|
|
596
|
-
{
|
|
597
|
-
name: 'data_deduplication',
|
|
598
|
-
description: 'Remove duplicate entries from scraped data',
|
|
599
|
-
inputSchema: {
|
|
600
|
-
type: 'object',
|
|
601
|
-
properties: {
|
|
602
|
-
data: { type: 'array' },
|
|
603
|
-
uniqueKeys: { type: 'array', items: { type: 'string' } },
|
|
604
|
-
fuzzyMatch: { type: 'boolean', default: false },
|
|
605
|
-
threshold: { type: 'number', default: 0.9 },
|
|
606
|
-
},
|
|
607
|
-
required: ['data'],
|
|
608
|
-
},
|
|
609
|
-
},
|
|
610
519
|
{
|
|
611
520
|
name: 'data_type_validator',
|
|
612
521
|
description: 'Validate data types against JSON schema',
|
|
@@ -619,18 +528,6 @@ export const TOOLS = [
|
|
|
619
528
|
required: ['data', 'schema'],
|
|
620
529
|
},
|
|
621
530
|
},
|
|
622
|
-
{
|
|
623
|
-
name: 'consistency_checker',
|
|
624
|
-
description: 'Check data consistency across fields',
|
|
625
|
-
inputSchema: {
|
|
626
|
-
type: 'object',
|
|
627
|
-
properties: {
|
|
628
|
-
data: { type: 'array' },
|
|
629
|
-
rules: { type: 'array', description: 'Validation rules' },
|
|
630
|
-
},
|
|
631
|
-
required: ['data', 'rules'],
|
|
632
|
-
},
|
|
633
|
-
},
|
|
634
531
|
// Advanced Captcha Handling (3 tools)
|
|
635
532
|
{
|
|
636
533
|
name: 'ocr_engine',
|
|
@@ -673,21 +570,6 @@ export const TOOLS = [
|
|
|
673
570
|
},
|
|
674
571
|
},
|
|
675
572
|
// Screenshot & Visual Tools (5 tools)
|
|
676
|
-
{
|
|
677
|
-
name: 'full_page_screenshot',
|
|
678
|
-
description: 'Capture entire page screenshot',
|
|
679
|
-
inputSchema: {
|
|
680
|
-
type: 'object',
|
|
681
|
-
properties: {
|
|
682
|
-
url: { type: 'string' },
|
|
683
|
-
outputPath: { type: 'string' },
|
|
684
|
-
format: { type: 'string', enum: ['png', 'jpeg'], default: 'png' },
|
|
685
|
-
quality: { type: 'number', default: 90 },
|
|
686
|
-
fullPage: { type: 'boolean', default: true },
|
|
687
|
-
},
|
|
688
|
-
required: ['outputPath'],
|
|
689
|
-
},
|
|
690
|
-
},
|
|
691
573
|
{
|
|
692
574
|
name: 'element_screenshot',
|
|
693
575
|
description: 'Capture screenshot of specific element',
|
|
@@ -870,18 +752,6 @@ export const TOOLS = [
|
|
|
870
752
|
},
|
|
871
753
|
},
|
|
872
754
|
},
|
|
873
|
-
{
|
|
874
|
-
name: 'cookie_manager',
|
|
875
|
-
description: 'Manage cookies (get, set, delete, clear)',
|
|
876
|
-
inputSchema: {
|
|
877
|
-
type: 'object',
|
|
878
|
-
properties: {
|
|
879
|
-
action: { type: 'string', enum: ['get', 'set', 'delete', 'clear'], default: 'get' },
|
|
880
|
-
cookie: { type: 'object' },
|
|
881
|
-
cookieName: { type: 'string' },
|
|
882
|
-
},
|
|
883
|
-
},
|
|
884
|
-
},
|
|
885
755
|
{
|
|
886
756
|
name: 'form_auto_fill',
|
|
887
757
|
description: 'Automatically fill form fields',
|
|
@@ -922,16 +792,6 @@ export const TOOLS = [
|
|
|
922
792
|
},
|
|
923
793
|
},
|
|
924
794
|
},
|
|
925
|
-
{
|
|
926
|
-
name: 'data_quality_metrics',
|
|
927
|
-
description: 'Report data quality metrics',
|
|
928
|
-
inputSchema: {
|
|
929
|
-
type: 'object',
|
|
930
|
-
properties: {
|
|
931
|
-
data: { type: 'array' },
|
|
932
|
-
},
|
|
933
|
-
},
|
|
934
|
-
},
|
|
935
795
|
// Advanced Video & Media Download Tools
|
|
936
796
|
{
|
|
937
797
|
name: 'video_link_finder',
|
|
@@ -1083,14 +943,11 @@ export const TOOL_NAMES = {
|
|
|
1083
943
|
RANDOM_SCROLL: 'random_scroll',
|
|
1084
944
|
FIND_SELECTOR: 'find_selector',
|
|
1085
945
|
SAVE_CONTENT_AS_MARKDOWN: 'save_content_as_markdown',
|
|
1086
|
-
// Smart Data Extractors
|
|
1087
|
-
EXTRACT_LIST: 'extract_list',
|
|
1088
946
|
EXTRACT_JSON: 'extract_json',
|
|
1089
947
|
SCRAPE_META_TAGS: 'scrape_meta_tags',
|
|
1090
948
|
EXTRACT_SCHEMA: 'extract_schema',
|
|
1091
949
|
// Multi-Element Extractors
|
|
1092
950
|
BATCH_ELEMENT_SCRAPER: 'batch_element_scraper',
|
|
1093
|
-
NESTED_DATA_EXTRACTION: 'nested_data_extraction',
|
|
1094
951
|
ATTRIBUTE_HARVESTER: 'attribute_harvester',
|
|
1095
952
|
// Content Type Specific
|
|
1096
953
|
LINK_HARVESTER: 'link_harvester',
|
|
@@ -1109,11 +966,8 @@ export const TOOL_NAMES = {
|
|
|
1109
966
|
NETWORK_RECORDER: 'network_recorder',
|
|
1110
967
|
API_FINDER: 'api_finder',
|
|
1111
968
|
// Pagination Tools
|
|
1112
|
-
MULTI_PAGE_SCRAPER: 'multi_page_scraper',
|
|
1113
969
|
BREADCRUMB_NAVIGATOR: 'breadcrumb_navigator',
|
|
1114
970
|
// Data Processing
|
|
1115
|
-
HTML_TO_TEXT: 'html_to_text',
|
|
1116
|
-
DUPLICATE_REMOVER: 'duplicate_remover',
|
|
1117
971
|
// AI-Powered Features
|
|
1118
972
|
SMART_SELECTOR_GENERATOR: 'smart_selector_generator',
|
|
1119
973
|
CONTENT_CLASSIFICATION: 'content_classification',
|
|
@@ -1126,16 +980,13 @@ export const TOOL_NAMES = {
|
|
|
1126
980
|
REGEX_PATTERN_MATCHER: 'regex_pattern_matcher',
|
|
1127
981
|
XPATH_SUPPORT: 'xpath_support',
|
|
1128
982
|
ADVANCED_CSS_SELECTORS: 'advanced_css_selectors',
|
|
1129
|
-
VISUAL_ELEMENT_FINDER: 'visual_element_finder',
|
|
1130
983
|
// Data Quality & Validation
|
|
1131
|
-
DATA_DEDUPLICATION: 'data_deduplication',
|
|
1132
984
|
DATA_TYPE_VALIDATOR: 'data_type_validator',
|
|
1133
985
|
// Advanced Captcha Handling
|
|
1134
986
|
OCR_ENGINE: 'ocr_engine',
|
|
1135
987
|
AUDIO_CAPTCHA_SOLVER: 'audio_captcha_solver',
|
|
1136
988
|
PUZZLE_CAPTCHA_HANDLER: 'puzzle_captcha_handler',
|
|
1137
989
|
// Screenshot & Visual Tools
|
|
1138
|
-
FULL_PAGE_SCREENSHOT: 'full_page_screenshot',
|
|
1139
990
|
ELEMENT_SCREENSHOT: 'element_screenshot',
|
|
1140
991
|
VIDEO_RECORDING: 'video_recording',
|
|
1141
992
|
};
|
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.6",
|
|
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",
|