
Security News
Ruby's Bundler 4.0.18 Extends Cooldown to bundle lock and bundle cache
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.
Web scraper + validated extraction contracts for AI agents. Markdown, PDF/DOCX, JSON-LD/microdata/commerce/forms/analytics, structured errors, diagnostics, and LLM extraction to any OpenAI-compatible endpoint.
Web scraper + validated extraction contracts for AI agents. PDF/DOCX, markdown, JSON-LD/microdata/commerce/forms/analytics detection, no-LLM readiness diagnostics, structured errors, standard User-Agent compatibility, retry/timeout, optional in-memory cache. Adaptive Cheerio→Playwright. Open source, AGPL-3.0.
Current validated-contract, MCP, and REST API features should be installed from this GitHub source until the next npm publish lands:
git clone https://github.com/manchittlab/TheCrawler.git
cd TheCrawler/engine
npm install
npm run build
node dist/cli.js --version # expect 0.3.3 for this source build
The published npm package exists, but may lag this source build:
npm install thecrawler
Or from a local checkout:
npm install file:/path/to/TheCrawler/engine
import { crawl, extract } from 'thecrawler';
// Plain crawl
const r = await crawl({
urls: ['https://example.com'],
extractMarkdown: true,
});
console.log(r.pages[0].markdown);
// Multi-URL with reliability options
const r2 = await crawl({
urls: ['https://...', 'https://...'],
extractMarkdown: true,
requestRetries: 3, // retry transient failures
requestTimeoutSecs: 30,
rotateUserAgent: true, // rotate from real-browser UA pool
cache: { enabled: true, ttlSeconds: 300 },
});
// Errors are structured. Branch on errorType + retryable.
for (const p of r2.pages) {
if (p.status === 'error') {
console.log(p.errorType, p.errorRetryable, p.error);
// errorType ∈ 'dns'|'timeout'|'rate-limit'|'blocked-bot'|
// 'js-required'|'http-4xx'|'http-5xx'|'parse'|'network'|'unknown'
}
}
Crawls a URL, sends the cleaned markdown to an OpenAI-compatible LLM endpoint with a JSON schema or natural-language prompt, returns parsed typed data. Endpoint-agnostic: works against llama.cpp's llama-server, vLLM, LM Studio, Ollama, OpenAI proper, and compatible /v1/chat/completions endpoints. Schema-backed extraction uses JSON Schema response format where supported, with fallbacks for endpoints that only support JSON-object or text output.
import { extract } from 'thecrawler';
const r = await extract({
urls: ['https://shop.example.com/products/123'],
jsonSchema: {
type: 'object',
properties: {
productName: { type: 'string' },
price: { type: 'number' },
currency: { type: 'string' },
inStock: { type: 'boolean' },
},
required: ['productName'],
},
llm: {
baseUrl: 'http://your-llm-host:8080/v1/chat/completions',
model: 'your-model-name',
// apiKey: 'optional',
// temperature: 0,
// maxTokens: 4000,
// timeoutSecs: 120,
},
});
console.log(r[0].data);
// { productName: '...', price: 49.99, currency: 'USD', inStock: true }
ExtractResult includes parsed data, status, structured errorType, rawResponse (for debugging), token usage, and timing breakdown (crawlMs, llmMs, responseTimeMs).
# From this source checkout, use the local CLI until npm catches up.
node dist/cli.js --version # expect 0.3.3 for this source build
# Crawl
node dist/cli.js crawl https://example.com --markdown
node dist/cli.js crawl https://example.com --retries 5 --timeout 60 --cache
# Search Google + scrape top results
node dist/cli.js search "your query" --markdown
# Sitemap-driven crawl
node dist/cli.js sitemap https://example.com/sitemap.xml --markdown
# Markdown shortcut
node dist/cli.js md https://example.com
# Built-in extraction contract with validation evidence
node dist/cli.js extract https://example.com/listing \
--contract real-estate-listing \
--llm-base-url http://localhost:1234/v1/chat/completions \
--llm-model local-model \
--evidence-output real-estate-evidence.json
# No-LLM contract readiness diagnostic
node dist/cli.js diagnose https://example.com/listing-1 https://example.com/listing-2 \
--contract real-estate-listing \
--output real-estate-workflow-diagnostic.json \
--report real-estate-workflow-report.md
Contracts turn a crawl into a repeatable, validated output shape for agent workflows. Current built-in contracts are real-estate-listing, which extracts normalized property listing fields, and product-page, which extracts normalized product catalog fields such as name, price, availability, brand, SKU, rating, source URL, confidence, and evidence notes.
Use node dist/cli.js extract --list-contracts to list available contracts from a current source checkout. Contract mode returns the normal ExtractResult plus a validation object with valid, requiredFields, and missingRequiredFields, so an agent can branch on extraction quality instead of trusting loose markdown.
Use node dist/cli.js diagnose <url...> --contract real-estate-listing or --contract product-page before LLM extraction to score whether a source or workflow is ready for contract extraction. The diagnostic does not call an LLM; it crawls each page, checks source signals, and returns per-URL verdict, readyForExtraction, score, blockers, warnings, recommendedNextStep, and signal evidence plus an aggregate workflow summary (readyUrls, blockedUrls, workflowVerdict, blockersByType, recommendedNextStep). Add --report report.md to produce a buyer-readable Markdown report with missing readiness signals, without raw extracted contact details or page evidence.
Eight tools: crawl, crawl_markdown, search_and_crawl, crawl_sitemap, extract_structured, list_extraction_contracts, diagnose_extraction_contract, extract_extraction_contract.
Add to your MCP client config (Claude Code / Cursor / Windsurf):
{
"mcpServers": {
"thecrawler": {
"command": "node",
"args": ["/path/to/TheCrawler/engine/dist/mcp.js"],
"env": {
"THECRAWLER_LLM_BASEURL": "http://your-llm-host:8080/v1/chat/completions",
"THECRAWLER_LLM_MODEL": "your-model-name"
}
}
}
}
The contract tools let an MCP client discover built-in contracts, run a no-LLM readiness diagnostic, and extract with required-field validation:
{
"tool": "diagnose_extraction_contract",
"arguments": {
"urls": ["https://example.com/listing"],
"contractName": "real-estate-listing",
"reportMarkdown": true
}
}
The env vars set defaults for extract_structured and extract_extraction_contract; per-call args override.
THECRAWLER_API_KEY=local_test_key node dist/server.js --port 3000
Endpoints:
POST /v1/crawlPOST /v1/scrapePOST /v1/markdownPOST /v1/searchPOST /v1/mapPOST /v1/sitemapPOST /v1/extractGET /v1/contracts?includeSchema=truePOST /v1/diagnosePOST /v1/extract-contractGET /v1/healthContract endpoints mirror the CLI/MCP contract flow for API-first buyers:
curl -H "Authorization: Bearer $THECRAWLER_API_KEY" \
http://localhost:3000/v1/contracts?includeSchema=true
curl -X POST http://localhost:3000/v1/diagnose \
-H "Authorization: Bearer $THECRAWLER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contractName":"product-page","urls":["https://example.com/product"],"reportMarkdown":true}'
curl -X POST http://localhost:3000/v1/scrape \
-H "Authorization: Bearer $THECRAWLER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/product","formats":["markdown","metadata","links","structuredData","commerceData"]}'
curl -X POST http://localhost:3000/v1/map \
-H "Authorization: Bearer $THECRAWLER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","maxPages":1}'
curl -X POST http://localhost:3000/v1/extract-contract \
-H "Authorization: Bearer $THECRAWLER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contractName":"product-page","urls":["https://example.com/product"],"llmBaseUrl":"http://localhost:1234/v1/chat/completions","llmModel":"qwen/qwen3.5-9b"}'
/v1/scrape is the one-page API path for selected output formats. /v1/diagnose does not call an LLM. /v1/extract-contract uses the selected contract schema and returns required-field validation evidence. All extraction claims still depend on the tested URLs and the configured LLM; blocked pages are reported as blockers, not false successes.
Per page: title, description, language, canonical URL, robots directives, full text (50K cap), markdown (boilerplate-stripped, GFM), heading-aware chunks, headings (h1-h6), links (with internal/external + rel), images (with lazy-load src), meta tags (incl. OG + Twitter Card), tables, JSON-LD, microdata (itemscope/itemprop), commerce data (price/currency/SKU/rating from JSON-LD Product), forms (action/method/fields), 16 analytics trackers detected (GA4, GTM, Facebook Pixel, Hotjar, Segment, Mixpanel, Amplitude, Heap, Plausible, Matomo, Clarity, LinkedIn, Twitter, Pinterest, TikTok, etc.), optional email-like and phone-like public text fields, social links, hreflang tags, pagination links, redirect chain, response timing, page size.
PDF and DOCX URLs are auto-detected and parsed (text + metadata for PDFs; text + markdown for DOCX).
Default Cheerio (fast HTTP+parse) — set usePlaywright: true for full JS rendering, or adaptiveCrawling: true to try Cheerio first and auto-fall-back to Playwright when an SPA shell is detected (text < 200 chars or known SPA root div).
Optional User-Agent rotation uses standard browser User-Agent strings for compatibility; it does not override access controls. Challenge-page detection: when a 200 response carries an access-control or challenge body ("checking your browser", "attention required", "cloudflare ray id"), the page is marked errorType: 'blocked-bot' rather than silently returning challenge HTML.
If your workflow legitimately uses a proxy, supply proxyUrl (any Crawlee-compatible HTTP(S) proxy URL).
AGPL-3.0-or-later. Commercial licensing available — contact through the GitHub repo.
FAQs
Web scraper + validated extraction contracts for AI agents. Markdown, PDF/DOCX, JSON-LD/microdata/commerce/forms/analytics, structured errors, diagnostics, and LLM extraction to any OpenAI-compatible endpoint.
The npm package thecrawler receives a total of 15 weekly downloads. As such, thecrawler popularity was classified as not popular.
We found that thecrawler demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.