brave-real-browser-mcp-server 2.14.7 → 2.14.8
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/browser-manager.js +5 -0
- package/dist/handlers/APPLY_OPTIMIZATION_PATTERN.js +2 -2
- package/dist/handlers/advanced-video-media-handlers.js +7 -7
- package/dist/handlers/data-processing-handlers.js +0 -102
- package/dist/handlers/monitoring-reporting-handlers.js +0 -170
- package/dist/handlers/multi-element-handlers.js +0 -89
- package/dist/handlers/visual-tools-handlers.js +0 -56
- package/dist/index.js +4 -28
- package/dist/mcp-server.js +1 -4
- package/dist/optimization-utils.js +3 -3
- package/dist/tool-definitions.js +0 -97
- package/package.json +2 -2
package/dist/browser-manager.js
CHANGED
|
@@ -5,7 +5,12 @@ import * as net from 'net';
|
|
|
5
5
|
import { execSync, spawn } from 'child_process';
|
|
6
6
|
import { config as dotenvConfig } from 'dotenv';
|
|
7
7
|
// Load environment variables from .env file
|
|
8
|
+
// Silence dotenv output
|
|
9
|
+
const originalWrite = process.stdout.write;
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
process.stdout.write = () => true;
|
|
8
12
|
dotenvConfig();
|
|
13
|
+
process.stdout.write = originalWrite;
|
|
9
14
|
// Browser error categorization
|
|
10
15
|
export var BrowserErrorType;
|
|
11
16
|
(function (BrowserErrorType) {
|
|
@@ -32,7 +32,7 @@ export async function handleUNIVERSAL_TOOL_TEMPLATE(args) {
|
|
|
32
32
|
if (shouldCache) {
|
|
33
33
|
const cached = globalCache.get(cacheKey);
|
|
34
34
|
if (cached) {
|
|
35
|
-
console.
|
|
35
|
+
console.error(`[${toolName}] Cache hit for key: ${cacheKey}`);
|
|
36
36
|
return {
|
|
37
37
|
content: [
|
|
38
38
|
{
|
|
@@ -87,7 +87,7 @@ export async function handleUNIVERSAL_TOOL_TEMPLATE(args) {
|
|
|
87
87
|
// Cleanup and metrics
|
|
88
88
|
const duration = globalMetrics.end(toolName);
|
|
89
89
|
globalToolStatus.recordExecution(toolName, duration);
|
|
90
|
-
console.
|
|
90
|
+
console.error(`[${toolName}] Execution time: ${duration}ms`);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
// ============================================================================
|
|
@@ -580,7 +580,7 @@ export async function handleNetworkRecordingFinder(args) {
|
|
|
580
580
|
const contentType = response.headers()['content-type'] || '';
|
|
581
581
|
const resourceType = response.request().resourceType();
|
|
582
582
|
if (verbose && totalResponses % 10 === 0) {
|
|
583
|
-
console.
|
|
583
|
+
console.error(`[Network Recording] Processed ${totalResponses} responses, ${matchedResponses} matched`);
|
|
584
584
|
}
|
|
585
585
|
let shouldRecord = false;
|
|
586
586
|
const urlLower = url.toLowerCase();
|
|
@@ -603,7 +603,7 @@ export async function handleNetworkRecordingFinder(args) {
|
|
|
603
603
|
if (shouldRecord) {
|
|
604
604
|
matchedResponses++;
|
|
605
605
|
if (verbose) {
|
|
606
|
-
console.
|
|
606
|
+
console.error(`[Network Recording] ✅ Matched ${filterType}: ${url.substring(0, 100)}`);
|
|
607
607
|
}
|
|
608
608
|
try {
|
|
609
609
|
const buffer = await response.buffer();
|
|
@@ -629,21 +629,21 @@ export async function handleNetworkRecordingFinder(args) {
|
|
|
629
629
|
// Ignore individual response errors
|
|
630
630
|
}
|
|
631
631
|
};
|
|
632
|
-
console.
|
|
632
|
+
console.error(`[Network Recording] 🎬 Starting monitoring for ${filterType} (${duration}ms)${navigateTo ? ` + navigating to ${navigateTo}` : ''}`);
|
|
633
633
|
page.on('response', responseHandler);
|
|
634
634
|
// If navigateTo is provided, navigate first, then wait
|
|
635
635
|
if (navigateTo) {
|
|
636
636
|
try {
|
|
637
637
|
await page.goto(navigateTo, { waitUntil: 'networkidle2', timeout: 30000 });
|
|
638
|
-
console.
|
|
638
|
+
console.error(`[Network Recording] ✅ Navigation complete, continuing monitoring...`);
|
|
639
639
|
}
|
|
640
640
|
catch (e) {
|
|
641
|
-
console.
|
|
641
|
+
console.error(`[Network Recording] ⚠️ Navigation error (continuing anyway): ${e}`);
|
|
642
642
|
}
|
|
643
643
|
}
|
|
644
644
|
await sleep(duration);
|
|
645
645
|
page.off('response', responseHandler);
|
|
646
|
-
console.
|
|
646
|
+
console.error(`[Network Recording] 🛑 Monitoring stopped. Total: ${totalResponses}, Matched: ${matchedResponses}, Recorded: ${recordings.length}`);
|
|
647
647
|
if (recordings.length === 0) {
|
|
648
648
|
return {
|
|
649
649
|
content: [{
|
|
@@ -717,7 +717,7 @@ export async function handleNetworkRecordingExtractors(args) {
|
|
|
717
717
|
(contentType.includes('application/octet-stream') && url.includes('video'));
|
|
718
718
|
if (isVideoFile || isVideoAPI) {
|
|
719
719
|
if (verbose)
|
|
720
|
-
console.
|
|
720
|
+
console.error(`[Extractor] 🎥 Video found: ${url.substring(0, 80)}`);
|
|
721
721
|
extractedData.videos.push({
|
|
722
722
|
url,
|
|
723
723
|
contentType,
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// @ts-nocheck
|
|
4
4
|
import { withErrorHandling } from '../system-utils.js';
|
|
5
5
|
import { parsePhoneNumber } from 'libphonenumber-js';
|
|
6
|
-
import * as chrono from 'chrono-node';
|
|
7
6
|
import Ajv from 'ajv/dist/2020.js';
|
|
8
7
|
/**
|
|
9
8
|
* Extra whitespace और special characters remove करता है
|
|
@@ -85,107 +84,6 @@ export async function handleHTMLToText(args) {
|
|
|
85
84
|
};
|
|
86
85
|
}, 'Failed to convert HTML to text');
|
|
87
86
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Currency symbols और formatting से actual numbers निकालता है
|
|
90
|
-
*/
|
|
91
|
-
export async function handlePriceParser(args) {
|
|
92
|
-
return await withErrorHandling(async () => {
|
|
93
|
-
const text = args.text;
|
|
94
|
-
const currency = args.currency;
|
|
95
|
-
// Regular expressions for price patterns
|
|
96
|
-
const pricePatterns = [
|
|
97
|
-
/\$\s?(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)/g, // $1,234.56
|
|
98
|
-
/(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)\s?USD/gi, // 1234.56 USD
|
|
99
|
-
/€\s?(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)/g, // €1,234.56
|
|
100
|
-
/£\s?(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)/g, // £1,234.56
|
|
101
|
-
/₹\s?(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)/g, // ₹1,234.56
|
|
102
|
-
/(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)/g, // 1,234.56
|
|
103
|
-
];
|
|
104
|
-
const prices = [];
|
|
105
|
-
pricePatterns.forEach((pattern) => {
|
|
106
|
-
let match;
|
|
107
|
-
while ((match = pattern.exec(text)) !== null) {
|
|
108
|
-
const priceStr = match[1] || match[0];
|
|
109
|
-
const numericValue = parseFloat(priceStr.replace(/,/g, ''));
|
|
110
|
-
if (!isNaN(numericValue)) {
|
|
111
|
-
// Detect currency symbol
|
|
112
|
-
let detectedCurrency = currency || 'Unknown';
|
|
113
|
-
if (match[0].includes('$'))
|
|
114
|
-
detectedCurrency = 'USD';
|
|
115
|
-
else if (match[0].includes('€'))
|
|
116
|
-
detectedCurrency = 'EUR';
|
|
117
|
-
else if (match[0].includes('£'))
|
|
118
|
-
detectedCurrency = 'GBP';
|
|
119
|
-
else if (match[0].includes('₹'))
|
|
120
|
-
detectedCurrency = 'INR';
|
|
121
|
-
prices.push({
|
|
122
|
-
original: match[0],
|
|
123
|
-
value: numericValue,
|
|
124
|
-
currency: detectedCurrency,
|
|
125
|
-
formatted: `${detectedCurrency} ${numericValue.toFixed(2)}`,
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
// Remove duplicates
|
|
131
|
-
const uniquePrices = prices.filter((price, index, self) => index === self.findIndex((p) => p.value === price.value && p.currency === price.currency));
|
|
132
|
-
return {
|
|
133
|
-
content: [
|
|
134
|
-
{
|
|
135
|
-
type: 'text',
|
|
136
|
-
text: `✅ Parsed ${uniquePrices.length} price(s)\n\n${JSON.stringify(uniquePrices, null, 2)}`,
|
|
137
|
-
},
|
|
138
|
-
],
|
|
139
|
-
};
|
|
140
|
-
}, 'Failed to parse prices');
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Different date formats को standard format में convert करता है
|
|
144
|
-
*/
|
|
145
|
-
export async function handleDateNormalizer(args) {
|
|
146
|
-
return await withErrorHandling(async () => {
|
|
147
|
-
const text = args.text;
|
|
148
|
-
const outputFormat = args.outputFormat || 'iso';
|
|
149
|
-
// Parse dates using chrono-node
|
|
150
|
-
const parsedDates = chrono.parse(text);
|
|
151
|
-
const dates = [];
|
|
152
|
-
parsedDates.forEach((parsed) => {
|
|
153
|
-
const date = parsed.start.date();
|
|
154
|
-
let formatted;
|
|
155
|
-
if (outputFormat === 'iso') {
|
|
156
|
-
formatted = date.toISOString();
|
|
157
|
-
}
|
|
158
|
-
else if (outputFormat === 'locale') {
|
|
159
|
-
formatted = date.toLocaleString();
|
|
160
|
-
}
|
|
161
|
-
else if (outputFormat === 'unix') {
|
|
162
|
-
formatted = Math.floor(date.getTime() / 1000);
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
formatted = date.toISOString();
|
|
166
|
-
}
|
|
167
|
-
dates.push({
|
|
168
|
-
original: parsed.text,
|
|
169
|
-
parsed: formatted,
|
|
170
|
-
components: {
|
|
171
|
-
year: date.getFullYear(),
|
|
172
|
-
month: date.getMonth() + 1,
|
|
173
|
-
day: date.getDate(),
|
|
174
|
-
hour: date.getHours(),
|
|
175
|
-
minute: date.getMinutes(),
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
return {
|
|
180
|
-
content: [
|
|
181
|
-
{
|
|
182
|
-
type: 'text',
|
|
183
|
-
text: `✅ Normalized ${dates.length} date(s)\n\n${JSON.stringify(dates, null, 2)}`,
|
|
184
|
-
},
|
|
185
|
-
],
|
|
186
|
-
};
|
|
187
|
-
}, 'Failed to normalize dates');
|
|
188
|
-
}
|
|
189
87
|
/**
|
|
190
88
|
* Contact information automatically detect करता है
|
|
191
89
|
*/
|
|
@@ -110,91 +110,9 @@ export async function handleProgressTracker(args) {
|
|
|
110
110
|
throw new Error(`Unknown action: ${action}`);
|
|
111
111
|
}, 'Failed progress tracker');
|
|
112
112
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Error Logger - Log and track errors
|
|
115
|
-
*/
|
|
116
|
-
export async function handleErrorLogger(args) {
|
|
117
|
-
return await withErrorHandling(async () => {
|
|
118
|
-
const action = args.action || 'log'; // log, get, clear
|
|
119
|
-
if (action === 'log') {
|
|
120
|
-
const error = {
|
|
121
|
-
id: `err_${Date.now()}`,
|
|
122
|
-
message: args.message || 'Unknown error',
|
|
123
|
-
type: args.type || 'error',
|
|
124
|
-
timestamp: new Date().toISOString(),
|
|
125
|
-
context: args.context || {},
|
|
126
|
-
stackTrace: args.stackTrace || null,
|
|
127
|
-
};
|
|
128
|
-
monitoringState.errors.push(error);
|
|
129
|
-
return {
|
|
130
|
-
content: [{
|
|
131
|
-
type: 'text',
|
|
132
|
-
text: `✅ Error logged: ${error.message}\n\n${JSON.stringify(error, null, 2)}`,
|
|
133
|
-
}],
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
if (action === 'get') {
|
|
137
|
-
const limit = args.limit || 10;
|
|
138
|
-
const errorType = args.type;
|
|
139
|
-
let filteredErrors = monitoringState.errors;
|
|
140
|
-
if (errorType) {
|
|
141
|
-
filteredErrors = filteredErrors.filter((err) => err.type === errorType);
|
|
142
|
-
}
|
|
143
|
-
const recentErrors = filteredErrors.slice(-limit);
|
|
144
|
-
return {
|
|
145
|
-
content: [{
|
|
146
|
-
type: 'text',
|
|
147
|
-
text: `✅ Retrieved ${recentErrors.length} error(s)\n\nTotal Errors: ${monitoringState.errors.length}\n\n${JSON.stringify(recentErrors, null, 2)}`,
|
|
148
|
-
}],
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
if (action === 'clear') {
|
|
152
|
-
const count = monitoringState.errors.length;
|
|
153
|
-
monitoringState.errors = [];
|
|
154
|
-
return {
|
|
155
|
-
content: [{
|
|
156
|
-
type: 'text',
|
|
157
|
-
text: `✅ Cleared ${count} error(s)`,
|
|
158
|
-
}],
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
throw new Error(`Unknown action: ${action}`);
|
|
162
|
-
}, 'Failed error logger');
|
|
163
|
-
}
|
|
164
113
|
/**
|
|
165
114
|
* Success Rate Reporter - Report success metrics
|
|
166
115
|
*/
|
|
167
|
-
export async function handleSuccessRateReporter(args) {
|
|
168
|
-
return await withErrorHandling(async () => {
|
|
169
|
-
const timeRange = args.timeRange || 'all'; // all, last_hour, last_day
|
|
170
|
-
let operations = monitoringState.operations;
|
|
171
|
-
if (timeRange === 'last_hour') {
|
|
172
|
-
const hourAgo = Date.now() - (60 * 60 * 1000);
|
|
173
|
-
operations = operations.filter((op) => op.startTime >= hourAgo);
|
|
174
|
-
}
|
|
175
|
-
else if (timeRange === 'last_day') {
|
|
176
|
-
const dayAgo = Date.now() - (24 * 60 * 60 * 1000);
|
|
177
|
-
operations = operations.filter((op) => op.startTime >= dayAgo);
|
|
178
|
-
}
|
|
179
|
-
const total = operations.length;
|
|
180
|
-
const completed = operations.filter((op) => op.status === 'completed').length;
|
|
181
|
-
const failed = operations.filter((op) => op.status === 'failed').length;
|
|
182
|
-
const inProgress = operations.filter((op) => op.status === 'in_progress').length;
|
|
183
|
-
const successRate = total > 0 ? ((completed / total) * 100).toFixed(2) : 0;
|
|
184
|
-
const failureRate = total > 0 ? ((failed / total) * 100).toFixed(2) : 0;
|
|
185
|
-
// Calculate average duration
|
|
186
|
-
const completedOps = operations.filter((op) => op.duration !== undefined);
|
|
187
|
-
const avgDuration = completedOps.length > 0
|
|
188
|
-
? (completedOps.reduce((sum, op) => sum + op.duration, 0) / completedOps.length).toFixed(2)
|
|
189
|
-
: 0;
|
|
190
|
-
return {
|
|
191
|
-
content: [{
|
|
192
|
-
type: 'text',
|
|
193
|
-
text: `✅ Success Rate Report (${timeRange})\n\nTotal Operations: ${total}\nCompleted: ${completed}\nFailed: ${failed}\nIn Progress: ${inProgress}\n\nSuccess Rate: ${successRate}%\nFailure Rate: ${failureRate}%\nAverage Duration: ${avgDuration}ms\n\nUptime: ${((Date.now() - monitoringState.startTime) / 1000 / 60).toFixed(2)} minutes`,
|
|
194
|
-
}],
|
|
195
|
-
};
|
|
196
|
-
}, 'Failed success rate reporter');
|
|
197
|
-
}
|
|
198
116
|
/**
|
|
199
117
|
* Data Quality Metrics - Report data quality metrics
|
|
200
118
|
*/
|
|
@@ -282,94 +200,6 @@ export async function handleDataQualityMetrics(args) {
|
|
|
282
200
|
/**
|
|
283
201
|
* Performance Monitor - Monitor browser and page performance
|
|
284
202
|
*/
|
|
285
|
-
export async function handlePerformanceMonitor(args) {
|
|
286
|
-
return await withErrorHandling(async () => {
|
|
287
|
-
validateWorkflow('performance_monitor', {
|
|
288
|
-
requireBrowser: true,
|
|
289
|
-
requirePage: true,
|
|
290
|
-
});
|
|
291
|
-
const page = getCurrentPage();
|
|
292
|
-
const performanceData = await page.evaluate(() => {
|
|
293
|
-
const perfData = {
|
|
294
|
-
navigation: {},
|
|
295
|
-
resources: [],
|
|
296
|
-
memory: {},
|
|
297
|
-
timing: {},
|
|
298
|
-
};
|
|
299
|
-
// Navigation timing
|
|
300
|
-
if (performance.timing) {
|
|
301
|
-
const timing = performance.timing;
|
|
302
|
-
perfData.navigation = {
|
|
303
|
-
domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,
|
|
304
|
-
loadComplete: timing.loadEventEnd - timing.navigationStart,
|
|
305
|
-
domInteractive: timing.domInteractive - timing.navigationStart,
|
|
306
|
-
firstPaint: timing.responseEnd - timing.requestStart,
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
// Resource timing
|
|
310
|
-
if (performance.getEntriesByType) {
|
|
311
|
-
const resources = performance.getEntriesByType('resource');
|
|
312
|
-
perfData.resources = resources.slice(0, 20).map((resource) => ({
|
|
313
|
-
name: resource.name.substring(0, 100),
|
|
314
|
-
type: resource.initiatorType,
|
|
315
|
-
duration: Math.round(resource.duration),
|
|
316
|
-
size: resource.transferSize || 0,
|
|
317
|
-
}));
|
|
318
|
-
}
|
|
319
|
-
// Memory (if available)
|
|
320
|
-
if (performance.memory) {
|
|
321
|
-
const memory = performance.memory;
|
|
322
|
-
perfData.memory = {
|
|
323
|
-
usedJSHeapSize: Math.round(memory.usedJSHeapSize / 1024 / 1024) + ' MB',
|
|
324
|
-
totalJSHeapSize: Math.round(memory.totalJSHeapSize / 1024 / 1024) + ' MB',
|
|
325
|
-
jsHeapSizeLimit: Math.round(memory.jsHeapSizeLimit / 1024 / 1024) + ' MB',
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
// Performance marks and measures
|
|
329
|
-
if (performance.getEntriesByType) {
|
|
330
|
-
const marks = performance.getEntriesByType('mark');
|
|
331
|
-
const measures = performance.getEntriesByType('measure');
|
|
332
|
-
perfData.timing.marks = marks.length;
|
|
333
|
-
perfData.timing.measures = measures.length;
|
|
334
|
-
}
|
|
335
|
-
return perfData;
|
|
336
|
-
});
|
|
337
|
-
// Calculate summary
|
|
338
|
-
const resourceCount = performanceData.resources.length;
|
|
339
|
-
const totalResourceDuration = performanceData.resources.reduce((sum, r) => sum + r.duration, 0);
|
|
340
|
-
const avgResourceDuration = resourceCount > 0 ? (totalResourceDuration / resourceCount).toFixed(2) : 0;
|
|
341
|
-
return {
|
|
342
|
-
content: [{
|
|
343
|
-
type: 'text',
|
|
344
|
-
text: `✅ Performance Monitor\n\nPage Load Metrics:\n${JSON.stringify(performanceData.navigation, null, 2)}\n\nResources (showing ${resourceCount}):\nAverage Load Time: ${avgResourceDuration}ms\n\nMemory Usage:\n${JSON.stringify(performanceData.memory, null, 2)}\n\nTop Resources:\n${JSON.stringify(performanceData.resources.slice(0, 10), null, 2)}`,
|
|
345
|
-
}],
|
|
346
|
-
};
|
|
347
|
-
}, 'Failed performance monitor');
|
|
348
|
-
}
|
|
349
203
|
/**
|
|
350
204
|
* Get Monitoring Summary - Get overall monitoring summary
|
|
351
205
|
*/
|
|
352
|
-
export async function handleGetMonitoringSummary(args) {
|
|
353
|
-
return await withErrorHandling(async () => {
|
|
354
|
-
const summary = {
|
|
355
|
-
uptime: ((Date.now() - monitoringState.startTime) / 1000 / 60).toFixed(2) + ' minutes',
|
|
356
|
-
operations: {
|
|
357
|
-
total: monitoringState.operations.length,
|
|
358
|
-
completed: monitoringState.operations.filter((op) => op.status === 'completed').length,
|
|
359
|
-
failed: monitoringState.operations.filter((op) => op.status === 'failed').length,
|
|
360
|
-
inProgress: monitoringState.operations.filter((op) => op.status === 'in_progress').length,
|
|
361
|
-
},
|
|
362
|
-
errors: {
|
|
363
|
-
total: monitoringState.errors.length,
|
|
364
|
-
recent: monitoringState.errors.slice(-5),
|
|
365
|
-
},
|
|
366
|
-
metrics: monitoringState.metrics,
|
|
367
|
-
};
|
|
368
|
-
return {
|
|
369
|
-
content: [{
|
|
370
|
-
type: 'text',
|
|
371
|
-
text: `✅ Monitoring Summary\n\n${JSON.stringify(summary, null, 2)}`,
|
|
372
|
-
}],
|
|
373
|
-
};
|
|
374
|
-
}, 'Failed to get monitoring summary');
|
|
375
|
-
}
|
|
@@ -441,92 +441,3 @@ export async function handleMediaExtractor(args) {
|
|
|
441
441
|
};
|
|
442
442
|
}, 'Failed to extract media');
|
|
443
443
|
}
|
|
444
|
-
/**
|
|
445
|
-
* Downloadable files (PDF, DOC, etc.) detect करता है
|
|
446
|
-
*/
|
|
447
|
-
export async function handlePDFLinkFinder(args) {
|
|
448
|
-
return await withErrorHandling(async () => {
|
|
449
|
-
validateWorkflow('pdf_link_finder', {
|
|
450
|
-
requireBrowser: true,
|
|
451
|
-
requirePage: true,
|
|
452
|
-
});
|
|
453
|
-
const page = getCurrentPage();
|
|
454
|
-
const selector = args.selector || 'a[href]';
|
|
455
|
-
const includeOtherFiles = args.includeOtherFiles !== false;
|
|
456
|
-
const fileData = await page.evaluate(({ selector, includeOtherFiles }) => {
|
|
457
|
-
const links = document.querySelectorAll(selector);
|
|
458
|
-
const results = {
|
|
459
|
-
pdfs: [],
|
|
460
|
-
documents: [],
|
|
461
|
-
archives: [],
|
|
462
|
-
others: [],
|
|
463
|
-
};
|
|
464
|
-
const fileExtensions = {
|
|
465
|
-
pdf: ['pdf'],
|
|
466
|
-
documents: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'ods', 'odp'],
|
|
467
|
-
archives: ['zip', 'rar', '7z', 'tar', 'gz', 'bz2'],
|
|
468
|
-
others: ['txt', 'csv', 'json', 'xml'],
|
|
469
|
-
};
|
|
470
|
-
links.forEach((link, index) => {
|
|
471
|
-
const href = link.href;
|
|
472
|
-
const text = link.textContent?.trim() || '';
|
|
473
|
-
// Check file extension
|
|
474
|
-
const url = href.toLowerCase();
|
|
475
|
-
let fileType = '';
|
|
476
|
-
let category = '';
|
|
477
|
-
for (const [cat, exts] of Object.entries(fileExtensions)) {
|
|
478
|
-
for (const ext of exts) {
|
|
479
|
-
if (url.endsWith(`.${ext}`) || url.includes(`.${ext}?`) || url.includes(`.${ext}#`)) {
|
|
480
|
-
fileType = ext;
|
|
481
|
-
category = cat;
|
|
482
|
-
break;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
if (fileType)
|
|
486
|
-
break;
|
|
487
|
-
}
|
|
488
|
-
if (!fileType && !includeOtherFiles) {
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
const fileInfo = {
|
|
492
|
-
index,
|
|
493
|
-
href,
|
|
494
|
-
text,
|
|
495
|
-
fileType,
|
|
496
|
-
fileName: href.split('/').pop()?.split('?')[0] || '',
|
|
497
|
-
};
|
|
498
|
-
// Get file size if available
|
|
499
|
-
const sizeAttr = link.getAttribute('data-size') || link.getAttribute('title');
|
|
500
|
-
if (sizeAttr) {
|
|
501
|
-
fileInfo.size = sizeAttr;
|
|
502
|
-
}
|
|
503
|
-
// Categorize
|
|
504
|
-
if (category === 'pdf') {
|
|
505
|
-
results.pdfs.push(fileInfo);
|
|
506
|
-
}
|
|
507
|
-
else if (category === 'documents') {
|
|
508
|
-
results.documents.push(fileInfo);
|
|
509
|
-
}
|
|
510
|
-
else if (category === 'archives') {
|
|
511
|
-
results.archives.push(fileInfo);
|
|
512
|
-
}
|
|
513
|
-
else if (includeOtherFiles) {
|
|
514
|
-
results.others.push(fileInfo);
|
|
515
|
-
}
|
|
516
|
-
});
|
|
517
|
-
return results;
|
|
518
|
-
}, { selector, includeOtherFiles });
|
|
519
|
-
const totalFiles = fileData.pdfs.length +
|
|
520
|
-
fileData.documents.length +
|
|
521
|
-
fileData.archives.length +
|
|
522
|
-
fileData.others.length;
|
|
523
|
-
return {
|
|
524
|
-
content: [
|
|
525
|
-
{
|
|
526
|
-
type: 'text',
|
|
527
|
-
text: `✅ Found ${totalFiles} downloadable files\n\n${JSON.stringify(fileData, null, 2)}`,
|
|
528
|
-
},
|
|
529
|
-
],
|
|
530
|
-
};
|
|
531
|
-
}, 'Failed to find PDF links');
|
|
532
|
-
}
|
|
@@ -150,62 +150,6 @@ export async function handleElementScreenshot(args) {
|
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
/**
|
|
154
|
-
* PDF Generation - Convert page to PDF
|
|
155
|
-
*/
|
|
156
|
-
export async function handlePDFGeneration(args) {
|
|
157
|
-
const { url, outputPath, format = 'A4', landscape = false, printBackground = true, margin } = args;
|
|
158
|
-
try {
|
|
159
|
-
const page = getPageInstance();
|
|
160
|
-
if (!page) {
|
|
161
|
-
throw new Error('Browser not initialized. Call browser_init first.');
|
|
162
|
-
}
|
|
163
|
-
if (url && page.url() !== url) {
|
|
164
|
-
await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
|
|
165
|
-
}
|
|
166
|
-
// Ensure output directory exists
|
|
167
|
-
if (outputPath) {
|
|
168
|
-
const dir = path.dirname(outputPath);
|
|
169
|
-
await fs.mkdir(dir, { recursive: true });
|
|
170
|
-
}
|
|
171
|
-
const pdfOptions = {
|
|
172
|
-
path: outputPath,
|
|
173
|
-
format,
|
|
174
|
-
landscape,
|
|
175
|
-
printBackground
|
|
176
|
-
};
|
|
177
|
-
if (margin) {
|
|
178
|
-
pdfOptions.margin = margin;
|
|
179
|
-
}
|
|
180
|
-
await page.pdf(pdfOptions);
|
|
181
|
-
// Get file stats
|
|
182
|
-
let fileSize = 0;
|
|
183
|
-
if (outputPath) {
|
|
184
|
-
const stats = await fs.stat(outputPath);
|
|
185
|
-
fileSize = stats.size;
|
|
186
|
-
}
|
|
187
|
-
const resultText = `✅ PDF generated successfully\n\nPath: ${outputPath}\nFormat: ${format}\nLandscape: ${landscape}\nFile Size: ${(fileSize / 1024).toFixed(2)} KB (${(fileSize / (1024 * 1024)).toFixed(2)} MB)\nTimestamp: ${new Date().toISOString()}`;
|
|
188
|
-
return {
|
|
189
|
-
content: [
|
|
190
|
-
{
|
|
191
|
-
type: 'text',
|
|
192
|
-
text: resultText,
|
|
193
|
-
},
|
|
194
|
-
],
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
return {
|
|
199
|
-
content: [
|
|
200
|
-
{
|
|
201
|
-
type: 'text',
|
|
202
|
-
text: `❌ PDF generation failed: ${error.message}`,
|
|
203
|
-
},
|
|
204
|
-
],
|
|
205
|
-
isError: true,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
153
|
/**
|
|
210
154
|
* Video Recording - Record browser session (basic implementation)
|
|
211
155
|
*/
|
package/dist/index.js
CHANGED
|
@@ -27,11 +27,11 @@ import { handleSaveContentAsMarkdown } from "./handlers/file-handlers.js";
|
|
|
27
27
|
// Import new data extraction handlers
|
|
28
28
|
import { handleScrapeTable, handleExtractList, handleExtractJSON, handleScrapeMetaTags, handleExtractSchema, } from "./handlers/data-extraction-handlers.js";
|
|
29
29
|
// Import multi-element handlers
|
|
30
|
-
import { handleBatchElementScraper, handleNestedDataExtraction, handleAttributeHarvester, handleImageScraper, handleLinkHarvester, handleMediaExtractor,
|
|
30
|
+
import { handleBatchElementScraper, handleNestedDataExtraction, handleAttributeHarvester, handleImageScraper, handleLinkHarvester, handleMediaExtractor, } from "./handlers/multi-element-handlers.js";
|
|
31
31
|
// Import pagination handlers
|
|
32
32
|
import { handleAutoPagination, handleInfiniteScroll, handleMultiPageScraper, handleSitemapParser, handleBreadcrumbNavigator, } from "./handlers/pagination-handlers.js";
|
|
33
33
|
// Import data processing handlers
|
|
34
|
-
import { handleSmartTextCleaner, handleHTMLToText,
|
|
34
|
+
import { handleSmartTextCleaner, handleHTMLToText, handleContactExtractor, handleSchemaValidator, handleRequiredFieldsChecker, handleDuplicateRemover, } from "./handlers/data-processing-handlers.js";
|
|
35
35
|
// Import AI-powered handlers
|
|
36
36
|
import { handleSmartSelectorGenerator, handleContentClassification, handleSentimentAnalysis, handleSummaryGenerator, handleTranslationSupport, } from "./handlers/ai-powered-handlers.js";
|
|
37
37
|
// Import search & filter handlers
|
|
@@ -41,13 +41,13 @@ import { handleDataDeduplication, handleMissingDataHandler, handleDataTypeValida
|
|
|
41
41
|
// Import captcha handlers
|
|
42
42
|
import { handleOCREngine, handleAudioCaptchaSolver, handlePuzzleCaptchaHandler, } from "./handlers/captcha-handlers.js";
|
|
43
43
|
// Import visual tools handlers
|
|
44
|
-
import { handleFullPageScreenshot, handleElementScreenshot,
|
|
44
|
+
import { handleFullPageScreenshot, handleElementScreenshot, handleVideoRecording, handleVisualComparison, } from "./handlers/visual-tools-handlers.js";
|
|
45
45
|
// Import smart data extractors
|
|
46
46
|
import { handleHtmlElementsExtractor, handleTagsFinder, handleLinksFinder, handleXpathLinks, handleAjaxExtractor, handleFetchXHR, handleNetworkRecorder, handleRegexPatternFinder, handleIframeExtractor, handleEmbedPageExtractor, handleImageExtractorAdvanced, handleVideoSourceExtractor, handleVideoPlayerExtractor, handleVideoPlayerHosterFinder, handleOriginalVideoHosterFinder, handleUrlRedirectTracer, handleUserAgentExtractor, } from "./handlers/smart-data-extractors.js";
|
|
47
47
|
// Import dynamic session handlers
|
|
48
48
|
import { handleShadowDOMExtractor, handleCookieManager, handleSessionPersistence, handleFormAutoFill, handleAjaxContentWaiter, handleModalPopupHandler, handleLoginSessionManager, } from "./handlers/dynamic-session-handlers.js";
|
|
49
49
|
// Import monitoring & reporting handlers
|
|
50
|
-
import { handleProgressTracker,
|
|
50
|
+
import { handleProgressTracker, handleDataQualityMetrics, } from "./handlers/monitoring-reporting-handlers.js";
|
|
51
51
|
// Import advanced video & media handlers
|
|
52
52
|
import { handleVideoLinkFinder, handleVideoDownloadPage, handleVideoDownloadButton, handleVideoPlayPushSource, handleVideoPlayButtonClick, handleUrlRedirectTraceEndpoints, handleNetworkRecordingFinder, handleNetworkRecordingExtractors, handleVideoLinksFinders, handleVideosSelectors, handleLinkProcessExtracts, handleVideoLinkFindersExtracts, handleVideoDownloadButtonFinders, } from "./handlers/advanced-video-media-handlers.js";
|
|
53
53
|
// Import advanced extraction handlers (Ad-bypass & Obfuscation)
|
|
@@ -173,9 +173,6 @@ export async function executeToolByName(name, args) {
|
|
|
173
173
|
case TOOL_NAMES.MEDIA_EXTRACTOR:
|
|
174
174
|
result = await handleMediaExtractor(args || {});
|
|
175
175
|
break;
|
|
176
|
-
case TOOL_NAMES.PDF_LINK_FINDER:
|
|
177
|
-
result = await handlePDFLinkFinder(args || {});
|
|
178
|
-
break;
|
|
179
176
|
// Pagination Tools
|
|
180
177
|
case TOOL_NAMES.AUTO_PAGINATION:
|
|
181
178
|
result = await handleAutoPagination(args || {});
|
|
@@ -199,12 +196,6 @@ export async function executeToolByName(name, args) {
|
|
|
199
196
|
case TOOL_NAMES.HTML_TO_TEXT:
|
|
200
197
|
result = await handleHTMLToText(args);
|
|
201
198
|
break;
|
|
202
|
-
case TOOL_NAMES.PRICE_PARSER:
|
|
203
|
-
result = await handlePriceParser(args);
|
|
204
|
-
break;
|
|
205
|
-
case TOOL_NAMES.DATE_NORMALIZER:
|
|
206
|
-
result = await handleDateNormalizer(args);
|
|
207
|
-
break;
|
|
208
199
|
case TOOL_NAMES.CONTACT_EXTRACTOR:
|
|
209
200
|
result = await handleContactExtractor(args);
|
|
210
201
|
break;
|
|
@@ -283,9 +274,6 @@ export async function executeToolByName(name, args) {
|
|
|
283
274
|
case TOOL_NAMES.ELEMENT_SCREENSHOT:
|
|
284
275
|
result = await handleElementScreenshot(args);
|
|
285
276
|
break;
|
|
286
|
-
case TOOL_NAMES.PDF_GENERATION:
|
|
287
|
-
result = await handlePDFGeneration(args);
|
|
288
|
-
break;
|
|
289
277
|
case TOOL_NAMES.VIDEO_RECORDING:
|
|
290
278
|
result = await handleVideoRecording(args);
|
|
291
279
|
break;
|
|
@@ -370,21 +358,9 @@ export async function executeToolByName(name, args) {
|
|
|
370
358
|
case "progress_tracker":
|
|
371
359
|
result = await handleProgressTracker(args || {});
|
|
372
360
|
break;
|
|
373
|
-
case "error_logger":
|
|
374
|
-
result = await handleErrorLogger(args || {});
|
|
375
|
-
break;
|
|
376
|
-
case "success_rate_reporter":
|
|
377
|
-
result = await handleSuccessRateReporter(args || {});
|
|
378
|
-
break;
|
|
379
361
|
case "data_quality_metrics":
|
|
380
362
|
result = await handleDataQualityMetrics(args || {});
|
|
381
363
|
break;
|
|
382
|
-
case "performance_monitor":
|
|
383
|
-
result = await handlePerformanceMonitor(args || {});
|
|
384
|
-
break;
|
|
385
|
-
case "monitoring_summary":
|
|
386
|
-
result = await handleGetMonitoringSummary(args || {});
|
|
387
|
-
break;
|
|
388
364
|
// Advanced Video & Media Download Tools
|
|
389
365
|
case "video_link_finder":
|
|
390
366
|
result = await handleVideoLinkFinder(args || {});
|
package/dist/mcp-server.js
CHANGED
|
@@ -9,7 +9,7 @@ import { handleClick, handleType, handlePressKey, handleSolveCaptcha, handleRand
|
|
|
9
9
|
import { handleGetContent, handleFindSelector } from './handlers/content-handlers.js';
|
|
10
10
|
import { handleSaveContentAsMarkdown } from './handlers/file-handlers.js';
|
|
11
11
|
import { handleScrapeTable, handleExtractList, handleExtractJSON, handleScrapeMetaTags, handleExtractSchema } from './handlers/data-extraction-handlers.js';
|
|
12
|
-
import { handleBatchElementScraper, handleNestedDataExtraction, handleAttributeHarvester, handleImageScraper, handleLinkHarvester, handleMediaExtractor,
|
|
12
|
+
import { handleBatchElementScraper, handleNestedDataExtraction, handleAttributeHarvester, handleImageScraper, handleLinkHarvester, handleMediaExtractor, } from './handlers/multi-element-handlers.js';
|
|
13
13
|
export async function createMcpServer() {
|
|
14
14
|
const server = new Server(SERVER_INFO, { capabilities: CAPABILITIES });
|
|
15
15
|
// Register initialize handler
|
|
@@ -111,9 +111,6 @@ export async function createMcpServer() {
|
|
|
111
111
|
case TOOL_NAMES.MEDIA_EXTRACTOR:
|
|
112
112
|
result = await handleMediaExtractor(args || {});
|
|
113
113
|
break;
|
|
114
|
-
case TOOL_NAMES.PDF_LINK_FINDER:
|
|
115
|
-
result = await handlePDFLinkFinder(args || {});
|
|
116
|
-
break;
|
|
117
114
|
default:
|
|
118
115
|
throw new Error(`Unknown tool: ${name}`);
|
|
119
116
|
}
|
|
@@ -207,7 +207,7 @@ export async function executeToolWithOptimizations(toolName, toolFn, options = {
|
|
|
207
207
|
if (cacheKey && shouldCache) {
|
|
208
208
|
const cached = globalCache.get(cacheKey);
|
|
209
209
|
if (cached) {
|
|
210
|
-
console.
|
|
210
|
+
console.error(`[${toolName}] Cache hit for key: ${cacheKey}`);
|
|
211
211
|
return cached;
|
|
212
212
|
}
|
|
213
213
|
}
|
|
@@ -226,7 +226,7 @@ export async function executeToolWithOptimizations(toolName, toolFn, options = {
|
|
|
226
226
|
catch (error) {
|
|
227
227
|
// Retry on failure for network tools
|
|
228
228
|
if (retryAttempts > 0) {
|
|
229
|
-
console.
|
|
229
|
+
console.error(`[${toolName}] Retrying after error: ${error instanceof Error ? error.message : String(error)}`);
|
|
230
230
|
return retryWithBackoff(toolFn, retryAttempts, retryDelay);
|
|
231
231
|
}
|
|
232
232
|
throw error;
|
|
@@ -253,7 +253,7 @@ export async function cleanupToolResources(page, context) {
|
|
|
253
253
|
// Clear cache periodically
|
|
254
254
|
const cacheStats = globalCache.getStats();
|
|
255
255
|
if (cacheStats.size > 100) {
|
|
256
|
-
console.
|
|
256
|
+
console.error('[Cleanup] Clearing cache - size exceeded 100 items');
|
|
257
257
|
globalCache.clear();
|
|
258
258
|
}
|
|
259
259
|
}
|
package/dist/tool-definitions.js
CHANGED
|
@@ -468,17 +468,6 @@ export const TOOLS = [
|
|
|
468
468
|
},
|
|
469
469
|
},
|
|
470
470
|
},
|
|
471
|
-
{
|
|
472
|
-
name: 'pdf_link_finder',
|
|
473
|
-
description: 'Downloadable files (PDF, DOC, etc.) detect करता है',
|
|
474
|
-
inputSchema: {
|
|
475
|
-
type: 'object',
|
|
476
|
-
properties: {
|
|
477
|
-
selector: { type: 'string', default: 'a[href]' },
|
|
478
|
-
includeOtherFiles: { type: 'boolean', default: true },
|
|
479
|
-
},
|
|
480
|
-
},
|
|
481
|
-
},
|
|
482
471
|
// Pagination Tools
|
|
483
472
|
{
|
|
484
473
|
name: 'auto_pagination',
|
|
@@ -570,31 +559,6 @@ export const TOOLS = [
|
|
|
570
559
|
required: ['html'],
|
|
571
560
|
},
|
|
572
561
|
},
|
|
573
|
-
{
|
|
574
|
-
name: 'price_parser',
|
|
575
|
-
description: 'Currency symbols से actual numbers extract करता है',
|
|
576
|
-
inputSchema: {
|
|
577
|
-
type: 'object',
|
|
578
|
-
properties: {
|
|
579
|
-
text: { type: 'string' },
|
|
580
|
-
currency: { type: 'string' },
|
|
581
|
-
},
|
|
582
|
-
required: ['text'],
|
|
583
|
-
},
|
|
584
|
-
},
|
|
585
|
-
{
|
|
586
|
-
name: 'date_normalizer',
|
|
587
|
-
description: 'Different date formats को standard format में convert करता है',
|
|
588
|
-
inputSchema: {
|
|
589
|
-
type: 'object',
|
|
590
|
-
properties: {
|
|
591
|
-
text: { type: 'string' },
|
|
592
|
-
outputFormat: { type: 'string', enum: ['iso', 'locale', 'unix'], default: 'iso' },
|
|
593
|
-
timezone: { type: 'string' },
|
|
594
|
-
},
|
|
595
|
-
required: ['text'],
|
|
596
|
-
},
|
|
597
|
-
},
|
|
598
562
|
{
|
|
599
563
|
name: 'contact_extractor',
|
|
600
564
|
description: 'Phone numbers और email addresses automatically detect करता है',
|
|
@@ -917,22 +881,6 @@ export const TOOLS = [
|
|
|
917
881
|
required: ['selector', 'outputPath'],
|
|
918
882
|
},
|
|
919
883
|
},
|
|
920
|
-
{
|
|
921
|
-
name: 'pdf_generation',
|
|
922
|
-
description: 'Convert page to PDF',
|
|
923
|
-
inputSchema: {
|
|
924
|
-
type: 'object',
|
|
925
|
-
properties: {
|
|
926
|
-
url: { type: 'string' },
|
|
927
|
-
outputPath: { type: 'string' },
|
|
928
|
-
format: { type: 'string', default: 'A4' },
|
|
929
|
-
landscape: { type: 'boolean', default: false },
|
|
930
|
-
printBackground: { type: 'boolean', default: true },
|
|
931
|
-
margin: { type: 'object' },
|
|
932
|
-
},
|
|
933
|
-
required: ['outputPath'],
|
|
934
|
-
},
|
|
935
|
-
},
|
|
936
884
|
{
|
|
937
885
|
name: 'video_recording',
|
|
938
886
|
description: 'Record browser session',
|
|
@@ -1235,31 +1183,6 @@ export const TOOLS = [
|
|
|
1235
1183
|
},
|
|
1236
1184
|
},
|
|
1237
1185
|
},
|
|
1238
|
-
{
|
|
1239
|
-
name: 'error_logger',
|
|
1240
|
-
description: 'Log and track errors',
|
|
1241
|
-
inputSchema: {
|
|
1242
|
-
type: 'object',
|
|
1243
|
-
properties: {
|
|
1244
|
-
action: { type: 'string', enum: ['log', 'get', 'clear'], default: 'log' },
|
|
1245
|
-
message: { type: 'string' },
|
|
1246
|
-
type: { type: 'string' },
|
|
1247
|
-
context: { type: 'object' },
|
|
1248
|
-
stackTrace: { type: 'string' },
|
|
1249
|
-
limit: { type: 'number', default: 10 },
|
|
1250
|
-
},
|
|
1251
|
-
},
|
|
1252
|
-
},
|
|
1253
|
-
{
|
|
1254
|
-
name: 'success_rate_reporter',
|
|
1255
|
-
description: 'Report success metrics',
|
|
1256
|
-
inputSchema: {
|
|
1257
|
-
type: 'object',
|
|
1258
|
-
properties: {
|
|
1259
|
-
timeRange: { type: 'string', enum: ['all', 'last_hour', 'last_day'], default: 'all' },
|
|
1260
|
-
},
|
|
1261
|
-
},
|
|
1262
|
-
},
|
|
1263
1186
|
{
|
|
1264
1187
|
name: 'data_quality_metrics',
|
|
1265
1188
|
description: 'Report data quality metrics',
|
|
@@ -1270,22 +1193,6 @@ export const TOOLS = [
|
|
|
1270
1193
|
},
|
|
1271
1194
|
},
|
|
1272
1195
|
},
|
|
1273
|
-
{
|
|
1274
|
-
name: 'performance_monitor',
|
|
1275
|
-
description: 'Monitor browser and page performance',
|
|
1276
|
-
inputSchema: {
|
|
1277
|
-
type: 'object',
|
|
1278
|
-
properties: {},
|
|
1279
|
-
},
|
|
1280
|
-
},
|
|
1281
|
-
{
|
|
1282
|
-
name: 'monitoring_summary',
|
|
1283
|
-
description: 'Get overall monitoring summary',
|
|
1284
|
-
inputSchema: {
|
|
1285
|
-
type: 'object',
|
|
1286
|
-
properties: {},
|
|
1287
|
-
},
|
|
1288
|
-
},
|
|
1289
1196
|
// Advanced Video & Media Download Tools
|
|
1290
1197
|
{
|
|
1291
1198
|
name: 'video_link_finder',
|
|
@@ -1487,7 +1394,6 @@ export const TOOL_NAMES = {
|
|
|
1487
1394
|
IMAGE_SCRAPER: 'image_scraper',
|
|
1488
1395
|
LINK_HARVESTER: 'link_harvester',
|
|
1489
1396
|
MEDIA_EXTRACTOR: 'media_extractor',
|
|
1490
|
-
PDF_LINK_FINDER: 'pdf_link_finder',
|
|
1491
1397
|
// Pagination Tools
|
|
1492
1398
|
AUTO_PAGINATION: 'auto_pagination',
|
|
1493
1399
|
INFINITE_SCROLL: 'infinite_scroll',
|
|
@@ -1497,8 +1403,6 @@ export const TOOL_NAMES = {
|
|
|
1497
1403
|
// Data Processing
|
|
1498
1404
|
SMART_TEXT_CLEANER: 'smart_text_cleaner',
|
|
1499
1405
|
HTML_TO_TEXT: 'html_to_text',
|
|
1500
|
-
PRICE_PARSER: 'price_parser',
|
|
1501
|
-
DATE_NORMALIZER: 'date_normalizer',
|
|
1502
1406
|
CONTACT_EXTRACTOR: 'contact_extractor',
|
|
1503
1407
|
// Data Validation
|
|
1504
1408
|
SCHEMA_VALIDATOR: 'schema_validator',
|
|
@@ -1529,7 +1433,6 @@ export const TOOL_NAMES = {
|
|
|
1529
1433
|
// Screenshot & Visual Tools
|
|
1530
1434
|
FULL_PAGE_SCREENSHOT: 'full_page_screenshot',
|
|
1531
1435
|
ELEMENT_SCREENSHOT: 'element_screenshot',
|
|
1532
|
-
PDF_GENERATION: 'pdf_generation',
|
|
1533
1436
|
VIDEO_RECORDING: 'video_recording',
|
|
1534
1437
|
VISUAL_COMPARISON: 'visual_comparison',
|
|
1535
1438
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-browser-mcp-server",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.8",
|
|
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",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"ajv": "^8.12.0",
|
|
40
40
|
"axios": "^1.6.5",
|
|
41
41
|
"brave-real-browser": "^1.5.105",
|
|
42
|
-
"brave-real-launcher": "^1.2.
|
|
42
|
+
"brave-real-launcher": "^1.2.29",
|
|
43
43
|
"brave-real-puppeteer-core": "^24.33.0-patch.1",
|
|
44
44
|
"cheerio": "^1.0.0-rc.12",
|
|
45
45
|
"chrono-node": "^2.7.0",
|