Skip to main content
Glama
mysleekdesigns

CrawlForge MCP Server

crawl_deep

Read-only

Crawl a website by following its links to collect content from many pages, enabling knowledge base extraction, documentation indexing, and full-site audits.

Instructions

Use this to fetch many pages of one site by following links - a knowledge base, a docs index, a full-site audit. Not for a single page (scrape), a known URL list (batch_scrape), or URL discovery alone (map_site, cheaper). Cost: 4 credits base, grows with page count. Example: crawl_deep({url: "https://docs.example.com", max_depth: 3, max_pages: 200, extract_content: true})

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesStarting URL for the crawl
sessionNoShared cookie-jar/session for login-then-crawl workflows
max_depthNoMaximum crawl depth from starting URL
max_pagesNoMaximum number of pages to crawl
redact_piiNoRedact personal data from the text this call returns, before it reaches your context window. true means the free regex pass over EMAIL, PHONE, FINANCIAL and SECRET. The result carries redaction:{entities,count}. Default: off
concurrencyNoNumber of concurrent requests
domain_filterNoPer-domain allow/deny lists and crawl rules
respect_robotsNoRespect robots.txt directives
extract_contentNoExtract page content during crawl
follow_externalNoFollow links to external domains
exclude_patternsNoURL patterns to exclude (regex)
include_patternsNoURL patterns to include (regex)
max_inline_charsNoLargest result to return inline, in characters of its JSON. Over it, the call returns a preview plus a result_handle for read_result instead of the whole result (default 40,000; env CRAWLFORGE_MAX_INLINE_CHARS)
content_max_lengthNoMaximum characters of page content to include per page (default 500); sets a truncated flag when trimmed
enable_link_analysisNoCompute PageRank/link-graph analysis over crawled pages
import_filter_configNoJSON string of a previously exported domain-filter config
link_analysis_optionsNoPageRank tuning options

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlNo
viewNoWhether preview and read_result offsets index a text field or the pretty-printed JSON
_costNoCost-transparency metadata (D3.5), present when injected into the text copy of the result
errorNo
statsNo
cachedNoTrue when this response was replayed from an earlier crawl rather than crawled now; crawled_at gives its age
errorsNo
previewNoThe first max_inline_chars characters of the view named by view_path (or of the pretty-printed JSON)
resultsNo
sessionNo
successNoFalse only when the crawl was cancelled via elicitation decline
redactionNoPresent when redact_pii was set: what was redacted from the text of this result
truncatedNoTrue when the inline result is a preview
view_pathNoDotted path of the text field the view was cut from; null for the JSON view
crawled_atNoWhen the pages were actually fetched (ISO 8601)
expires_atNoWhen the stored result is dropped (ISO 8601)
crawl_depthNo
duration_msNo
error_countNo
pages_foundNo
total_charsNoLength of the full view in characters
link_analysisNo
pages_crawledNo
result_handleNoHandle for read_result; the full result is kept 1 hour
site_structureNo
pages_per_secondNo
domain_filter_configNo

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed28 schema fields changedv6.0.0
    • removedInput schema / additionalProperties
      Removed value: -false
    • removedInput schema / properties / domain_filter / additionalProperties
      Removed value: -false
    • addedInput schema / properties / domain_filter / properties / blacklist / items
      Added value: +{}
    • addedInput schema / properties / domain_filter / properties / domain_rules / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / domain_filter / properties / whitelist / items
      Added value: +{}
    • removedInput schema / properties / link_analysis_options / additionalProperties
      Removed value: -false
    • addedInput schema / properties / max_inline_chars
      Added value: +{
      +  "description": "Largest result to return inline, in characters of its JSON. Over it, the call returns a preview plus a result_handle for read_result instead of the whole result (default 40,000; env CRAWLFORGE_MAX_INLINE_CHARS)",
      +  "maximum": 10000000,
      +  "minimum": 1000,
      +  "type": "integer"
      +}
    • addedInput schema / properties / redact_pii
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "properties": {
      +        "entities": {
      +          "description": "Which classes to redact, case-insensitive: EMAIL, PHONE, FINANCIAL, SECRET, plus PERSON and LOCATION when mode is \"model\". Omitted or empty means all four regex classes (and both model classes in \"model\" mode). An unknown name, or a model-only name without mode:\"model\", is rejected",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "mode": {
      +          "description": "\"fast\" (default) is regex only and free; \"model\" adds an Ollama NER pass for PERSON and LOCATION (+3 credits once per call)",
      +          "enum": [
      +            "fast",
      +            "model"
      +          ],
      +          "type": "string"
      +        },
      +        "replace_style": {
      +          "description": "\"tag\" (default) writes <EMAIL>, \"mask\" writes [REDACTED], \"remove\" deletes the value",
      +          "enum": [
      +            "tag",
      +            "mask",
      +            "remove"
      +          ],
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    }
      +  ],
      +  "description": "Redact personal data from the text this call returns, before it reaches your context window. true means the free regex pass over EMAIL, PHONE, FINANCIAL and SECRET. The result carries redaction:{entities,count}. Default: off"
      +}
    • removedInput schema / properties / session / additionalProperties
      Removed value: -false
    • addedInput schema / properties / session / properties / headers / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • removedInput schema / properties / session / properties / initialRequest / additionalProperties
      Removed value: -false
    • addedInput schema / properties / session / properties / initialRequest / properties / headers / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • changedOutput schema / properties / _cost / additionalProperties
      Previous value: -trueNew value: +{}
    • addedOutput schema / properties / expires_at
      Added value: +{
      +  "description": "When the stored result is dropped (ISO 8601)",
      +  "type": "string"
      +}
    • addedOutput schema / properties / preview
      Added value: +{
      +  "description": "The first max_inline_chars characters of the view named by view_path (or of the pretty-printed JSON)",
      +  "type": "string"
      +}
    • addedOutput schema / properties / redaction
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when redact_pii was set: what was redacted from the text of this result",
      +  "properties": {
      +    "count": {
      +      "description": "Total spans replaced",
      +      "type": "number"
      +    },
      +    "entities": {
      +      "additionalProperties": {
      +        "type": "number"
      +      },
      +      "description": "How many spans were replaced, by entity class; a class with no hits is omitted",
      +      "propertyNames": {
      +        "type": "string"
      +      },
      +      "type": "object"
      +    },
      +    "mode": {
      +      "description": "\"fast\" is the free regex pass; \"model\" added an Ollama NER pass for PERSON and LOCATION",
      +      "enum": [
      +        "fast",
      +        "model"
      +      ],
      +      "type": "string"
      +    },
      +    "model_ran": {
      +      "description": "mode \"model\" only: whether a model actually answered. False means no LLM route existed and the model surcharge was not charged",
      +      "type": "boolean"
      +    }
      +  },
      +  "type": "object"
      +}
    • addedOutput schema / properties / result_handle
      Added value: +{
      +  "description": "Handle for read_result; the full result is kept 1 hour",
      +  "type": "string"
      +}
    • changedOutput schema / properties / results / items / additionalProperties
      Previous value: -trueNew value: +{}
    • changedOutput schema / properties / session / additionalProperties
      Previous value: -trueNew value: +{}
    • changedOutput schema / properties / site_structure / additionalProperties
      Previous value: -trueNew value: +{}
    • addedOutput schema / properties / site_structure / properties / depth_distribution / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / site_structure / properties / file_types / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / site_structure / properties / path_depth_distribution / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / site_structure / properties / path_patterns / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / total_chars
      Added value: +{
      +  "description": "Length of the full view in characters",
      +  "type": "number"
      +}
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when the inline result is a preview",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / view
      Added value: +{
      +  "description": "Whether preview and read_result offsets index a text field or the pretty-printed JSON",
      +  "enum": [
      +    "text",
      +    "json"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / view_path
      Added value: +{
      +  "description": "Dotted path of the text field the view was cut from; null for the JSON view",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  2. Changed2 schema fields changedv5.4.0
    • addedOutput schema / properties / site_structure / properties / depth_distribution / description
      Added value: +"Pages per crawl depth (links from the start URL)"
    • addedOutput schema / properties / site_structure / properties / path_depth_distribution
      Added value: +{
      +  "additionalProperties": {
      +    "type": "number"
      +  },
      +  "description": "Pages per URL path-segment depth",
      +  "type": "object"
      +}
  3. Changed2 schema fields changedv5.1.0
    • addedOutput schema / properties / cached
      Added value: +{
      +  "description": "True when this response was replayed from an earlier crawl rather than crawled now; crawled_at gives its age",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / crawled_at
      Added value: +{
      +  "description": "When the pages were actually fetched (ISO 8601)",
      +  "type": "string"
      +}
  4. Changed2 schema fields changedv5.0.4
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "https://json-schema.org/draft/2020-12/schema",
      +  "additionalProperties": false,
      +  "properties": {
      +    "_cost": {
      +      "additionalProperties": true,
      +      "description": "Cost-transparency metadata (D3.5), present when injected into the text copy of the result",
      +      "properties": {
      +        "actual": {
      +          "description": "Credits actually charged (0 in creator mode, half-rate on error)",
      +          "type": "number"
      +        },
      +        "projected": {
      +          "description": "Credits projected for this call before execution",
      +          "type": "number"
      +        },
      +        "projection_note": {
      +          "description": "Human-readable note about how the cost was projected",
      +          "type": "string"
      +        },
      +        "remaining_credits": {
      +          "description": "Credits remaining on the account after this call, if known",
      +          "type": [
      +            "number",
      +            "null"
      +          ]
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "crawl_depth": {
      +      "type": "number"
      +    },
      +    "domain_filter_config": {
      +      "anyOf": [
      +        {},
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "duration_ms": {
      +      "type": "number"
      +    },
      +    "error": {
      +      "type": "string"
      +    },
      +    "error_count": {
      +      "type": "number"
      +    },
      +    "errors": {
      +      "items": {},
      +      "type": "array"
      +    },
      +    "link_analysis": {
      +      "anyOf": [
      +        {},
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "pages_crawled": {
      +      "type": "number"
      +    },
      +    "pages_found": {
      +      "type": "number"
      +    },
      +    "pages_per_second": {
      +      "type": "number"
      +    },
      +    "results": {
      +      "items": {
      +        "additionalProperties": true,
      +        "properties": {
      +          "content": {
      +            "type": "string"
      +          },
      +          "content_length": {
      +            "type": "number"
      +          },
      +          "depth": {
      +            "type": "number"
      +          },
      +          "links_count": {
      +            "type": "number"
      +          },
      +          "metadata": {},
      +          "timestamp": {
      +            "type": [
      +              "string",
      +              "number"
      +            ]
      +          },
      +          "title": {
      +            "type": "string"
      +          },
      +          "truncated": {
      +            "type": "boolean"
      +          },
      +          "url": {
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "session": {
      +      "additionalProperties": true,
      +      "properties": {
      +        "cookies_captured": {
      +          "type": "number"
      +        },
      +        "enabled": {
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "site_structure": {
      +      "additionalProperties": true,
      +      "properties": {
      +        "depth_distribution": {
      +          "additionalProperties": {
      +            "type": "number"
      +          },
      +          "type": "object"
      +        },
      +        "file_types": {
      +          "additionalProperties": {
      +            "type": "number"
      +          },
      +          "type": "object"
      +        },
      +        "path_patterns": {
      +          "additionalProperties": {
      +            "type": "number"
      +          },
      +          "type": "object"
      +        },
      +        "subdomains": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "total_pages": {
      +          "type": "number"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "stats": {},
      +    "success": {
      +      "description": "False only when the crawl was cancelled via elicitation decline",
      +      "type": "boolean"
      +    },
      +    "url": {
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
  5. First observedv4.10.0

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, covering safety and variability. The description adds cost and the example, but doesn't disclose additional behavioral traits like pagination, handling of redirects, or result format (though the output schema exists). It adds some context beyond annotations, but not rich detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences plus an example, with zero fluff. The purpose is front-loaded, followed by exclusions, cost, and a clear example. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the high complexity (17 parameters, nested objects, output schema present), the description covers the essential decision-making (when to use, when not, cost, example) and relies on the schema for parameter details. It could mention that it's a heavy operation or that results may be large, but the output schema and schema descriptions fill most gaps. It is complete for an agent to decide whether to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema documents every parameter in detail. The description itself includes a concrete example using url, max_depth, max_pages, and extract_content, which reinforces usage, but doesn't add semantic meaning beyond what the schema already provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('fetch many pages by following links') and clearly distinguishes itself from sibling tools (scrape, batch_scrape, map_site) by naming what it is not for. It also gives concrete use cases (knowledge base, docs index, full-site audit), so an agent can immediately understand its scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when NOT to use it (single page, known URL list, URL discovery) and names cheaper alternatives (map_site). It also provides cost context ('4 credits base, grows with page count'), which helps the agent decide if it's the right tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Latest Blog Posts

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