crawlforge-mcp-server 5.2.8 → 5.2.9
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/CLAUDE.md +1 -1
- package/package.json +1 -1
- package/server.js +1 -1
- package/src/core/llm/LLMManager.js +44 -13
package/CLAUDE.md
CHANGED
|
@@ -62,7 +62,7 @@ These guidelines are working if: fewer unnecessary changes in diffs, fewer rewri
|
|
|
62
62
|
|
|
63
63
|
CrawlForge MCP Server - A professional MCP (Model Context Protocol) server providing 28 web scraping, crawling, and content processing tools (5 inline + 23 advanced).
|
|
64
64
|
|
|
65
|
-
**Current Version:** 5.2.
|
|
65
|
+
**Current Version:** 5.2.9
|
|
66
66
|
|
|
67
67
|
## Development Commands
|
|
68
68
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crawlforge-mcp-server",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.9",
|
|
4
4
|
"mcpName": "io.github.mysleekdesigns/crawlforge-mcp-server",
|
|
5
5
|
"description": "CrawlForge MCP Server - Professional Model Context Protocol server with 28 web scraping, crawling, deep-research, and autonomous-extraction tools. Returns clean Markdown and structured JSON for Claude, Cursor, and any MCP client. Defaults to local Ollama for LLM extraction (no API key needed); OpenAI/Anthropic available as opt-in. Includes a unified multi-format scrape tool, an autonomous agent, pre-built site templates, and Camoufox stealth browsing.",
|
|
6
6
|
"main": "server.js",
|
package/server.js
CHANGED
|
@@ -100,7 +100,7 @@ const taskStore = createTaskStore({ logger });
|
|
|
100
100
|
// Create the server
|
|
101
101
|
const server = new McpServer({
|
|
102
102
|
name: "crawlforge",
|
|
103
|
-
version: "5.2.
|
|
103
|
+
version: "5.2.9",
|
|
104
104
|
description: "Production-ready MCP server with 28 web scraping, crawling, and content processing tools. Features MCP Resources (crawlforge://), Prompts, Sampling fallback, Elicitation, stealth browsing, deep research, structured extraction, real Google SERP rank tracking, Reddit search via community archives, change tracking, local-LLM extraction via Ollama, unified multi-format scrape, and autonomous agent tool.",
|
|
105
105
|
homepage: "https://www.crawlforge.dev",
|
|
106
106
|
icon: "https://www.crawlforge.dev/icon.png",
|
|
@@ -259,7 +259,9 @@ Return a JSON object with:
|
|
|
259
259
|
"keyPoints": ["point1", "point2", ...],
|
|
260
260
|
"topicAlignment": "description of alignment",
|
|
261
261
|
"credibilityIndicators": ["indicator1", "indicator2", ...]
|
|
262
|
-
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
Be brief: at most 5 items per array, one short sentence each.`;
|
|
263
265
|
|
|
264
266
|
const prompt = `Research Topic: "${topic}"
|
|
265
267
|
|
|
@@ -269,19 +271,48 @@ ${truncatedContent}
|
|
|
269
271
|
Analyze the relevance of this content to the research topic:`;
|
|
270
272
|
|
|
271
273
|
try {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
274
|
+
// Same discipline as synthesizeFindings: constrain the output shape
|
|
275
|
+
// (small local models otherwise wrap the JSON in markdown fences —
|
|
276
|
+
// the raw JSON.parse here failed on every Ollama run), strip fences,
|
|
277
|
+
// validate the load-bearing field, and retry a truncated response
|
|
278
|
+
// once before falling back.
|
|
279
|
+
const relevanceSchema = {
|
|
280
|
+
type: 'object',
|
|
281
|
+
properties: {
|
|
282
|
+
relevanceScore: { type: 'number' },
|
|
283
|
+
keyPoints: { type: 'array', items: { type: 'string' } },
|
|
284
|
+
topicAlignment: { type: 'string' },
|
|
285
|
+
credibilityIndicators: { type: 'array', items: { type: 'string' } }
|
|
286
|
+
},
|
|
287
|
+
required: ['relevanceScore']
|
|
284
288
|
};
|
|
289
|
+
|
|
290
|
+
let lastError;
|
|
291
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
292
|
+
try {
|
|
293
|
+
const response = await this.generateCompletion(prompt, {
|
|
294
|
+
systemPrompt,
|
|
295
|
+
maxTokens: 800,
|
|
296
|
+
temperature: 0.3,
|
|
297
|
+
format: relevanceSchema
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
const cleaned = response.replace(/^```(?:json)?\n?/, '').replace(/\n?```$/, '').trim();
|
|
301
|
+
const analysis = JSON.parse(cleaned);
|
|
302
|
+
if (!analysis || typeof analysis.relevanceScore !== 'number') {
|
|
303
|
+
throw new Error('Relevance response missing relevanceScore');
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
relevanceScore: Math.max(0, Math.min(1, analysis.relevanceScore)),
|
|
307
|
+
keyPoints: analysis.keyPoints || [],
|
|
308
|
+
topicAlignment: analysis.topicAlignment || '',
|
|
309
|
+
credibilityIndicators: analysis.credibilityIndicators || []
|
|
310
|
+
};
|
|
311
|
+
} catch (error) {
|
|
312
|
+
lastError = error;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
throw lastError;
|
|
285
316
|
} catch (error) {
|
|
286
317
|
this.logger.warn('LLM relevance analysis failed, using fallback', { error: error.message });
|
|
287
318
|
return this.fallbackRelevanceAnalysis(content, topic);
|