crawlforge-mcp-server 6.22.0 → 6.22.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 +2 -2
- package/server.js +1 -1
- package/src/core/AgentOrchestrator.js +88 -3
- package/src/core/ResearchOrchestrator.js +30 -2
- 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 +1 -1
- package/src/skills/agent-skills/crawlforge-structured-extraction/SKILL.md +1 -1
- package/src/skills/agent-skills/crawlforge-web-scraping/SKILL.md +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crawlforge-mcp-server",
|
|
3
|
-
"version": "6.22.
|
|
3
|
+
"version": "6.22.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",
|
|
@@ -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.18.
|
|
124
|
+
"crawlforge-extractors": "^1.18.2",
|
|
125
125
|
"diff": "^9.0.0",
|
|
126
126
|
"dotenv": "^17.2.1",
|
|
127
127
|
"franc": "^6.2.0",
|
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.22.
|
|
116
|
+
version: "6.22.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",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* pro model: delegates to ResearchOrchestrator.conductResearch() for richer synthesis.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
import { load } from 'cheerio';
|
|
23
24
|
import { fetchAndParse } from '../tools/extract/_fetchAndParse.js';
|
|
24
25
|
import { SamplingClient } from './SamplingClient.js';
|
|
25
26
|
import { fenceUntrusted } from '../utils/untrustedContent.js';
|
|
@@ -75,7 +76,7 @@ function truncate(text, maxChars = 8000) {
|
|
|
75
76
|
* strings that do not (deduplicated, in answer order). Comparison is
|
|
76
77
|
* case-insensitive with whitespace and thousands separators removed, so
|
|
77
78
|
* "6.3.3" matches "6.3.3" and "1,234" matches "1 234". URLs in the answer are
|
|
78
|
-
*
|
|
79
|
+
* skipped here: they are citations, checked by unverifiedUrls.
|
|
79
80
|
*/
|
|
80
81
|
const MONTHS = '(?:jan|feb|mar|apr|may|jun|jul|aug|sep|sept|oct|nov|dec)[a-z]*';
|
|
81
82
|
const VALUE_PATTERNS = [
|
|
@@ -109,6 +110,71 @@ export function unverifiedValues(answer, sourceText) {
|
|
|
109
110
|
return missing.filter((v, i) => !missing.some((o, j) => j !== i && o.length > v.length && o.includes(v)));
|
|
110
111
|
}
|
|
111
112
|
|
|
113
|
+
/**
|
|
114
|
+
* The http(s) URLs in a text, trailing punctuation removed. A closing
|
|
115
|
+
* parenthesis stays only when it closes one opened inside the URL, so
|
|
116
|
+
* "[HN](https://x/item?id=1)" yields the link and "/wiki/Foo_(bar)" survives.
|
|
117
|
+
*/
|
|
118
|
+
export function urlsIn(text) {
|
|
119
|
+
return (String(text || '').match(/https?:\/\/[^\s<>"'`\]]+/g) || []).map(url => {
|
|
120
|
+
for (;;) {
|
|
121
|
+
if (/[.,;:!?*'"]$/.test(url)) url = url.slice(0, -1);
|
|
122
|
+
else if (url.endsWith(')') && url.split('(').length < url.split(')').length) url = url.slice(0, -1);
|
|
123
|
+
else return url;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* A URL as a citation is compared: scheme, "www.", fragment and trailing
|
|
130
|
+
* slash dropped, host lowercased, "&" decoded. Null when it does not parse.
|
|
131
|
+
*/
|
|
132
|
+
function citationKey(url) {
|
|
133
|
+
try {
|
|
134
|
+
const u = new URL(String(url).replace(/&/g, '&'));
|
|
135
|
+
return `${u.host.toLowerCase().replace(/^www\./, '')}${u.pathname.replace(/\/+$/, '')}${u.search}`;
|
|
136
|
+
} catch {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* URLs the answer cites that no fetched page supports: not a fetched URL
|
|
143
|
+
* (before or after redirects), not a link on a fetched page, and not written
|
|
144
|
+
* in the source text. The R25 re-check (2026-10-19) answered the current HN
|
|
145
|
+
* top story with the right title and a link to a 2021 story that none of the
|
|
146
|
+
* sources contained, and the value-only check above skipped it as a citation.
|
|
147
|
+
*
|
|
148
|
+
* @param {string} answer
|
|
149
|
+
* @param {Iterable<string>} citable fetched URLs, their final URLs and the links on them
|
|
150
|
+
* @param {string} [sourceText]
|
|
151
|
+
* @returns {string[]} the cited URLs as written, deduplicated
|
|
152
|
+
*/
|
|
153
|
+
export function unverifiedUrls(answer, citable, sourceText = '') {
|
|
154
|
+
const known = new Set([...citable, ...urlsIn(sourceText)].map(citationKey).filter(Boolean));
|
|
155
|
+
const seen = new Set();
|
|
156
|
+
return urlsIn(answer).filter(url => {
|
|
157
|
+
const key = citationKey(url);
|
|
158
|
+
if (!key || seen.has(key)) return false;
|
|
159
|
+
seen.add(key);
|
|
160
|
+
return !known.has(key);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Absolute http(s) hrefs of the links on a parsed page. */
|
|
165
|
+
function pageLinks($, baseUrl) {
|
|
166
|
+
const links = [];
|
|
167
|
+
$('a[href]').each((_, el) => {
|
|
168
|
+
try {
|
|
169
|
+
const url = new URL($(el).attr('href'), baseUrl);
|
|
170
|
+
if (url.protocol === 'http:' || url.protocol === 'https:') links.push(url.href);
|
|
171
|
+
} catch {
|
|
172
|
+
// An unparsable href cites nothing.
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
return links;
|
|
176
|
+
}
|
|
177
|
+
|
|
112
178
|
/**
|
|
113
179
|
* Current-state task gate: prompts about the live "now" ("right now",
|
|
114
180
|
* "current", "currently", "today", "latest", "#1 … now") go stale through search alone —
|
|
@@ -596,6 +662,9 @@ export class AgentOrchestrator {
|
|
|
596
662
|
// cap whenever it was smaller than capUrls, leaving maxUrls unreachable
|
|
597
663
|
// at its default. Both caps remain fully enforced (neither is weakened).
|
|
598
664
|
const evidence = [];
|
|
665
|
+
// URLs an answer may cite: every evidence page's URL (requested and
|
|
666
|
+
// final) and the links on it.
|
|
667
|
+
const citable = [];
|
|
599
668
|
let urlsFetched = 0;
|
|
600
669
|
let step = 0;
|
|
601
670
|
const warnings = [];
|
|
@@ -631,6 +700,7 @@ export class AgentOrchestrator {
|
|
|
631
700
|
text: truncate(plain.textContent),
|
|
632
701
|
step
|
|
633
702
|
});
|
|
703
|
+
citable.push(url, plain.finalUrl, ...pageLinks(plain.$, plain.finalUrl));
|
|
634
704
|
continue;
|
|
635
705
|
}
|
|
636
706
|
// A real page that is simply off-topic: nothing to retry.
|
|
@@ -675,6 +745,7 @@ export class AgentOrchestrator {
|
|
|
675
745
|
via: 'stealth',
|
|
676
746
|
step
|
|
677
747
|
});
|
|
748
|
+
citable.push(url, stealth.url || url, ...pageLinks(load(stealth.html || ''), stealth.url || url));
|
|
678
749
|
continue;
|
|
679
750
|
}
|
|
680
751
|
warnings.push(`stealth retry of ${url} ${rendered.success ? 'returned a page unrelated to the task' : `did not get the page either${rendered.blocked?.vendor ? ` (${rendered.blocked.vendor})` : ''}`}`);
|
|
@@ -685,6 +756,7 @@ export class AgentOrchestrator {
|
|
|
685
756
|
|
|
686
757
|
if (relevantExcerpt) {
|
|
687
758
|
evidence.push({ url, title: relevantExcerpt.title, text: relevantExcerpt.text, snippet: true, step });
|
|
759
|
+
citable.push(url);
|
|
688
760
|
}
|
|
689
761
|
}
|
|
690
762
|
|
|
@@ -777,6 +849,7 @@ export class AgentOrchestrator {
|
|
|
777
849
|
let degraded = false;
|
|
778
850
|
let degradedReason;
|
|
779
851
|
let unverified = [];
|
|
852
|
+
let unverifiedLinks = [];
|
|
780
853
|
let forumOnlyVersions = [];
|
|
781
854
|
// Distinct from `degraded`: a run can be degraded because its version
|
|
782
855
|
// claims are unsupported and still have had its provenance checked.
|
|
@@ -820,11 +893,16 @@ export class AgentOrchestrator {
|
|
|
820
893
|
// 2026-09-04). Versions, dates and counts in the answer must appear in
|
|
821
894
|
// the source text; what does not gets one corrective rewrite, and
|
|
822
895
|
// whatever still remains is named in the answer and in `provenance`.
|
|
896
|
+
// A cited URL is checked the same way (R25 re-check, 2026-10-19: the
|
|
897
|
+
// right HN title with an invented item link).
|
|
898
|
+
const sourceText = evidence.map(e => e.text || '').join('\n');
|
|
823
899
|
unverified = unverifiedValues(answer, combinedText);
|
|
824
|
-
|
|
900
|
+
unverifiedLinks = unverifiedUrls(answer, citable, sourceText);
|
|
901
|
+
if ((unverified.length > 0 || unverifiedLinks.length > 0) && remaining() >= REWRITE_MIN_REMAINING_MS) {
|
|
825
902
|
const retryPrompt =
|
|
826
903
|
`${synthesisPrompt}\n\nYour previous answer was:\n${fenceUntrusted(answer, 'previous answer')}\n` +
|
|
827
|
-
`It contains values that appear nowhere in the source text: ${unverified.map(v => `"${v}"`).join(', ')}. ` +
|
|
904
|
+
(unverified.length > 0 ? `It contains values that appear nowhere in the source text: ${unverified.map(v => `"${v}"`).join(', ')}. ` : '') +
|
|
905
|
+
(unverifiedLinks.length > 0 ? `It cites URLs that are not among the sources or the links on them: ${unverifiedLinks.join(', ')}. Cite only the source URLs given above. ` : '') +
|
|
828
906
|
`Rewrite the answer. Keep only values that the sources state, spelled as the sources spell them. ` +
|
|
829
907
|
`Where the sources do not state a value, say that it is not stated instead of guessing.`;
|
|
830
908
|
try {
|
|
@@ -832,6 +910,7 @@ export class AgentOrchestrator {
|
|
|
832
910
|
if (rewritten && rewritten.trim()) {
|
|
833
911
|
answer = rewritten;
|
|
834
912
|
unverified = unverifiedValues(answer, combinedText);
|
|
913
|
+
unverifiedLinks = unverifiedUrls(answer, citable, sourceText);
|
|
835
914
|
}
|
|
836
915
|
} catch {
|
|
837
916
|
// Keep the first answer; it is flagged below.
|
|
@@ -842,6 +921,11 @@ export class AgentOrchestrator {
|
|
|
842
921
|
`\n\nProvenance warning: ${unverified.map(v => `"${v}"`).join(', ')} ` +
|
|
843
922
|
`${unverified.length === 1 ? 'does' : 'do'} not appear in the fetched sources and may be invented.`;
|
|
844
923
|
}
|
|
924
|
+
if (unverifiedLinks.length > 0) {
|
|
925
|
+
answer +=
|
|
926
|
+
`\n\nProvenance warning: ${unverifiedLinks.join(', ')} ` +
|
|
927
|
+
`${unverifiedLinks.length === 1 ? 'is' : 'are'} not among the fetched pages or the links on them and may be invented.`;
|
|
928
|
+
}
|
|
845
929
|
|
|
846
930
|
// Asked for a current version, the agent answered "2.4.3" from a forum
|
|
847
931
|
// thread about a different project while the project's own site and its
|
|
@@ -931,6 +1015,7 @@ export class AgentOrchestrator {
|
|
|
931
1015
|
provenance: {
|
|
932
1016
|
checked: !synthesisFailed,
|
|
933
1017
|
unverified,
|
|
1018
|
+
...(unverifiedLinks.length > 0 ? { unverified_urls: unverifiedLinks } : {}),
|
|
934
1019
|
...(forumOnlyVersions.length > 0 ? { unsupported_versions: forumOnlyVersions } : {})
|
|
935
1020
|
}
|
|
936
1021
|
};
|
|
@@ -67,6 +67,27 @@ export function reportedFindings(keyFindings) {
|
|
|
67
67
|
// At most three digits, so a year such as "(2024)" stays.
|
|
68
68
|
const CITATION_MARKER = /\s*(?:\(\d{1,3}(?:\s*[,\u2013-]\s*\d{1,3})*\)|\[\d{1,3}(?:\s*[,\u2013-]\s*\d{1,3})*\])/g;
|
|
69
69
|
const LIST_MARKER = /^(?:[-*\u2022\u25AA\u2013]|\d{1,2}[.)])\s+/;
|
|
70
|
+
// A lowercase word run straight into a capitalized one: "glanceWhat". A
|
|
71
|
+
// camelCase name starts with a capital ("JavaScript", "DataDome") and never matches.
|
|
72
|
+
const WELDED_WORDS = /\b[a-z]{2,}[A-Z][a-z]/g;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A line that is a table row or headings welded together, not a statement.
|
|
76
|
+
* extract_content reads a table one row per line, cells joined by " | " (a
|
|
77
|
+
* two-cell row has just one), and crawlforge-extractors' flattenText joins
|
|
78
|
+
* inline elements with no separator, so a table of contents of `<a class="block">` links came back as "The six
|
|
79
|
+
* vendors at a glanceWhat the independent benchmarks showWhy your approach…"
|
|
80
|
+
* (R25 re-check, 2026-10-19). A sentence ends in punctuation; welded headings
|
|
81
|
+
* have none.
|
|
82
|
+
*
|
|
83
|
+
* @param {string} line
|
|
84
|
+
* @returns {boolean}
|
|
85
|
+
*/
|
|
86
|
+
function isPageFragment(line) {
|
|
87
|
+
if (/\s\|\s/.test(line) || (line.match(/\|/g) || []).length >= 2) return true;
|
|
88
|
+
return line.length <= 300 && !/[.!?](?:\s|$)/.test(line) &&
|
|
89
|
+
(line.match(WELDED_WORDS) || []).length >= 2;
|
|
90
|
+
}
|
|
70
91
|
|
|
71
92
|
/**
|
|
72
93
|
* The statements in one extracted key point. A key point is a sentence as the
|
|
@@ -74,18 +95,25 @@ const LIST_MARKER = /^(?:[-*\u2022\u25AA\u2013]|\d{1,2}[.)])\s+/;
|
|
|
74
95
|
* string ("Built-in encryption\nQUIC was built with security in mind.").
|
|
75
96
|
* Each line becomes its own statement, except a line starting in lowercase,
|
|
76
97
|
* which continues the one before it (wrapped text). List and citation markers
|
|
77
|
-
* are removed.
|
|
98
|
+
* are removed. Table rows and welded headings are dropped; heading-only lines
|
|
99
|
+
* are left for isAdmissibleClaim to reject.
|
|
78
100
|
*
|
|
79
101
|
* @param {string} point
|
|
80
102
|
* @returns {string[]}
|
|
81
103
|
*/
|
|
82
104
|
export function claimStatements(point) {
|
|
83
105
|
const blocks = [];
|
|
106
|
+
let afterFragment = false;
|
|
84
107
|
for (const raw of String(point).split('\n')) {
|
|
85
108
|
const line = raw.trim();
|
|
86
109
|
if (!line) continue;
|
|
87
|
-
if (
|
|
110
|
+
if (isPageFragment(line)) {
|
|
111
|
+
afterFragment = true;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (blocks.length > 0 && !afterFragment && /^[a-z]/.test(line)) blocks[blocks.length - 1] += ` ${line}`;
|
|
88
115
|
else blocks.push(line);
|
|
116
|
+
afterFragment = false;
|
|
89
117
|
}
|
|
90
118
|
return blocks
|
|
91
119
|
.map(block => block.replace(LIST_MARKER, '').replace(CITATION_MARKER, '').replace(/\s+/g, ' ').trim())
|
|
@@ -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: 6.22.
|
|
5
|
+
version: 6.22.2
|
|
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: 6.22.
|
|
5
|
+
version: 6.22.2
|
|
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: 6.22.
|
|
5
|
+
version: 6.22.2
|
|
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: 6.22.
|
|
5
|
+
version: 6.22.2
|
|
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: 6.22.
|
|
5
|
+
version: 6.22.2
|
|
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: 6.22.
|
|
5
|
+
version: 6.22.2
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -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: 6.22.
|
|
5
|
+
version: 6.22.2
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: crawlforge-web-scraping
|
|
3
3
|
description: "Scrapes web pages and returns clean Markdown, HTML, plain text, links, or metadata using CrawlForge's scrape, fetch_url, extract_content, extract_text, extract_links, extract_metadata, map_site, and crawl_deep tools. Use when the user wants to scrape a URL, fetch a page, get the markdown or text of a website, extract links or metadata, read an article, map a site's URLs, generate a sitemap, or crawl a whole website or documentation site. Prefer the unified scrape tool to get multiple formats in one call; use map_site to discover URLs and crawl_deep to walk an entire site."
|
|
4
4
|
metadata:
|
|
5
|
-
version: 6.22.
|
|
5
|
+
version: 6.22.2
|
|
6
6
|
source: crawlforge-mcp-server
|
|
7
7
|
---
|
|
8
8
|
|