Skip to main content
Glama
mysleekdesigns

CrawlForge MCP Server

crawl_deep

Read-only

Fetch many pages of one site by following links for knowledge bases, docs indexes, or full-site audits. Not for single pages or known URL lists.

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_countNoURLs that failed; one entry each in errors[]
pages_foundNoSame as pages_crawled; kept for existing clients
total_charsNoLength of the full view in characters
link_analysisNo
pages_crawledNoPages fetched and returned in results
result_handleNoHandle for read_result; the full result is kept 1 hour
site_structureNo
pages_attemptedNoURLs the crawl tried: pages_crawled + error_count
pages_per_secondNo
domain_filter_configNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changedv6.18.1
    • addedOutput schema / properties / error_count / description
      Added value: +"URLs that failed; one entry each in errors[]"
    • addedOutput schema / properties / pages_attempted
      Added value: +{
      +  "description": "URLs the crawl tried: pages_crawled + error_count",
      +  "type": "number"
      +}
    • addedOutput schema / properties / pages_crawled / description
      Added value: +"Pages fetched and returned in results"
    • addedOutput schema / properties / pages_found / description
      Added value: +"Same as pages_crawled; kept for existing clients"
    • addedOutput schema / properties / site_structure / properties / total_pages / description
      Added value: +"Equals pages_crawled; failed URLs are not counted"
  2. 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"
      +  ]
      +}
  3. 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"
      +}
  4. 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"
      +}
  5. 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"
      +}
  6. First observedv4.10.0

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, openWorldHint=true, destructiveHint=false, so safety is covered. The description adds genuinely new behavioral context: the credit cost model (4 credits base, scaling with page count) and the relative cheapness of map_site. It does not discuss crawling rate limits, politeness delays, or partial-failure behavior, which would push it to a 5.

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?

Two tight sentences plus a compact example call. The alternative routing is front-loaded and every clause earns its place; no filler or restatement of the tool name.

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?

For a 17-param crawling tool with an output schema and rich annotations, the description covers purpose, alternatives, and cost, which is the core decision surface. It omits guidance on budget-related knobs (max_inline_chars/result_handle flow, redact_pii) and session/login workflows, so it is not fully complete despite the strong routing.

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 already documents all 17 parameters. The description only illustrates three params (url, max_depth, max_pages, extract_content) inside an example, adding no semantic detail beyond what the schema carries. Baseline 3 for full schema coverage.

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?

States a specific verb+resource with scope ('fetch many pages of one site by following links') and gives concrete use cases (knowledge base, docs index, full-site audit). It explicitly names sibling tools it is not (scrape, batch_scrape, map_site), so an agent can disambiguate without opening schemas.

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?

Explicit when-to-use and when-not-to-use with named alternatives routed by condition: single page -> scrape, known URL list -> batch_scrape, discovery alone -> map_site. It even flags map_site as cheaper, giving a cost-based tie-breaker.

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