crawlforge-mcp-server 6.19.0 → 6.19.2
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": "6.19.
|
|
3
|
+
"version": "6.19.2",
|
|
4
4
|
"mcpName": "io.github.mysleekdesigns/crawlforge-mcp-server",
|
|
5
5
|
"description": "CrawlForge MCP Server - Professional Model Context Protocol server with 31 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
|
@@ -113,7 +113,7 @@ if (configErrors.length > 0 && config.server.nodeEnv === 'production') {
|
|
|
113
113
|
// Create the server
|
|
114
114
|
const server = new McpServer({
|
|
115
115
|
name: "crawlforge",
|
|
116
|
-
version: "6.19.
|
|
116
|
+
version: "6.19.2",
|
|
117
117
|
description: "Production-ready MCP server with 31 web scraping, crawling, and content processing tools. Features MCP Resources (crawlforge://), Prompts, Sampling fallback, Elicitation, stealth browsing, stateful browser sessions with element refs, deep research, structured extraction, embedded JavaScript state 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.",
|
|
118
118
|
homepage: "https://www.crawlforge.dev",
|
|
119
119
|
icon: "https://www.crawlforge.dev/icon.png",
|
|
@@ -597,7 +597,7 @@ registerToolIfEnabled("serp_rank", {
|
|
|
597
597
|
location_code: z.number().optional().describe("Numeric DataForSEO location code (overrides location_name)"),
|
|
598
598
|
language_code: z.string().optional().describe("Language code (e.g. 'en')"),
|
|
599
599
|
device: z.enum(["desktop", "mobile"]).optional().describe("Device to emulate"),
|
|
600
|
-
depth: z.number().min(10).max(200).optional().describe("How many results to scan, 10-200 (default
|
|
600
|
+
depth: z.number().min(10).max(200).optional().describe("How many results to scan, 10-200 (default 30; DataForSEO bills ~$0.002 per 10 and gets slower the deeper it goes)")
|
|
601
601
|
},
|
|
602
602
|
outputSchema: OUTPUT_SCHEMAS.serp_rank
|
|
603
603
|
}, withAuth("serp_rank", async ({ keyword, target, location_name, location_code, language_code, device, depth }) => {
|
|
@@ -399,11 +399,15 @@ export class LocalizationManager extends EventEmitter {
|
|
|
399
399
|
// Configure geolocation
|
|
400
400
|
geolocation: config.geoLocation || this.getCountryCoordinates(targetCountry) || undefined,
|
|
401
401
|
|
|
402
|
-
// Set HTTP headers
|
|
402
|
+
// Set HTTP headers. A context's extraHTTPHeaders go on every request, so
|
|
403
|
+
// each must be one CORS ignores (a forbidden name: Accept-Encoding, DNT)
|
|
404
|
+
// or safelisted (Accept-Language). Cache-Control is neither: it turned
|
|
405
|
+
// every cross-origin CORS fetch into a preflighted one, which a server
|
|
406
|
+
// answering no OPTIONS refuses — the stealth headers broke Cloudflare's
|
|
407
|
+
// Turnstile the same way (R24).
|
|
403
408
|
extraHTTPHeaders: {
|
|
404
409
|
'Accept-Language': config.acceptLanguage,
|
|
405
410
|
'Accept-Encoding': 'gzip, deflate, br',
|
|
406
|
-
'Cache-Control': 'no-cache',
|
|
407
411
|
'DNT': '1',
|
|
408
412
|
...config.customHeaders,
|
|
409
413
|
...browserOptions.extraHTTPHeaders
|
|
@@ -963,7 +967,6 @@ export class LocalizationManager extends EventEmitter {
|
|
|
963
967
|
return {
|
|
964
968
|
"Accept-Language": this.generateAcceptLanguageHeader(config.language),
|
|
965
969
|
"Accept-Encoding": "gzip, deflate, br",
|
|
966
|
-
"Cache-Control": "no-cache",
|
|
967
970
|
"DNT": "1"
|
|
968
971
|
};
|
|
969
972
|
}
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* POST https://api.dataforseo.com/v3/serp/google/organic/live/advanced
|
|
13
13
|
*
|
|
14
14
|
* Cost: US$0.002 per 10 results of `depth` on Live Advanced — measured live,
|
|
15
|
-
* not estimated: depth 10 bills $0.002,
|
|
16
|
-
* depth
|
|
15
|
+
* not estimated: depth 10 bills $0.002, depth 20 bills $0.004, and depth 100
|
|
16
|
+
* bills $0.02, so the depth 30 default is $0.006. Deeper scans are also slower (see the timeout note
|
|
17
17
|
* below), so raise `depth` only when a rank below the default is worth paying
|
|
18
18
|
* for. For high-volume scheduled tracking, DataForSEO's task-based "Standard"
|
|
19
19
|
* queue (task_post → tasks_ready → task_get) is cheaper; swap the endpoint +
|
|
@@ -51,7 +51,7 @@ export class DataForSEOSearchAdapter {
|
|
|
51
51
|
* @param {number} [params.locationCode] - Numeric DataForSEO location code (overrides locationName)
|
|
52
52
|
* @param {string} [params.languageCode='en'] - Language code
|
|
53
53
|
* @param {('desktop'|'mobile')} [params.device='desktop'] - Device to emulate
|
|
54
|
-
* @param {number} [params.depth=
|
|
54
|
+
* @param {number} [params.depth=30] - How many results to scan (billed per 10)
|
|
55
55
|
* @returns {Promise<{items: Array<Object>, meta: Object}>} Normalized organic results + metadata
|
|
56
56
|
*/
|
|
57
57
|
async search(params) {
|
|
@@ -61,7 +61,7 @@ export class DataForSEOSearchAdapter {
|
|
|
61
61
|
locationCode,
|
|
62
62
|
languageCode = 'en',
|
|
63
63
|
device = 'desktop',
|
|
64
|
-
depth =
|
|
64
|
+
depth = 30,
|
|
65
65
|
} = params;
|
|
66
66
|
|
|
67
67
|
if (!keyword) {
|
|
@@ -27,7 +27,7 @@ const SerpRankSchema = z.object({
|
|
|
27
27
|
// DataForSEO bills per 10 results scanned and gets slower the deeper it goes,
|
|
28
28
|
// so the default stays shallow: 20 covers Google's first two pages for $0.004.
|
|
29
29
|
// Raise it (max 200, their cap) when a deeper position is worth the spend.
|
|
30
|
-
depth: z.number().int().min(10).max(200).optional().default(
|
|
30
|
+
depth: z.number().int().min(10).max(200).optional().default(30),
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
/** Reduce a domain or URL to a bare, comparable host: "https://www.Example.com/x" → "example.com".
|