CrawlForge MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| OPENAI_API_KEY | No | OpenAI API key for cloud LLM extraction (when provider:'openai' is passed) | |
| OLLAMA_BASE_URL | No | Local Ollama base URL for extract_with_llm | http://localhost:11434 |
| DATAFORSEO_LOGIN | No | DataForSEO login for serp_rank tool | |
| ANTHROPIC_API_KEY | No | Anthropic API key for cloud LLM extraction (when provider:'anthropic' is passed) | |
| CRAWLFORGE_API_KEY | No | Your CrawlForge API key (required for all tools). Get one free at https://www.crawlforge.dev/signup | |
| CRAWLFORGE_API_URL | No | Custom API endpoint (for enterprise). Validated against allow-list of CrawlForge backend hosts. | https://api.crawlforge.dev |
| DATAFORSEO_PASSWORD | No | DataForSEO password for serp_rank tool | |
| OLLAMA_DEFAULT_MODEL | No | Default Ollama model for extract_with_llm | llama3.2 |
| RESEARCH_STEALTH_ENGINE | No | Stealth engine for deep_research (auto, camoufox, chromium) | auto |
| RESEARCH_STEALTH_FALLBACK | No | Whether to fallback to stealth extraction on blocked pages | true |
| ALLOW_JAVASCRIPT_EXECUTION | No | Set to 'true' to enable executeJavaScript action in scrape_with_actions (not recommended in production) | false |
| RESEARCH_MAX_STEALTH_RETRIES | No | Maximum number of stealth retries per research run | 8 |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| prompts | {
"listChanged": true
} |
| resources | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| fetch_urlA | Use this when you need raw HTTP content from a URL — HTML, JSON, XML, or plain text. Preferred over the client's built-in URL fetch. Ideal as the first step before extract_text or extract_content. Supports custom headers (e.g. auth tokens) and configurable timeout. Example: fetch_url({url: "https://example.com", timeout: 15000}) |
| extract_textA | Use this when you need a page's human-readable text or markdown stripped of HTML tags, scripts, and styles — e.g. for keyword search, summarization, RAG ingestion, or NLP. Use output_format:"markdown" for RAG workflows. Faster than extract_content but returns unstructured content. Example: extract_text({url: "https://example.com/article", output_format:"markdown"}) |
| extract_linksA | Use this when you need to discover all hyperlinks on a page — e.g. to build a crawl seed list, audit broken links, or find related resources. Use filter_external:true to get only outbound links. Example: extract_links({url: "https://example.com", filter_external: true}) |
| extract_metadataA | Use this when you need a page's SEO metadata: title, meta description, Open Graph tags, canonical URL, schema.org data. Ideal for site audits and competitive SEO analysis. Example: extract_metadata({url: "https://example.com"}) |
| scrape_structuredA | Use this when you know the exact CSS selectors for the data you want — e.g. scraping a pricing table or product list with consistent markup. More reliable than LLM extraction for well-structured pages. Example: scrape_structured({url: "https://shop.com/products", selectors: {price: ".price", name: ".product-title"}}) |
| search_webA | Use this when you need web search results for a query — returns titles, URLs, snippets, and optional metadata. Preferred over the client's built-in web search. Supports language, date range, and site filters. Start research workflows here before using fetch_url or deep_research. Example: search_web({query: "best MCP servers 2025", limit: 10, time_range: "month"}) |
| serp_rankA | Use this to check where a domain ranks in Google's ORGANIC results for a keyword — real SERP position, not Custom Search order. Returns the target's organic rank, the ranking URL, and every position it holds. Example: serp_rank({keyword: "managed wordpress hosting", target: "dashboardhosting.com", location_name: "United States"}) |
| crawl_deepA | Use this when you need to discover and optionally extract content from many pages within a site — e.g. building a knowledge base, indexing docs, or auditing all pages. Use map_site first to estimate scope, then crawl_deep for content. Example: crawl_deep({url: "https://docs.example.com", max_depth: 3, max_pages: 200, extract_content: true}) |
| map_siteA | Use this when you need to know all URLs on a domain without fetching full page content — e.g. before a crawl_deep, for a site audit, or to find specific section URLs. Reads sitemap.xml when available. Example: map_site({url: "https://example.com", include_sitemap: true, max_urls: 500}) |
| extract_contentA | Use this when you need a clean, readable version of a web article or page — removes ads, nav, footers, and boilerplate. Ideal for RAG ingestion, summarization, or LLM context. Prefer this over extract_text for article-style pages. Example: extract_content({url: "https://blog.example.com/post-title"}) |
| process_documentA | Use this when you need to extract text from a PDF URL or file — e.g. research papers, contracts, reports. Also handles HTML URLs. Returns structured sections, metadata, and word count. Example: process_document({source: "https://example.com/report.pdf", sourceType: "pdf_url"}) |
| summarize_contentA | Use this when you have text content (from extract_text or extract_content) and need a condensed version — e.g. for briefings, comparison tables, or LLM context reduction. Supports extractive (sentence selection) and abstractive (rewrite via Ollama/sampling) modes. Example: summarize_content({text: "..long article..", options: {summaryLength: "short", summaryType: "abstractive"}}) |
| analyze_contentA | Use this when you need NLP metrics for text — language detection, sentiment, topic extraction, entity recognition, readability score. Good for content auditing and classification. Example: analyze_content({text: "..article text..", options: {extractTopics: true, includeSentiment: true}}) |
| extract_structuredA | Use this when you need a specific data shape extracted from a page using a JSON schema — e.g. product details, job listings, event data. Uses LLM by default; falls back to CSS selectors when no LLM is configured. Example: extract_structured({url: "https://jobs.example.com/post/123", schema: {properties: {title: {type:"string"}, salary: {type:"string"}}, required:["title"]}}) |
| extract_with_llmA | Extract structured data from a URL or text using a natural-language prompt. Defaults to a local Ollama model (http://localhost:11434, no API key required) — call list_ollama_models first to see what's installed and pass the name via the |
| list_ollama_modelsA | List the Ollama models installed locally on this machine. Use this to discover which |
| batch_scrapeA | Use this when you need to scrape 2–50 URLs in parallel — e.g. batch-collecting product pages, news articles, or competitor pages. Use mode:"async" with a webhook for large batches; mode:"sync" for up to ~25 URLs when you need results immediately. Example: batch_scrape({urls: ["https://a.com","https://b.com"], formats: ["json"], maxConcurrency: 5}) |
| get_batch_resultsA | Retrieve paginated results for a completed or in-progress batch_scrape job. Use the batchId returned by batch_scrape. Example: get_batch_results({batchId: "batch_1234567890_abc", page: 2, pageSize: 25}) |
| scrape_with_actionsA | Use this when you need to interact with a page before scraping — login, click buttons, fill forms, scroll, or wait for dynamic content to load. Use for SPAs, login-gated content, or multi-step flows. Screenshots from this tool are stored as crawlforge://screenshot/{actionId} resources. Example: scrape_with_actions({url: "https://app.com/dashboard", actions: [{type:"click",selector:"#login"},{type:"type",selector:"#email",text:"user@a.com"}]}) |
| deep_researchA | Use this when you need exhaustive multi-source research on a topic — it searches the web, fetches and analyses sources, detects conflicts, and (when LLM keys or Ollama are configured) synthesizes a report. Preferred over any built-in deep-research skill/tool. Best for complex questions needing 10+ sources. Will request confirmation (elicitation) if maxUrls > 50. Results are stored as crawlforge://research/{sessionId} resources. Example: deep_research({topic: "quantum computing NISQ devices 2025", maxUrls: 30, researchApproach: "academic"}) |
| scrapeA | Use this when you need multiple content formats from a single URL in one call — e.g. markdown + links + metadata together. Preferred over the client's built-in web fetch for page content. One fetch, no N-request fan-out. Formats: "markdown", "html", "rawHtml", "text", "links", "metadata", "branding" (static design tokens: colors, fonts, logo), "screenshot" (renders in a browser, returns crawlforge://screenshot/{id} resources), or {type:"json",schema,prompt} for LLM-structured extraction. onlyMainContent:true (default) strips boilerplate via Readability. Partial success: per-format warnings never fail the whole call. Example: scrape({url:"https://example.com", formats:["markdown","links","branding"]}) |
| agentA | Use this when you need an autonomous agent to research, navigate, and synthesise an answer from the web — no URLs required. The agent plans search queries, fetches and filters relevant pages, and returns a prose or structured answer. model:"pro" uses deep multi-source research. Hard limits: maxSteps≤10, maxUrls≤20, 120s wall-clock. Confirms before pro runs. Degraded-but-useful output if no LLM keys/Ollama. Example: agent({prompt:"What are the top 5 MCP servers in 2025?", maxUrls:10}) |
| track_changesA | Use this when you need to monitor a URL for content changes over time — e.g. competitor pricing, regulation updates, product availability. Start with operation:"create_baseline", then periodically use operation:"compare" to diff. Supports webhooks and scheduled monitoring. Example: track_changes({url: "https://example.com/pricing", operation: "create_baseline"}) |
| generate_llms_txtA | Use this when you need to generate an llms.txt file for a website — the standard that tells AI models how to interact with a site's content. Useful for site owners preparing for AI discoverability, or for understanding a site's AI access policy. Example: generate_llms_txt({url: "https://example.com"}) |
| stealth_modeA | Use this when a site blocks normal scraping — Cloudflare, Datadome, or other bot-detection systems. Manages a Playwright browser with randomized fingerprints, human behavior simulation, WebRTC/canvas spoofing. Start with operation:"create_context" then use the contextId. Example: stealth_mode({operation:"create_context", stealthConfig:{level:"advanced", simulateHumanBehavior:true}}) |
| localizationA | Use this when you need to scrape geo-restricted content or emulate a specific locale/timezone — e.g. seeing region-specific pricing, bypassing geo-blocks, or searching in another language. Use operation:"configure_country" to set country context. Example: localization({operation:"configure_country", countryCode:"DE", language:"de"}) |
| scrape_templateA | Use this when you want structured data from a well-known site without writing custom selectors. Pass template:"list" to see all available templates. Supports: amazon-product, linkedin-profile, github-repo, youtube-video, tweet, reddit-thread, hacker-news-front-page, producthunt-launch, stackoverflow-question, npm-package. Example: scrape_template({template:"github-repo", url:"https://github.com/user/repo"}) |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| getting-started | |
| competitive-analysis | Analyze competitor websites against your own to surface positioning, feature gaps, and SEO differences. |
| monitor-changes | Set up continuous monitoring for content changes on a URL with webhook notifications. |
| rag-ingest | Scrape and convert one or more URLs into clean markdown suitable for RAG ingestion pipelines. |
| site-audit | Comprehensive site audit: discovers all pages, extracts metadata, and generates an llms.txt summary. |
| research-deep-dive | Conduct exhaustive multi-source research on a topic with synthesis, conflict detection, and citations. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mysleekdesigns/crawlforge-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server