crawlforge-mcp-server 6.11.0 → 6.12.0

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 CHANGED
@@ -236,6 +236,11 @@ CRAWLFORGE_STEALTH_PROXIES= # comma-separated proxy URLs used by the es
236
236
  # from the PROXY_ROTATION_* family, which belongs to
237
237
  # localization. The agent's automatic stealth retry
238
238
  # (stealth review Phase 3) reads it too.
239
+ CRAWLFORGE_IMPIT= # `off` skips escalation's impit step (a Chrome TLS handshake with
240
+ # the honest UA, tried before the browser; stealth review Phase 7).
241
+ # Exit-IP dependent like the engine: it cleared indeed.com from a
242
+ # residential IP and nothing from the hosted datacenter IP, so
243
+ # render.yaml sets it off there. Measure with scripts/impit-probe.mjs.
239
244
  CRAWLFORGE_CLEARANCE_JAR= # `off` disables the clearance jar (stealth review Phase 4):
240
245
  # cf_clearance/__cf_bm/datadome cookies a stealth render earned
241
246
  # are replayed to the next stealth context with the same engine,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crawlforge-mcp-server",
3
- "version": "6.11.0",
3
+ "version": "6.12.0",
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",
@@ -121,7 +121,7 @@
121
121
  "cheerio": "^1.1.2",
122
122
  "commander": "^14.0.3",
123
123
  "compromise": "^14.14.4",
124
- "crawlforge-extractors": "^1.9.0",
124
+ "crawlforge-extractors": "^1.10.0",
125
125
  "diff": "^9.0.0",
126
126
  "dotenv": "^17.2.1",
127
127
  "franc": "^6.2.0",
package/server.js CHANGED
@@ -61,7 +61,7 @@ import { REDACT_PII_PARAM } from "./src/server/redaction.js"; // Phase 5 (5.3)
61
61
  import { SEARCH_QUERIES_PARAM, EXACTLY_ONE_QUERY_MESSAGE } from "./src/tools/search/batchSearch.js"; // Phase 5 (5.1)
62
62
  import { markPreflightRefusal, internalOwnerToken } from "./src/server/requestContext.js";
63
63
  import { recordStealthEscalation } from "./src/utils/complianceAudit.js";
64
- import { loadImpit, impitFetchPage, IMPIT_ENGINE } from "./src/utils/impitRung.js"; // stealth review Phase 7
64
+ import { loadImpit, impitEnabled, impitFetchPage, IMPIT_ENGINE } from "./src/utils/impitRung.js"; // stealth review Phase 7
65
65
  // D1.1 Resources + D1.2 Prompts + D1.4 Elicitation
66
66
  import { ResourceRegistry, MAX_RESOURCE_BLOB_BYTES } from "./src/resources/ResourceRegistry.js";
67
67
  import { PROMPTS, getPromptMessages } from "./src/prompts/PromptRegistry.js";
@@ -110,7 +110,7 @@ if (configErrors.length > 0 && config.server.nodeEnv === 'production') {
110
110
  // Create the server
111
111
  const server = new McpServer({
112
112
  name: "crawlforge",
113
- version: "6.11.0",
113
+ version: "6.12.0",
114
114
  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.",
115
115
  homepage: "https://www.crawlforge.dev",
116
116
  icon: "https://www.crawlforge.dev/icon.png",
@@ -259,7 +259,8 @@ const stealthEscalation = async ({ url, engine, respectRobots, tool }) => {
259
259
  // Stealth review Phase 7: under "auto", a Chrome TLS handshake with the
260
260
  // honest User-Agent is tried before any browser launches. A caller who
261
261
  // named an engine asked for that browser, so it is not tried for them.
262
- if (engine === 'auto' && await loadImpit()) {
262
+ // CRAWLFORGE_IMPIT=off skips it for a deployment whose exit IP it cannot help.
263
+ if (engine === 'auto' && impitEnabled() && await loadImpit()) {
263
264
  recordStealthEscalation({ url, tool, engine: IMPIT_ENGINE, ...auditIdentity });
264
265
  const page = await impitFetchPage(url);
265
266
  if (page) return { ...page, warnings };
@@ -48,6 +48,19 @@ const MIN_UNRENDERED_TEXT_CHARS = 200;
48
48
 
49
49
  let impitClass; // undefined: not tried yet; null: unavailable
50
50
 
51
+ /**
52
+ * Whether this deployment runs the step. `CRAWLFORGE_IMPIT=off` turns it off.
53
+ * Like the stealth engine, what it can clear depends on the exit IP: from a
54
+ * residential IP it cleared indeed.com, and from the hosted instance's
55
+ * datacenter IP (AS14618, Ashburn) it cleared nothing in 3 runs (2026-09-27),
56
+ * so render.yaml sets it off there. Read on every call, like the stealth
57
+ * proxy list, so an operator can change it without a restart.
58
+ * @returns {boolean}
59
+ */
60
+ export function impitEnabled() {
61
+ return String(process.env.CRAWLFORGE_IMPIT || '').trim().toLowerCase() !== 'off';
62
+ }
63
+
51
64
  /**
52
65
  * The Impit class, or null when the optional dependency is absent or its
53
66
  * native bindings do not load on this platform. Tried once per process.