crawlforge-mcp-server 6.20.1 → 6.21.1
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 +74 -296
- package/README.md +2 -2
- package/package.json +1 -2
- package/server.js +6 -4
- package/src/core/crawlers/BFSCrawler.js +1 -1
- package/src/schemas/toolOutputSchemas.js +1 -1
- package/src/skills/agent-skills/crawlforge-batch-automation/SKILL.md +1 -1
- package/src/skills/agent-skills/crawlforge-browser-sessions/SKILL.md +1 -1
- package/src/skills/agent-skills/crawlforge-change-tracking/SKILL.md +1 -1
- package/src/skills/agent-skills/crawlforge-deep-research/SKILL.md +1 -1
- package/src/skills/agent-skills/crawlforge-getting-started/SKILL.md +1 -1
- package/src/skills/agent-skills/crawlforge-stealth-browsing/SKILL.md +3 -3
- package/src/skills/agent-skills/crawlforge-stealth-browsing/references/engine-selection.md +2 -2
- package/src/skills/agent-skills/crawlforge-structured-extraction/SKILL.md +1 -1
- package/src/skills/agent-skills/crawlforge-web-scraping/SKILL.md +3 -3
- package/src/tools/crawl/mapSite.js +2 -1
- package/src/tools/scrape/unifiedScrape.js +4 -2
- package/src/tools/search/adapters/braveSearch.js +182 -0
- package/src/tools/search/adapters/crawlforgeSearch.js +5 -2
- package/src/tools/search/adapters/searchProviderFactory.js +20 -11
- package/src/tools/search/providers/searxng.js +5 -0
- package/src/tools/search/redditSearch.js +1 -1
- package/src/tools/search/searchWeb.js +27 -13
- package/src/tools/search/serpRank.js +54 -1
- package/src/utils/ErrorHandlingConfig.js +1 -1
- package/src/utils/urlNormalizer.js +2 -1
- package/src/utils/inputValidation.js +0 -766
- package/src/utils/securityMiddleware.js +0 -416
package/CLAUDE.md
CHANGED
|
@@ -1,214 +1,96 @@
|
|
|
1
1
|
# CLAUDE.md
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Guidance for Claude Code when working in this repository. File-specific detail lives in path-scoped rules under `.claude/rules/` (tool registration and billing, search tools, stealth engines, security guards); they load when matching files are read.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Working guidelines
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
These bias toward caution over speed; for trivial tasks, use judgment.
|
|
8
8
|
|
|
9
|
-
1. Think
|
|
10
|
-
|
|
9
|
+
1. **Think before coding.** Don't assume, and don't hide confusion.
|
|
10
|
+
- State your assumptions. If uncertain, ask.
|
|
11
|
+
- If several interpretations exist, present them rather than picking one silently.
|
|
12
|
+
- If a simpler approach exists, say so, and push back when warranted.
|
|
13
|
+
2. **Simplicity first.** Write the minimum code that solves the problem.
|
|
14
|
+
- No features, abstractions, configurability or error handling beyond what was asked or what can actually happen.
|
|
15
|
+
- If 200 lines could be 50, rewrite it.
|
|
16
|
+
3. **Surgical changes.** Touch only what you must.
|
|
17
|
+
- Don't "improve" adjacent code, comments or formatting, and don't refactor what isn't broken. Match the existing style.
|
|
18
|
+
- Remove imports, variables and functions your change made unused. Mention pre-existing dead code; don't delete it unless asked.
|
|
19
|
+
- Every changed line should trace to the request.
|
|
20
|
+
4. **Goal-driven execution.** Turn the task into a check you can run, and loop until it passes: "fix the bug" → a test that reproduces it, then make it pass; "refactor X" → tests pass before and after. For multi-step work, state a brief plan with a verification step for each item.
|
|
11
21
|
|
|
12
|
-
|
|
22
|
+
## Project overview
|
|
13
23
|
|
|
14
|
-
|
|
15
|
-
If multiple interpretations exist, present them - don't pick silently.
|
|
16
|
-
If a simpler approach exists, say so. Push back when warranted.
|
|
17
|
-
If something is unclear, stop. Name what's confusing. Ask.
|
|
24
|
+
CrawlForge MCP Server — an MCP server providing 31 web scraping, crawling and content-processing tools (6 inline in `server.js` + 25 advanced). Node ESM, MCP SDK v2 (`@modelcontextprotocol/server`), Zod. The version lives in `package.json`.
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
Minimum code that solves the problem. Nothing speculative.
|
|
21
|
-
|
|
22
|
-
No features beyond what was asked.
|
|
23
|
-
No abstractions for single-use code.
|
|
24
|
-
No "flexibility" or "configurability" that wasn't requested.
|
|
25
|
-
No error handling for impossible scenarios.
|
|
26
|
-
If you write 200 lines and it could be 50, rewrite it.
|
|
27
|
-
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
|
|
28
|
-
|
|
29
|
-
3. Surgical Changes
|
|
30
|
-
Touch only what you must. Clean up only your own mess.
|
|
31
|
-
|
|
32
|
-
When editing existing code:
|
|
33
|
-
|
|
34
|
-
Don't "improve" adjacent code, comments, or formatting.
|
|
35
|
-
Don't refactor things that aren't broken.
|
|
36
|
-
Match existing style, even if you'd do it differently.
|
|
37
|
-
If you notice unrelated dead code, mention it - don't delete it.
|
|
38
|
-
When your changes create orphans:
|
|
39
|
-
|
|
40
|
-
Remove imports/variables/functions that YOUR changes made unused.
|
|
41
|
-
Don't remove pre-existing dead code unless asked.
|
|
42
|
-
The test: Every changed line should trace directly to the user's request.
|
|
43
|
-
|
|
44
|
-
4. Goal-Driven Execution
|
|
45
|
-
Define success criteria. Loop until verified.
|
|
46
|
-
|
|
47
|
-
Transform tasks into verifiable goals:
|
|
48
|
-
|
|
49
|
-
"Add validation" → "Write tests for invalid inputs, then make them pass"
|
|
50
|
-
"Fix the bug" → "Write a test that reproduces it, then make it pass"
|
|
51
|
-
"Refactor X" → "Ensure tests pass before and after"
|
|
52
|
-
For multi-step tasks, state a brief plan:
|
|
53
|
-
|
|
54
|
-
1. [Step] → verify: [check]
|
|
55
|
-
2. [Step] → verify: [check]
|
|
56
|
-
3. [Step] → verify: [check]
|
|
57
|
-
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
|
|
58
|
-
|
|
59
|
-
These guidelines are working if: fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes.
|
|
60
|
-
|
|
61
|
-
## Project Overview
|
|
62
|
-
|
|
63
|
-
CrawlForge MCP Server - A professional MCP (Model Context Protocol) server providing 31 web scraping, crawling, and content processing tools (6 inline + 25 advanced).
|
|
64
|
-
|
|
65
|
-
**Current Version:** 5.6.6
|
|
66
|
-
|
|
67
|
-
## Development Commands
|
|
26
|
+
## Development commands
|
|
68
27
|
|
|
69
28
|
```bash
|
|
70
|
-
# Install dependencies
|
|
71
29
|
npm install
|
|
30
|
+
npm run setup # first run, users only; or export CRAWLFORGE_API_KEY=...
|
|
31
|
+
npm start # stdio server
|
|
32
|
+
npm run start:http # HTTP transport
|
|
33
|
+
npm run dev # verbose logging
|
|
72
34
|
|
|
73
|
-
|
|
74
|
-
npm
|
|
75
|
-
# Or provide API key via environment:
|
|
76
|
-
export CRAWLFORGE_API_KEY="your_api_key_here"
|
|
77
|
-
|
|
78
|
-
# Run the server (production)
|
|
79
|
-
npm start
|
|
80
|
-
|
|
81
|
-
# HTTP transport mode
|
|
82
|
-
npm run start:http
|
|
83
|
-
|
|
84
|
-
# Development mode with verbose logging
|
|
85
|
-
npm run dev
|
|
86
|
-
|
|
87
|
-
# Test MCP protocol compliance
|
|
88
|
-
npm test
|
|
89
|
-
|
|
90
|
-
# Unit tests (400+ tests across tests/unit/, no live network)
|
|
91
|
-
npm run test:unit
|
|
92
|
-
# Phase D regressions live in tests/unit/phaseD-regressions.test.js (agent hard stops, unified scrape, map_site ranking)
|
|
93
|
-
# Run a single test file: node --test tests/unit/phaseD-regressions.test.js
|
|
94
|
-
# Note: the script includes --test-force-exit — importing StealthBrowserManager
|
|
95
|
-
# (d2-reliability.test.js) leaves a Playwright handle that otherwise hangs the
|
|
96
|
-
# runner at exit after all tests pass. When running a single file manually, put
|
|
97
|
-
# --test-force-exit BEFORE the file path (after it, the flag is silently ignored).
|
|
98
|
-
|
|
99
|
-
# Integration tests
|
|
35
|
+
npm run test:unit # node:test over tests/unit/**, no live network
|
|
36
|
+
npm test # MCP protocol compliance
|
|
100
37
|
npm run test:integration
|
|
38
|
+
node test-tools.js # functional test of every tool
|
|
39
|
+
node test-real-world.js # real-world scenarios
|
|
101
40
|
|
|
102
|
-
#
|
|
103
|
-
node test-tools.js # Test all tools
|
|
104
|
-
node test-real-world.js # Test real-world usage scenarios
|
|
105
|
-
|
|
106
|
-
# MCP Protocol tests
|
|
107
|
-
node tests/integration/mcp-protocol-compliance.test.js
|
|
108
|
-
|
|
109
|
-
# CLI (v4.1.0+, requires global install or npx)
|
|
110
|
-
crawlforge --help # Show all subcommands
|
|
111
|
-
crawlforge init # API-key detection + skill install + idempotent MCP-stanza merge (v4.6.0)
|
|
112
|
-
crawlforge init --all --yes # Merge MCP config into Claude Code / Desktop / Cursor non-interactively
|
|
113
|
-
crawlforge scrape https://example.com
|
|
114
|
-
crawlforge batch --urls urls.txt --format markdown
|
|
115
|
-
crawlforge install-skills --target claude-code
|
|
116
|
-
# See docs/cli-guide.md for full reference
|
|
117
|
-
|
|
118
|
-
# Docker
|
|
119
|
-
npm run docker:build # Build Docker image
|
|
120
|
-
npm run docker:dev # Run development container
|
|
121
|
-
npm run docker:prod # Run production container
|
|
41
|
+
npm run docker:build # also docker:dev, docker:prod
|
|
122
42
|
```
|
|
123
43
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
-
|
|
127
|
-
- Set `NODE_ENV=development` for verbose logging
|
|
128
|
-
- Use `--expose-gc` flag for memory profiling: `node --expose-gc server.js`
|
|
129
|
-
- Check `cache/` directory for cached responses
|
|
130
|
-
- Review `logs/` directory for application logs
|
|
131
|
-
- Memory monitoring auto-enabled in development mode (logs every 60s if >200MB)
|
|
132
|
-
|
|
133
|
-
## High-Level Architecture
|
|
134
|
-
|
|
135
|
-
### Core Infrastructure (`src/core/`)
|
|
136
|
-
|
|
137
|
-
- **AuthManager**: Authentication, credit tracking, and usage reporting
|
|
138
|
-
- **PerformanceManager**: Centralized performance monitoring and optimization
|
|
139
|
-
- **JobManager**: Asynchronous job tracking and management for batch operations
|
|
140
|
-
- **WebhookDispatcher**: Event notification system for job completion callbacks
|
|
141
|
-
- **ActionExecutor**: Browser automation engine (Playwright-based)
|
|
142
|
-
- **ResearchOrchestrator**: Multi-stage research with query expansion and synthesis
|
|
143
|
-
- **AgentOrchestrator**: Powers the `agent` tool — NL prompt → autonomous PLAN→GATHER→ACT→DECIDE→SHAPE loop with three orchestrator-enforced hard stops (maxSteps≤10, maxUrls≤20, wall-clock) never delegated to the LLM; degraded no-LLM-key path (D2, v4.6.0)
|
|
144
|
-
- **StealthBrowserManager**: Stealth mode scraping with anti-detection; Camoufox (Firefox) engine added in v4.0.0. Engine selection goes through the one resolver `resolveStealthEngine(requested)` → `{engine, fallbackWarning}`; `'auto'` (the default for `scrape.escalate_engine` and `stealth_mode.engine` since the 2026-09 stealth review Phase 2) prefers Camoufox and falls back to Chromium with a caller-visible warning when its binary is absent. `'playwright'` is the tool layer's public name for Chromium. Camoufox personas are pinned to the installed binary's Firefox major so the UA's `rv:` and `Firefox/` tokens agree — see `docs/STEALTH_REVIEW_2026-09.md`
|
|
145
|
-
- **LocalizationManager**: Multi-language content and localization
|
|
146
|
-
- **ChangeTracker**: Content change tracking over time
|
|
147
|
-
- **SnapshotManager**: Website snapshots and version history
|
|
148
|
-
- **ResourceRegistry**: MCP Resources (crawlforge:// URI scheme, 5 resource types) — D1.1, v3.6.0
|
|
149
|
-
- **PromptRegistry** (`src/prompts/`): 5 workflow prompts — D1.2, v3.6.0
|
|
150
|
-
- **SamplingClient**: MCP Sampling with Ollama-API fallback chain — D1.3, v3.6.0
|
|
151
|
-
- **ElicitationHelper**: MCP Elicitation for user confirmation on expensive operations — D1.4, v3.6.0
|
|
152
|
-
- **endpointGuard**: Allow-list guard for server's own backend calls — v3.0.18
|
|
153
|
-
|
|
154
|
-
### Tool Layer (`src/tools/`)
|
|
155
|
-
|
|
156
|
-
Tools are organized in subdirectories by category:
|
|
44
|
+
- Single test file: `node --test --test-force-exit tests/unit/<file>.test.js`. The flag must come **before** the path (after it, it is silently ignored). Without it, the Playwright handle that `StealthBrowserManager` leaves open hangs the runner after all tests pass; `npm run test:unit` already sets it.
|
|
45
|
+
- Phase D regressions (agent hard stops, unified scrape, map_site ranking): `tests/unit/phaseD-regressions.test.js`.
|
|
46
|
+
- CLI (`crawlforge --help`): `init`, `scrape`, `batch`, `install-skills`, … — full reference in `docs/cli-guide.md`.
|
|
157
47
|
|
|
158
|
-
|
|
159
|
-
- `agent/` - agent (AgentOrchestrator-driven autonomous tool, v4.6.0)
|
|
160
|
-
- `basic/` - fetchUrl, extractText, extractLinks, extractMetadata, scrapeStructured
|
|
161
|
-
- `scrape/` - unifiedScrape (single-fetch multi-format `scrape` tool, v4.6.0)
|
|
162
|
-
- `crawl/` - crawlDeep, mapSite
|
|
163
|
-
- `extract/` - analyzeContent, extractContent, extractStructured, extractWithLlm, listOllamaModels, processDocument, summarizeContent
|
|
164
|
-
- `research/` - deepResearch
|
|
165
|
-
- `result/` - readResult (`read_result`: search/slice/lines/json_path over a stored over-threshold result by `result_handle`, v5.8.0)
|
|
166
|
-
- `search/` - searchWeb (proxied through CrawlForge.dev API), serpRank (real Google organic rank via DataForSEO; adapter in `search/adapters/dataforseoSearch.js`), redditSearch (Reddit posts/comments/threads via Arctic Shift + PullPush community archives — reddit.com blocks scrapers)
|
|
167
|
-
- `templates/` - ScrapeTemplateTool (10 pre-built site templates, v4.0.0)
|
|
168
|
-
- `tracking/` - trackChanges
|
|
169
|
-
- `llmstxt/` - generateLLMsTxt
|
|
48
|
+
### Debugging
|
|
170
49
|
|
|
171
|
-
|
|
50
|
+
- **stdout is reserved** for the MCP JSON-RPC stream and CLI `--json` output. All diagnostics (Winston logs, status banners) go to stderr.
|
|
51
|
+
- `NODE_ENV=development` for verbose logging and memory monitoring (logs every 60s above 200MB); `node --expose-gc server.js` for memory profiling.
|
|
52
|
+
- Cached responses are in `cache/`; application logs in `logs/`.
|
|
172
53
|
|
|
173
|
-
|
|
174
|
-
fetch_url, extract_text, extract_links, extract_metadata, extract_embedded_state, scrape_structured
|
|
54
|
+
## Architecture
|
|
175
55
|
|
|
176
|
-
|
|
177
|
-
search_web, serp_rank, reddit_search, crawl_deep, map_site, extract_content, process_document, summarize_content, analyze_content, extract_structured, extract_with_llm, list_ollama_models, batch_scrape, get_batch_results, scrape_with_actions, deep_research, track_changes, generate_llms_txt, stealth_mode, localization, scrape_template, scrape, agent, read_result, browser_session
|
|
56
|
+
`server.js` is the entry point: loads `.env` early (creator mode), sets up `AuthManager`, registers every tool through `withAuth()` for credit tracking, connects the stdio transport, and cleans up browsers and job managers on graceful shutdown.
|
|
178
57
|
|
|
179
|
-
|
|
180
|
-
- `serp_rank` — reports where a target domain ranks in Google's REAL organic results for a keyword (the SERP position Google Custom Search / `search_web` cannot give). Backed by the DataForSEO Google Organic SERP API (Live Advanced, `POST /v3/serp/google/organic/live/advanced`, HTTP Basic auth). Credentials via `DATAFORSEO_LOGIN` / `DATAFORSEO_PASSWORD`, billed to the user's own DataForSEO account (~US$0.002 per 10 results of `depth`, so $0.004 at the default `depth:20` and $0.02 at `depth:100`), separate from CrawlForge credits. When unconfigured it returns `{ configured:false }` and charges **0** credits; when configured, **Cost: 5**. Never fabricates a rank.
|
|
58
|
+
### Core (`src/core/`)
|
|
181
59
|
|
|
182
|
-
**
|
|
183
|
-
-
|
|
60
|
+
- **AuthManager** — API-key validation, credit tracking, usage reporting; `getToolCost` is the source of truth for prices.
|
|
61
|
+
- **AgentOrchestrator** — powers `agent`: NL prompt → PLAN→GATHER→ACT→DECIDE→SHAPE loop. Its three hard stops (maxSteps ≤10, maxUrls ≤20, wall-clock) are enforced by the orchestrator, never delegated to the LLM; has a degraded no-LLM-key path.
|
|
62
|
+
- **ResearchOrchestrator** — multi-stage research with query expansion and synthesis.
|
|
63
|
+
- **StealthBrowserManager** — anti-detection scraping, Chromium or Camoufox (see `.claude/rules/stealth.md`).
|
|
64
|
+
- **ActionExecutor** — Playwright browser automation for `scrape_with_actions`.
|
|
65
|
+
- **JobManager** / **WebhookDispatcher** — async jobs for batch operations and their completion callbacks.
|
|
66
|
+
- **PerformanceManager**, **LocalizationManager**, **ChangeTracker**, **SnapshotManager**.
|
|
67
|
+
- MCP features: **ResourceRegistry** (`crawlforge://` resources), **PromptRegistry** (`src/prompts/`, 5 workflow prompts), **SamplingClient** (with Ollama fallback), **ElicitationHelper** (user confirmation on expensive operations).
|
|
68
|
+
- **endpointGuard** — allowlist for the server's own backend calls.
|
|
184
69
|
|
|
185
|
-
|
|
186
|
-
- `scrape` — single fetch + one cheerio load dispatching a `formats` array (markdown/html/rawHtml/text/links/metadata/screenshot/json-schema) + `onlyMainContent`; partial-success via per-format `warnings[]`. Cost: 2.
|
|
187
|
-
- `agent` — NL prompt → autonomous research/extract, no URLs required (see AgentOrchestrator above). Cost: 8.
|
|
188
|
-
- `map_site` gained an optional `search=` param that ranks discovered URLs (`ranked_urls:[{url,score}]`); default output unchanged.
|
|
70
|
+
### Tools (`src/tools/`)
|
|
189
71
|
|
|
190
|
-
|
|
72
|
+
| Directory | Tools |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `basic/` | fetchUrl, extractText, extractLinks, extractMetadata, scrapeStructured |
|
|
75
|
+
| `scrape/` | unifiedScrape — `scrape`: one fetch, one cheerio load, a `formats` array, per-format `warnings[]` |
|
|
76
|
+
| `agent/` | `agent` (AgentOrchestrator) |
|
|
77
|
+
| `advanced/` | BatchScrapeTool, ScrapeWithActionsTool, BrowserSessionTool |
|
|
78
|
+
| `crawl/` | crawlDeep, mapSite (optional `search=` ranks URLs into `ranked_urls`) |
|
|
79
|
+
| `extract/` | analyzeContent, extractContent, extractStructured, extractWithLlm, listOllamaModels, processDocument, summarizeContent |
|
|
80
|
+
| `research/` | deepResearch |
|
|
81
|
+
| `result/` | readResult — search/slice/lines/json_path over a stored over-threshold result by `result_handle` |
|
|
82
|
+
| `search/` | searchWeb (proxied through the CrawlForge.dev API), serpRank (DataForSEO), redditSearch (community archives) — see `.claude/rules/search-tools.md` |
|
|
83
|
+
| `templates/` | ScrapeTemplateTool (10 site templates) |
|
|
84
|
+
| `tracking/` | trackChanges |
|
|
85
|
+
| `llmstxt/` | generateLLMsTxt |
|
|
191
86
|
|
|
192
|
-
The
|
|
87
|
+
**The 31 MCP tools.** Inline (6): fetch_url, extract_text, extract_links, extract_metadata, extract_embedded_state, scrape_structured. Advanced (25): search_web, serp_rank, reddit_search, crawl_deep, map_site, extract_content, process_document, summarize_content, analyze_content, extract_structured, extract_with_llm, list_ollama_models, batch_scrape, get_batch_results, scrape_with_actions, deep_research, track_changes, generate_llms_txt, stealth_mode, localization, scrape_template, scrape, agent, read_result, browser_session.
|
|
193
88
|
|
|
194
|
-
|
|
195
|
-
2. **Authentication Flow**: AuthManager for API key validation and credit tracking
|
|
196
|
-
3. **Tool Registration**: All tools registered via `server.registerTool()`, wrapped with `withAuth()` for credit tracking
|
|
197
|
-
4. **Transport**: stdio transport for MCP protocol communication
|
|
198
|
-
5. **Graceful Shutdown**: Cleans up browser instances, job managers, and other resources
|
|
89
|
+
Adding or changing a tool: `.claude/rules/tool-registration.md`.
|
|
199
90
|
|
|
200
|
-
|
|
91
|
+
## Configuration
|
|
201
92
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
- Checks credits before execution (skipped in creator mode)
|
|
205
|
-
- Reports usage with credit deduction on success
|
|
206
|
-
- Charges half credits on error
|
|
207
|
-
- Creator mode: Unlimited access for package maintainer
|
|
208
|
-
|
|
209
|
-
### Key Configuration
|
|
210
|
-
|
|
211
|
-
Critical environment variables defined in `src/constants/config.js`:
|
|
93
|
+
Defaults and validation: `src/constants/config.js`. User auth is stored in `~/.crawlforge/config.json`; development env in `.env`.
|
|
212
94
|
|
|
213
95
|
```bash
|
|
214
96
|
CRAWLFORGE_API_KEY=your_api_key_here
|
|
@@ -219,123 +101,19 @@ RATE_LIMIT_REQUESTS_PER_SECOND=10
|
|
|
219
101
|
MAX_CRAWL_DEPTH=5
|
|
220
102
|
MAX_PAGES_PER_CRAWL=100
|
|
221
103
|
RESPECT_ROBOTS_TXT=true
|
|
222
|
-
ROBOTS_CACHE_TTL_MS=3600000 # how long a parsed robots.txt stays good for
|
|
223
|
-
CRAWLFORGE_BLOCKED_HOSTS= # comma-separated; extends the permanent opt-out blocklist
|
|
224
|
-
CRAWLFORGE_STEALTH_ENGINE= # which engine `auto` resolves to on THIS deployment:
|
|
225
|
-
# chromium|playwright pins it to Chromium; unset or anything
|
|
226
|
-
# else keeps the default preference for Camoufox. A caller
|
|
227
|
-
# naming an engine always wins. There is no correct global
|
|
228
|
-
# value — which engine clears a wall depends on the exit IP
|
|
229
|
-
# (residential favours Camoufox, the hosted datacenter IP
|
|
230
|
-
# favours Chromium, measured twice).
|
|
231
|
-
CRAWLFORGE_STEALTH_PROXIES= # comma-separated proxy URLs used by the escalation stage,
|
|
232
|
-
# stealth_mode, browser_session, scrape_with_actions and the
|
|
233
|
-
# deep_research fallback when the caller passes none (a proxy
|
|
234
|
-
# passed on the call wins). CrawlForge supplies no proxies, and
|
|
235
|
-
# a datacenter one does not defeat these detectors. Distinct
|
|
236
|
-
# from the PROXY_ROTATION_* family, which belongs to
|
|
237
|
-
# localization. The agent's automatic stealth retry
|
|
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.
|
|
244
|
-
CRAWLFORGE_CLEARANCE_JAR= # `off` disables the clearance jar (stealth review Phase 4):
|
|
245
|
-
# cf_clearance/__cf_bm/datadome cookies a stealth render earned
|
|
246
|
-
# are replayed to the next stealth context with the same engine,
|
|
247
|
-
# UA and proxy. Persisted at ~/.crawlforge/stealth-clearance.json.
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
Camoufox is an **optional** dependency and its transitive `language-tags@2.1.0` requires Node ≥22. npm silently drops an optional subtree that fails an engine check, so on Node 20 it is simply absent — `'auto'` then resolves to Chromium and says so in `fallbackWarning`. `engines.node` stays at `>=20.16.0` deliberately; bumping it is breaking and is a release decision.
|
|
251
|
-
|
|
252
|
-
Web Bot Auth (optional, off by default — requests go out unsigned when unset):
|
|
253
|
-
|
|
254
|
-
```bash
|
|
255
|
-
CRAWLFORGE_SIGNING_KEY= # Ed25519 PKCS#8 PEM, or base64 of it. SECRET — never commit.
|
|
256
|
-
WEB_BOT_AUTH_DIRECTORY= # https://www.crawlforge.dev — advertised in Signature-Agent
|
|
257
104
|
```
|
|
258
105
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
`OPENAI_API_KEY` / `ANTHROPIC_API_KEY` are optional. They only affect `deep_research`: when set, it produces a fully synthesized report internally; when unset, it returns raw evidence for the calling LLM (e.g. Claude Code) to synthesize.
|
|
263
|
-
|
|
264
|
-
### Configuration Files
|
|
265
|
-
|
|
266
|
-
- `~/.crawlforge/config.json` - User authentication and API key storage
|
|
267
|
-
- `.env` - Environment variables for development
|
|
268
|
-
- `src/constants/config.js` - Central configuration with defaults and validation
|
|
269
|
-
|
|
270
|
-
### Adding New Tools
|
|
271
|
-
|
|
272
|
-
When adding a new tool to server.js:
|
|
273
|
-
|
|
274
|
-
1. Import the tool class from `src/tools/`
|
|
275
|
-
2. Instantiate the tool (with config if needed)
|
|
276
|
-
3. Register with `server.registerTool(name, { description, inputSchema }, withAuth(name, handler))`
|
|
277
|
-
4. Ensure tool implements `execute(params)` method
|
|
278
|
-
5. Add to cleanup array in gracefulShutdown if it has `destroy()` or `cleanup()` methods
|
|
279
|
-
6. Update tool count in console log at server startup
|
|
280
|
-
|
|
281
|
-
## Sandboxing & Approvals
|
|
282
|
-
|
|
283
|
-
Key mechanisms for security-conscious future sessions:
|
|
284
|
-
|
|
285
|
-
- **SSRF** (`src/utils/ssrfGuard.js` enforcing `src/utils/ssrfProtection.js`): As of v4.8.0 SSRF is actually enforced on the live scraping fetch path (previously `ssrfProtection.js` was unwired). `ssrfGuard` injects an undici dispatcher whose connect-time `lookup` validates every connection — initial request and each redirect hop — and pins the validated IP (closing the DNS-rebinding TOCTOU window). Stage 1 (default) blocks loopback, link-local/cloud-metadata (169.254.169.254), and 0.0.0.0; `SSRF_STRICT=true` adds full RFC1918/ULA/etc. enforcement. Kill switch `SSRF_PROTECTION_ENABLED=false`; `ALLOWED_DOMAINS` allowlist bypass. Wired into every read-scrape site (`_fetch.js`, `_fetchAndParse.js`, `batchScrape/worker.js`, `mapSite.js`, `BFSCrawler.js`, extract/template/session/research/llms-txt/robots/sitemap/track-changes fetches) via `ssrfGuard()`/`safeFetch()`. http/https only; dangerous ports + path-traversal still rejected by `ssrfProtection.js`.
|
|
286
|
-
- **endpointGuard** (`src/core/endpointGuard.js`): Hard allow-list of `{crawlforge.dev, www.crawlforge.dev, api.crawlforge.dev}` for the server's own backend calls; HTTPS required; fail-closed. Localhost only in creator mode (v3.0.18).
|
|
287
|
-
- **Action allowlist** (`src/core/ActionExecutor.js`): `scrape_with_actions` accepts only 7 action types: `wait`, `click`, `type`, `press`, `scroll`, `screenshot`, `executeJavaScript`. `executeJavaScript` throws unless `ALLOW_JAVASCRIPT_EXECUTION=true` is set at deploy time (off by default).
|
|
288
|
-
- **Elicitation** (`src/core/ElicitationHelper.js`): User confirmation requested for `deep_research` (>50 URLs), `batch_scrape` (sync, >25 URLs), `crawl_deep` (projected >500 pages), `extract_structured` (schema has >3 required fields, no LLM configured), and credit-low situations. Fail-open if client does not support elicitation.
|
|
289
|
-
- **Browser sandboxing**: Standard pool retains OS sandbox. Stealth Chromium uses `--no-sandbox` (deliberate fingerprint-spoofing trade-off); `--disable-web-security` was removed from it in Phase 1 of the 2026-09 stealth review — a page reads it in one line — but the non-stealth render browser (`BrowserProcessor`) still carries both flags. Camoufox (Firefox, v4.0.0) is the alternative — see `docs/stealth-engines.md`.
|
|
290
|
-
|
|
291
|
-
See `docs/sandboxing-and-approvals.md` for the full reference.
|
|
106
|
+
- Stealth variables (`CRAWLFORGE_STEALTH_ENGINE`, `CRAWLFORGE_STEALTH_PROXIES`, `CRAWLFORGE_IMPIT`, `CRAWLFORGE_CLEARANCE_JAR`): `.claude/rules/stealth.md`.
|
|
107
|
+
- Robots, blocklist and Web Bot Auth signing variables: `.claude/rules/security-guards.md`.
|
|
108
|
+
- `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` are optional and only affect `deep_research`: set, it synthesizes the report itself; unset, it returns raw evidence for the calling LLM to synthesize.
|
|
292
109
|
|
|
293
110
|
## Security
|
|
294
111
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
- `docs/sandboxing-and-approvals.md` — Canonical sandboxing & approvals reference
|
|
298
|
-
- `docs/security-audit-report.md` — Full security audit
|
|
299
|
-
- `.github/workflows/ci.yml` — CI pipeline with security checks
|
|
300
|
-
- `.github/workflows/security.yml` — Daily scheduled security scanning
|
|
301
|
-
- `docs/SECURITY.md` — Security policy and procedures
|
|
302
|
-
|
|
303
|
-
Run `npm audit` locally to check dependencies.
|
|
304
|
-
|
|
305
|
-
## Implementation Patterns
|
|
306
|
-
|
|
307
|
-
### Tool Structure
|
|
308
|
-
|
|
309
|
-
```javascript
|
|
310
|
-
export class ToolName {
|
|
311
|
-
constructor(config) { this.config = config; }
|
|
312
|
-
|
|
313
|
-
async execute(params) {
|
|
314
|
-
return { success: true, data: {...} };
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
async destroy() { /* cleanup resources */ }
|
|
318
|
-
}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
### Error Handling Pattern
|
|
322
|
-
|
|
323
|
-
```javascript
|
|
324
|
-
try {
|
|
325
|
-
const result = await tool.execute(params);
|
|
326
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
327
|
-
} catch (error) {
|
|
328
|
-
return {
|
|
329
|
-
content: [{ type: "text", text: `Operation failed: ${error.message}` }],
|
|
330
|
-
isError: true,
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
```
|
|
112
|
+
- SSRF is enforced on every live fetch path through `ssrfGuard()`/`safeFetch()`; never call `fetch` directly on a user-supplied URL.
|
|
113
|
+
- References: `docs/sandboxing-and-approvals.md` (canonical), `docs/security-audit-report.md`, `docs/SECURITY.md`; CI checks in `.github/workflows/ci.yml` and `.github/workflows/security.yml`. Run `npm audit` locally.
|
|
334
114
|
|
|
335
|
-
## Project
|
|
115
|
+
## Project management rules
|
|
336
116
|
|
|
337
|
-
- Delegate to a sub
|
|
338
|
-
-
|
|
339
|
-
-
|
|
340
|
-
- Put all documentation md files into the `docs/` folder
|
|
341
|
-
- Every time you finish a phase run the test suites (`npm run test:unit` and `npm test`) and fix all failures before pushing
|
|
117
|
+
- Delegate to a sub-agent only for a genuinely independent, parallelizable track — not for work finishable in a few tool calls, and never to verify your own output (Claude 5 models over-delegate when told to parallelize).
|
|
118
|
+
- Put all documentation `.md` files in `docs/`.
|
|
119
|
+
- When a phase completes: run `npm run test:unit` and `npm test` and fix all failures, update `docs/PRODUCTION_READINESS.md`, then push all changes to GitHub.
|
package/README.md
CHANGED
|
@@ -199,8 +199,8 @@ CrawlForge requires a CrawlForge API key — **every tool is metered and consume
|
|
|
199
199
|
| `browser_session` | 3 | **A browser page that stays open across calls**, keeping its cookies and its login in between. `open` a session on a URL, `snapshot` it to list the interactive elements as stable refs (`@e1`, `@e2`), `act` on a ref, `read` the content, `close`. Priced per operation: open 3, read 2, snapshot/act/screenshot/close/list 1 each. Reach for it when you must see the page before choosing what to click, when the flow spans several calls, or when a login must hold across later reads; one fixed action chain on one page is `scrape_with_actions` |
|
|
200
200
|
| `summarize_content` | 4 | Generate intelligent summaries |
|
|
201
201
|
| `crawl_deep` | 4 | Deep crawl entire websites |
|
|
202
|
-
| `search_web` | 5 | Search the web
|
|
203
|
-
| `reddit_search` | 5 | Search Reddit posts/comments or read a full thread — reddit.com blocks direct scraping, so this reads the Arctic Shift community archive (free, no Reddit credentials). A Reddit-wide search spends a web search to discover posts, so it is priced with `search_web` |
|
|
202
|
+
| `search_web` | 5 | Search the live web (Brave Search API, through the CrawlForge API) |
|
|
203
|
+
| `reddit_search` | 5 | Search Reddit posts/comments or read a full thread — reddit.com blocks direct scraping, so this reads the Arctic Shift community archive (free, no Reddit credentials). A Reddit-wide search spends a web search to discover posts, so it is priced with `search_web`. Optional: with your own Reddit app credentials (`REDDIT_CLIENT_ID`/`REDDIT_CLIENT_SECRET`), posts searches and thread reads come from Reddit's official API first (live scores, complete comment trees), with the archives as fallback; same price. Reddit no longer issues new credentials without an approval ticket, see [docs/reddit-access-and-oauth.md](docs/reddit-access-and-oauth.md) |
|
|
204
204
|
| `serp_rank` | 5 | Check where a domain ranks in Google's **real organic SERP** for a keyword (the position `search_web` can't give). Powered by DataForSEO (`DATAFORSEO_LOGIN`/`DATAFORSEO_PASSWORD`, billed to your own DataForSEO account). Returns `{ configured:false }` and charges **0** credits until configured |
|
|
205
205
|
| `batch_scrape` | 5 | Process multiple URLs simultaneously |
|
|
206
206
|
| `scrape_with_actions` | 5 | Browser automation chains |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crawlforge-mcp-server",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.21.1",
|
|
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",
|
|
@@ -125,7 +125,6 @@
|
|
|
125
125
|
"diff": "^9.0.0",
|
|
126
126
|
"dotenv": "^17.2.1",
|
|
127
127
|
"franc": "^6.2.0",
|
|
128
|
-
"isomorphic-dompurify": "^3.9.0",
|
|
129
128
|
"jsdom": "^29.0.2",
|
|
130
129
|
"lru-cache": "^11.1.0",
|
|
131
130
|
"mammoth": "^1.12.2",
|
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.
|
|
116
|
+
version: "6.21.1",
|
|
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",
|
|
@@ -588,7 +588,7 @@ registerToolIfEnabled("search_web", {
|
|
|
588
588
|
|
|
589
589
|
// Tool: serp_rank — REAL Google organic rank for a target domain (via DataForSEO)
|
|
590
590
|
registerToolIfEnabled("serp_rank", {
|
|
591
|
-
description: "Use this to check where a domain ranks in Google's ORGANIC results for a keyword - real SERP position, not
|
|
591
|
+
description: "Use this to check where a domain ranks in Google's ORGANIC results for a keyword - real SERP position, not search_web's order. Returns the target's organic rank, the ranking URL, and every position it holds. Not for general search (search_web). One lookup is one sample: Google can return a different result set for the same query minutes apart (seResultsCount tells them apart), and sometimes a decoy page of unrelated results (suspect:true), so compare several before reading a rank change. Requires DataForSEO credentials and returns configured:false without them - do not retry in that case. Cost: 5 credits (0 when unconfigured). Example: serp_rank({keyword: \"managed wordpress hosting\", target: \"dashboardhosting.com\", location_name: \"United States\"})",
|
|
592
592
|
annotations: { title: "SERP Rank Check", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
593
593
|
inputSchema: {
|
|
594
594
|
keyword: z.string().describe("The search query to check ranking for"),
|
|
@@ -1395,9 +1395,11 @@ function stealthScrapeFormats(formats, scraped) {
|
|
|
1395
1395
|
const links = [];
|
|
1396
1396
|
$('a[href]').each((_, el) => {
|
|
1397
1397
|
const href = $(el).attr('href');
|
|
1398
|
-
if (!href || href.startsWith('#')
|
|
1398
|
+
if (!href || href.startsWith('#')) return;
|
|
1399
1399
|
try {
|
|
1400
|
-
const
|
|
1400
|
+
const resolved = new URL(href, scraped.url);
|
|
1401
|
+
if (['javascript:', 'data:', 'vbscript:'].includes(resolved.protocol)) return;
|
|
1402
|
+
const absolute = resolved.toString();
|
|
1401
1403
|
if (seen.has(absolute)) return;
|
|
1402
1404
|
seen.add(absolute);
|
|
1403
1405
|
links.push({ href: absolute, text: $(el).text().trim() });
|
|
@@ -444,7 +444,7 @@ export class BFSCrawler {
|
|
|
444
444
|
const links = [];
|
|
445
445
|
$('a[href]').each((_, element) => {
|
|
446
446
|
const href = $(element).attr('href');
|
|
447
|
-
if (href && !href.startsWith('#') &&
|
|
447
|
+
if (href && !href.startsWith('#') && !/^\s*(javascript|data|vbscript):/i.test(href)) {
|
|
448
448
|
links.push(href);
|
|
449
449
|
}
|
|
450
450
|
});
|
|
@@ -306,7 +306,7 @@ const searchWebShape = {
|
|
|
306
306
|
effective_query: z.string().optional().describe('Present when query expansion changed the query actually used'),
|
|
307
307
|
expanded_queries: z.array(z.string()).optional().describe('Present only when the original query returned nothing: the queries searched, in order - the original, then its expanded form'),
|
|
308
308
|
results: z.array(searchWebResultShape).optional(),
|
|
309
|
-
total_results: z.union([z.string(), z.number()]).optional(),
|
|
309
|
+
total_results: z.union([z.string(), z.number()]).nullable().optional().describe('The backend\'s total match count; null when it reports none (Brave Search API)'),
|
|
310
310
|
search_time: z.number().optional(),
|
|
311
311
|
offset: z.number().optional(),
|
|
312
312
|
limit: z.number().optional(),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: crawlforge-batch-automation
|
|
3
3
|
description: "Automates large scraping jobs and browser interactions with CrawlForge's batch_scrape, get_batch_results, scrape_with_actions, and generate_llms_txt tools. Use when the user wants to scrape many URLs at once, batch-scrape a list of pages, collect dozens of product, news, or competitor pages, run browser actions (click, type, scroll, wait) before scraping, log in or fill a form before extracting, or generate an llms.txt for a site. Use sync mode for up to about 25 URLs and async with a webhook for large batches; retrieve paginated output with get_batch_results."
|
|
4
4
|
metadata:
|
|
5
|
-
version:
|
|
5
|
+
version: 6.21.1
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: crawlforge-browser-sessions
|
|
3
3
|
description: "Keeps one browser page alive across several tool calls with CrawlForge's browser_session tool. Use when the user needs to log in and then read pages behind that login, work through a multi-step flow (search, filter, paginate, fill a wizard), or look at a page before deciding what to click. The loop is: open a session on a URL, snapshot it to list the interactive elements with stable refs (@e1, @e2), act on those refs, read the content, close. Unlike scrape_with_actions, which is one-shot and closes its browser when the call returns, a session survives between calls, so one login is paid for once and a wrong selector costs one call instead of a whole chain."
|
|
4
4
|
metadata:
|
|
5
|
-
version:
|
|
5
|
+
version: 6.21.1
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: crawlforge-change-tracking
|
|
3
3
|
description: "Monitors web pages for changes over time with CrawlForge's track_changes tool. Use when the user wants to track changes to a page, watch a URL, monitor competitor pricing, detect when content updates, get notified of regulation or product-availability changes, or diff a page against a saved baseline. Workflow: create a baseline with operation create_baseline, then periodically compare with operation compare to get a change percentage and a diff; supports CSS-selector scoping, webhooks, and scheduled monitoring."
|
|
4
4
|
metadata:
|
|
5
|
-
version:
|
|
5
|
+
version: 6.21.1
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: crawlforge-deep-research
|
|
3
3
|
description: "Runs multi-source web research and autonomous question-answering with CrawlForge's deep_research, agent, search_web, and reddit_search tools. Use when the user wants to research a topic, do a deep dive, compare competitors, gather facts with citations, answer a question from the web, search the web, or get a synthesized report from many sources, or search Reddit posts, comments, and threads. deep_research expands queries, fetches and dedupes sources, then synthesizes; agent autonomously plans searches and navigation from a plain-English prompt with no URLs needed; search_web returns ranked results; reddit_search searches Reddit via community archives (reddit.com blocks scrapers). Caps costs via max_urls and confirms before expensive runs."
|
|
4
4
|
metadata:
|
|
5
|
-
version:
|
|
5
|
+
version: 6.21.1
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: crawlforge-getting-started
|
|
3
3
|
description: "Orientation and tool-selection guide for the CrawlForge MCP server's 31 web tools. Use when the user is getting started with CrawlForge, asks which CrawlForge tool to use, how to set up the API key, how skills or the CLI work, what a tool costs in credits, or when one tool fails and a fallback is needed. Routes requests to the right specialized skill (web scraping, deep research, stealth, structured extraction, change tracking, batch automation, browser sessions), and explains MCP-tools-vs-CLI, the Ollama-first LLM fallback chain, and per-tool credit costs."
|
|
4
4
|
metadata:
|
|
5
|
-
version:
|
|
5
|
+
version: 6.21.1
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: crawlforge-stealth-browsing
|
|
3
3
|
description: "Bypasses bot detection with CrawlForge's stealth_mode tool and looks up a country's locale settings with localization. Use when a site returns 403 or 429, CAPTCHAs, 'please enable JavaScript', or empty content, or is protected by Cloudflare, DataDome, or PerimeterX, or when the user needs a page in a specific locale, language, or timezone. stealth_mode runs a stealth browser (engine auto by default: camoufox/Firefox for advanced fingerprinting, playwright/Chromium when pinned for speed) and can screenshot; localization returns a country's Accept-Language, timezone and currency for you to pass to fetch_url or stealth_mode - it applies nothing itself and uses no proxy. Explains when to escalate from a normal scrape to stealth, and why a hard block needs a residential proxy."
|
|
4
4
|
metadata:
|
|
5
|
-
version:
|
|
5
|
+
version: 6.21.1
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -71,8 +71,8 @@ differs from the one the browser was launched with) is named in the result's
|
|
|
71
71
|
- `engine:"auto"` (default) — Camoufox when its binary is installed, Chromium
|
|
72
72
|
with a warning when it is not. Leave it alone unless you have a reason.
|
|
73
73
|
- `engine:"camoufox"` — Firefox-based with native anti-detection (no patches).
|
|
74
|
-
The
|
|
75
|
-
(harrods.com)
|
|
74
|
+
The engine that gets past Cloudflare Turnstile and Akamai where Chromium is
|
|
75
|
+
blocked (e.g. indeed.com, harrods.com). Pin it to require that engine: it
|
|
76
76
|
errors rather than falling back. Costs roughly +0.8 s and +400 MB per call
|
|
77
77
|
against Chromium.
|
|
78
78
|
- `engine:"playwright"` — Chromium with stealth patches. Pin it for speed on
|
|
@@ -32,8 +32,8 @@ them default to `auto`.
|
|
|
32
32
|
- Firefox-based with **native** anti-detection (no runtime patches — uses
|
|
33
33
|
Firefox's genuine properties).
|
|
34
34
|
- Scores higher on CreepJS and the other detector pages than patched Chromium,
|
|
35
|
-
and
|
|
36
|
-
(harrods.com)
|
|
35
|
+
and gets past Cloudflare Turnstile and Akamai where Chromium is blocked
|
|
36
|
+
(e.g. indeed.com, harrods.com).
|
|
37
37
|
- Heavier: measured once each on an Apple Silicon Mac, 946 ms and 667 MB to
|
|
38
38
|
launch a browser, a context and a blank page, against Chromium's 148 ms and
|
|
39
39
|
253 MB.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: crawlforge-structured-extraction
|
|
3
3
|
description: "Extracts structured JSON and analyzes content with CrawlForge's extract_structured, extract_with_llm, extract_embedded_state, scrape_structured, scrape_template, process_document, analyze_content, summarize_content, and list_ollama_models tools. Use when the user wants to extract specific fields, pull data into a JSON schema, extract by natural-language prompt, scrape with CSS selectors, read a page's embedded JavaScript state (__NEXT_DATA__, React Server Components, Nuxt, Apollo, Redux), get product, profile, or repo data from known sites (Amazon, LinkedIn, GitHub, YouTube, Reddit, and more), parse a PDF or DOCX, summarize a page, or analyze sentiment, entities, or keywords. Defaults to local Ollama for LLM extraction; OpenAI and Anthropic optional."
|
|
4
4
|
metadata:
|
|
5
|
-
version:
|
|
5
|
+
version: 6.21.1
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|