crawlforge-mcp-server 3.0.4 → 3.0.5
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crawlforge-mcp-server",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"description": "CrawlForge MCP Server - Professional Model Context Protocol server with 19 comprehensive web scraping, crawling, and content processing tools.",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"bin": {
|
|
@@ -166,10 +166,20 @@ export class SnapshotManager extends EventEmitter {
|
|
|
166
166
|
*/
|
|
167
167
|
async storeSnapshot(url, content, metadata = {}, options = {}) {
|
|
168
168
|
const operationId = this.generateOperationId();
|
|
169
|
-
|
|
169
|
+
|
|
170
170
|
try {
|
|
171
|
+
// Validate content is not null/undefined
|
|
172
|
+
if (content === null || content === undefined) {
|
|
173
|
+
throw new Error('Content cannot be null or undefined');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Ensure content is a string
|
|
177
|
+
if (typeof content !== 'string') {
|
|
178
|
+
content = String(content);
|
|
179
|
+
}
|
|
180
|
+
|
|
171
181
|
this.activeOperations.set(operationId, { type: 'store', url, startTime: Date.now() });
|
|
172
|
-
|
|
182
|
+
|
|
173
183
|
const snapshotId = this.generateSnapshotId(url, metadata.timestamp || Date.now());
|
|
174
184
|
const contentHash = this.hashContent(content);
|
|
175
185
|
|
|
@@ -333,8 +333,8 @@ export class BrowserProcessor {
|
|
|
333
333
|
const { context, contextId } = await this.stealthManager.createStealthContext({
|
|
334
334
|
level: options.stealthMode.level,
|
|
335
335
|
customViewport: {
|
|
336
|
-
width: options.viewportWidth,
|
|
337
|
-
height: options.viewportHeight
|
|
336
|
+
width: options.viewportWidth || 1280,
|
|
337
|
+
height: options.viewportHeight || 720
|
|
338
338
|
}
|
|
339
339
|
});
|
|
340
340
|
|
|
@@ -475,8 +475,8 @@ export class BrowserProcessor {
|
|
|
475
475
|
async createPage(options) {
|
|
476
476
|
const contextOptions = {
|
|
477
477
|
viewport: {
|
|
478
|
-
width: options.viewportWidth,
|
|
479
|
-
height: options.viewportHeight
|
|
478
|
+
width: options.viewportWidth || 1280,
|
|
479
|
+
height: options.viewportHeight || 720
|
|
480
480
|
},
|
|
481
481
|
userAgent: options.userAgent,
|
|
482
482
|
extraHTTPHeaders: options.extraHeaders,
|
|
@@ -147,7 +147,12 @@ export class ScrapeWithActionsTool extends EventEmitter {
|
|
|
147
147
|
enableLogging = true,
|
|
148
148
|
enableCaching = false,
|
|
149
149
|
maxConcurrentSessions = 3,
|
|
150
|
-
defaultBrowserOptions = {
|
|
150
|
+
defaultBrowserOptions = {
|
|
151
|
+
viewportWidth: 1280,
|
|
152
|
+
viewportHeight: 720,
|
|
153
|
+
headless: true,
|
|
154
|
+
timeout: 30000
|
|
155
|
+
},
|
|
151
156
|
screenshotPath = './screenshots'
|
|
152
157
|
} = options;
|
|
153
158
|
|
|
@@ -317,7 +322,10 @@ export class ScrapeWithActionsTool extends EventEmitter {
|
|
|
317
322
|
sessionId: sessionContext.id,
|
|
318
323
|
url: params.url,
|
|
319
324
|
executionTime,
|
|
320
|
-
|
|
325
|
+
|
|
326
|
+
// Include error message if action chain failed
|
|
327
|
+
error: chainResult.error || undefined,
|
|
328
|
+
|
|
321
329
|
actionResults,
|
|
322
330
|
totalActions: params.actions.length,
|
|
323
331
|
successfulActions: actionResults.filter(r => r.success).length,
|
|
@@ -285,29 +285,40 @@ export class TrackChangesTool extends EventEmitter {
|
|
|
285
285
|
* @returns {Object} - Baseline creation results
|
|
286
286
|
*/
|
|
287
287
|
async createBaseline(params) {
|
|
288
|
-
const { url, content, html, trackingOptions, storageOptions } = params;
|
|
289
|
-
|
|
288
|
+
const { url, content, html, trackingOptions, storageOptions = {} } = params;
|
|
289
|
+
|
|
290
|
+
// Apply defaults for storageOptions fields
|
|
291
|
+
const enableSnapshots = storageOptions.enableSnapshots !== false; // Default to true
|
|
292
|
+
|
|
290
293
|
try {
|
|
291
294
|
// Fetch content if not provided
|
|
292
295
|
let sourceContent = content || html;
|
|
293
296
|
let fetchMetadata = {};
|
|
294
|
-
|
|
297
|
+
|
|
295
298
|
if (!sourceContent) {
|
|
296
299
|
const fetchResult = await this.fetchContent(url);
|
|
300
|
+
if (!fetchResult || !fetchResult.content) {
|
|
301
|
+
throw new Error('Failed to fetch content from URL');
|
|
302
|
+
}
|
|
297
303
|
sourceContent = fetchResult.content;
|
|
298
|
-
fetchMetadata = fetchResult.metadata;
|
|
304
|
+
fetchMetadata = fetchResult.metadata || {};
|
|
299
305
|
}
|
|
300
|
-
|
|
306
|
+
|
|
307
|
+
// Validate sourceContent
|
|
308
|
+
if (!sourceContent || typeof sourceContent !== 'string') {
|
|
309
|
+
throw new Error('Invalid content: content must be a non-empty string');
|
|
310
|
+
}
|
|
311
|
+
|
|
301
312
|
// Create baseline with change tracker
|
|
302
313
|
const baseline = await this.changeTracker.createBaseline(
|
|
303
314
|
url,
|
|
304
315
|
sourceContent,
|
|
305
316
|
trackingOptions
|
|
306
317
|
);
|
|
307
|
-
|
|
308
|
-
// Store snapshot if enabled
|
|
318
|
+
|
|
319
|
+
// Store snapshot if enabled (defaults to true)
|
|
309
320
|
let snapshotInfo = null;
|
|
310
|
-
if (
|
|
321
|
+
if (enableSnapshots) {
|
|
311
322
|
const snapshotResult = await this.snapshotManager.storeSnapshot(
|
|
312
323
|
url,
|
|
313
324
|
sourceContent,
|
|
@@ -347,29 +358,40 @@ export class TrackChangesTool extends EventEmitter {
|
|
|
347
358
|
* @returns {Object} - Comparison results
|
|
348
359
|
*/
|
|
349
360
|
async compareWithBaseline(params) {
|
|
350
|
-
const { url, content, html, trackingOptions, storageOptions, notificationOptions } = params;
|
|
351
|
-
|
|
361
|
+
const { url, content, html, trackingOptions, storageOptions = {}, notificationOptions } = params;
|
|
362
|
+
|
|
363
|
+
// Apply defaults for storageOptions fields
|
|
364
|
+
const enableSnapshots = storageOptions.enableSnapshots !== false; // Default to true
|
|
365
|
+
|
|
352
366
|
try {
|
|
353
367
|
// Fetch current content if not provided
|
|
354
368
|
let currentContent = content || html;
|
|
355
369
|
let fetchMetadata = {};
|
|
356
|
-
|
|
370
|
+
|
|
357
371
|
if (!currentContent) {
|
|
358
372
|
const fetchResult = await this.fetchContent(url);
|
|
373
|
+
if (!fetchResult || !fetchResult.content) {
|
|
374
|
+
throw new Error('Failed to fetch content from URL');
|
|
375
|
+
}
|
|
359
376
|
currentContent = fetchResult.content;
|
|
360
|
-
fetchMetadata = fetchResult.metadata;
|
|
377
|
+
fetchMetadata = fetchResult.metadata || {};
|
|
361
378
|
}
|
|
362
|
-
|
|
379
|
+
|
|
380
|
+
// Validate currentContent
|
|
381
|
+
if (!currentContent || typeof currentContent !== 'string') {
|
|
382
|
+
throw new Error('Invalid content: content must be a non-empty string');
|
|
383
|
+
}
|
|
384
|
+
|
|
363
385
|
// Perform comparison
|
|
364
386
|
const comparisonResult = await this.changeTracker.compareWithBaseline(
|
|
365
387
|
url,
|
|
366
388
|
currentContent,
|
|
367
389
|
trackingOptions
|
|
368
390
|
);
|
|
369
|
-
|
|
370
|
-
// Store snapshot if changes detected and storage enabled
|
|
391
|
+
|
|
392
|
+
// Store snapshot if changes detected and storage enabled (defaults to true)
|
|
371
393
|
let snapshotInfo = null;
|
|
372
|
-
if (comparisonResult.hasChanges &&
|
|
394
|
+
if (comparisonResult.hasChanges && enableSnapshots) {
|
|
373
395
|
const snapshotResult = await this.snapshotManager.storeSnapshot(
|
|
374
396
|
url,
|
|
375
397
|
currentContent,
|