Skip to main content
Glama

Scrape a URL

spicrawl_scrape

Retrieve a web page and return its content as markdown (default), text, HTML, a JSON envelope, or a printed PDF. Handles the fetch vs. browser decision, charset decoding, and PDF-to-text for you. Optionally extract structured data with CSS selectors (extract) or autoparse (a natural-language ai_extract is coming soon), return discovered links, take a screenshot, or scope the DOM with include_tags/exclude_tags. Each successful call is billed in credits (a failure costs 0). Results are cached by default, and a cache hit is billed like the fetch that stored it (the cache saves time, not credits); set cache=false for time-sensitive pages. With the defaults it only reads the page. A method other than GET, HEAD or OPTIONS, and the actions that click, fill or run scripts on the page, can change state on the target site: set them only when the user asks for that. For markdown, text and HTML it returns { content }. With format: "json", or when extract, ai_extract, autoparse, links, screenshot or network_capture is set, it returns the JSON envelope: content, the site's status, credits, engine (the rendering tier: fetch, js or browser), warnings and data for extraction. Screenshots come back as image content blocks; each screenshots entry in the JSON keeps its metadata and says which block holds it. A PDF comes back as a resource content block, with its size, the rendering tier and the credits in the JSON.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesThe absolute URL to retrieve.
modeNoRouting mode. `auto` lets the platform escalate fetch -> browser as needed, billing only the rung that worked.
waitNoMilliseconds to wait after load before capturing (render only).
cacheNoServe a recent cached result if fresh (on by default). A hit is billed at the same price as the fetch that stored it: the cache saves time, not credits. Set false only when you need live data.
linksNoAlso return the page's discovered links as an absolute, de-duplicated list.
proxyNoYour own proxy URL to egress through. Takes precedence over the pool; no surcharge.
formatNoOutput format. 'markdown' (default) is best for feeding to an LLM; 'html' returns the raw document; 'json' returns a structured envelope; 'pdf' prints the page in a full browser (routed there for you) and returns the file as a resource content block.markdown
methodNoHTTP method sent to the target (default GET; no request body can be sent). Anything but GET, HEAD or OPTIONS can change state on the target site: use it only when the user asks.
renderNoRender with a real browser (executes JavaScript). Use for single-page apps or pages whose content is painted client-side. Costs more than the default fetch tier.
actionsNoBrowser steps run in order before capture (render only). Each step is {type, ...fields}. Examples: [{"type":"click","selector":"#load-more"},{"type":"wait_for","selector":".item:nth-child(20)","timeout_ms":5000}] · infinite scroll: [{"type":"scroll","to_bottom":true},{"type":"wait_for","ms":1000}] · login: [{"type":"fill","selector":"#user","value":"me"},{"type":"fill","selector":"#pass","value":"…","secret":true},{"type":"click","selector":"button[type=submit]","wait_for_navigation":true}]. A screenshot step switches the response to the JSON envelope (a FORMAT_COERCED warning says so).
extractNoSelector-based extraction: a map of field -> CSS/XPath selector, e.g. {"title":"h1","price":".amount"}. Returns structured `data`. Precise and cheap when you know the page structure.
stealthNoComing soon: not available yet, do not send. Stealth mode: render in a full browser hardened against bot detection. Default false.
max_costNoRefuse (rather than run) a request that would cost more than this many credits.
wait_forNoCSS selector to wait for before capturing (render only).
autoparseNoReturn the structured data the page publishes about itself (JSON-LD, OpenGraph, Twitter Card, microdata). No selectors; survives redesigns.
cache_ttlNoMax age in seconds of a cached copy to accept (0 forces a fresh fetch; capped at 48h). Freshness only: a hit is billed like a fetch.
parse_pdfNoTurn a PDF target into text/markdown (default true). false refuses PDFs.
ai_extractNoComing soon: not available yet, do not send. Model-driven extraction: describe what you want and let a model find it, no selectors. Refused with ERR::INTERNAL::UNAVAILABLE until it launches; use `extract` or `autoparse`.
screenshotNoCapture a screenshot (requires render).
session_idNoRun inside a session from spicrawl_session_create: same exit IP and browser state (cookies, localStorage) across calls.
sticky_keyNoComing soon: not available yet, do not send. Reuse the same managed-pool exit for every request carrying this key, without a session.
impersonateNoFetch tier only: present a real browser's TLS/JA3 + HTTP/2 fingerprint to clear passive bot gates. On by default; set false to send a plain client handshake.
exclude_tagsNoCSS selectors to remove (e.g. ['nav','.ad','#cookie']).
include_tagsNoCSS selectors to KEEP (everything else is dropped).
proxy_verifyNoVerify `proxy` is reachable before using it.
premium_proxyNoComing soon: not available yet, do not send. Use a residential exit from Spicrawl's managed pool instead of datacenter. Until then, pass your own `proxy`.
proxy_countryNoComing soon: not available yet, do not send. ISO-3166 alpha-2 country for a managed-pool exit, lowercase (e.g. 'us', 'de').
custom_headersNoExtra request headers sent to the target, e.g. {"Accept-Language":"de"}.
extract_presetNoComing soon: not available yet, do not send. A named extraction preset instead of an inline `extract` map; any value fails today. Put the rules in `extract`.
block_resourcesNoResource types the browser should not load, e.g. ["fonts","media","images"] (render only). Faster and cheaper.
network_captureNoRecord the API responses the PAGE fetched while rendering — often cleaner JSON than the DOM. Render only.
original_statusNoReturn the target's own HTTP status instead of 200 for a successful scrape.
wait_for_timeoutNoMax milliseconds to wait for `wait_for`.
main_content_onlyNoStrip the page to its main article, dropping nav/footer/aside. Defaults on for markdown.
screenshot_formatNoScreenshot image format.
screenshot_qualityNoScreenshot quality 1-100 (lossy formats).
screenshot_fullpageNoCapture the whole page, not just the viewport.
screenshot_selectorNoCapture only the element matching this CSS selector.
allowed_status_codesNoTarget statuses to treat as success instead of an error (e.g. [404] to capture a not-found page).

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
pdfNoPresent for format=pdf: the file itself is a resource content block.
urlNoThe requested URL.
dataNoOutput of `extract` or `autoparse`.
linksNoThe page's links, absolute and de-duplicated, when `links` was set.
engineNoRendering tier that produced the page: fetch, js or browser.
statusNoThe target site's HTTP status (not this call's). Anything but 200/404/410 is charged 0.
contentNoThe page in the requested format (markdown, text or html); absent for a PDF.
creditsNoCredits charged for this call.
headersNoThe target's response headers.
networkNoResponses the page fetched, when `network_capture` was set.
warningsNoAdvisories about the call, e.g. an ignored option.
final_urlNoURL after redirects; may be empty.
truncatedNoThe target body exceeded the size cap and was cut.
diagnosticsNoWhich rendering tiers were tried, after an escalation.
screenshotsNoMetadata of each screenshot; the images are separate image content blocks.
empty_fieldsNo`extract` rules that matched nothing: usually a broken selector.
proxy_sourceNoWhose exit carried the request: pool, custom or direct.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": true,
      +  "properties": {
      +    "content": {
      +      "description": "The page in the requested format (markdown, text or html); absent for a PDF.",
      +      "type": "string"
      +    },
      +    "credits": {
      +      "description": "Credits charged for this call.",
      +      "type": "number"
      +    },
      +    "data": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": {},
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "Output of `extract` or `autoparse`."
      +    },
      +    "diagnostics": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": {},
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "Which rendering tiers were tried, after an escalation."
      +    },
      +    "empty_fields": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "`extract` rules that matched nothing: usually a broken selector."
      +    },
      +    "engine": {
      +      "description": "Rendering tier that produced the page: fetch, js or browser.",
      +      "type": "string"
      +    },
      +    "final_url": {
      +      "description": "URL after redirects; may be empty.",
      +      "type": "string"
      +    },
      +    "headers": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "The target's response headers."
      +    },
      +    "links": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "The page's links, absolute and de-duplicated, when `links` was set."
      +    },
      +    "network": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "additionalProperties": {},
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "Responses the page fetched, when `network_capture` was set."
      +    },
      +    "pdf": {
      +      "additionalProperties": true,
      +      "description": "Present for format=pdf: the file itself is a resource content block.",
      +      "properties": {
      +        "attached_as": {
      +          "description": "Which resource content block holds the PDF.",
      +          "type": "string"
      +        },
      +        "content_type": {
      +          "type": "string"
      +        },
      +        "not_attached": {
      +          "description": "Why the PDF is not attached, and how to get it.",
      +          "type": "string"
      +        },
      +        "size_bytes": {
      +          "type": "number"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "proxy_source": {
      +      "description": "Whose exit carried the request: pool, custom or direct.",
      +      "type": "string"
      +    },
      +    "screenshots": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "additionalProperties": true,
      +            "properties": {
      +              "attached_as": {
      +                "description": "Which image content block holds this screenshot.",
      +                "type": "string"
      +              },
      +              "format": {
      +                "type": "string"
      +              },
      +              "height": {
      +                "type": "number"
      +              },
      +              "label": {
      +                "type": "string"
      +              },
      +              "not_attached": {
      +                "description": "Why the image is not attached, and how to get it.",
      +                "type": "string"
      +              },
      +              "size_bytes": {
      +                "type": "number"
      +              },
      +              "width": {
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "Metadata of each screenshot; the images are separate image content blocks."
      +    },
      +    "status": {
      +      "description": "The target site's HTTP status (not this call's). Anything but 200/404/410 is charged 0.",
      +      "type": "number"
      +    },
      +    "truncated": {
      +      "description": "The target body exceeded the size cap and was cut.",
      +      "type": "boolean"
      +    },
      +    "url": {
      +      "description": "The requested URL.",
      +      "type": "string"
      +    },
      +    "warnings": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "Advisories about the call, e.g. an ignored option."
      +    }
      +  },
      +  "type": "object"
      +}
  2. Changed4 schema fields changed
    • removedInput schema / properties / engine
      Removed value: -{
      -  "description": "Pin the execution engine instead of letting the router choose. A pinned engine the deployment does not run is refused (ERR::ENGINE::UNAVAILABLE), never substituted. `camoufox` is coming soon: do not pin it yet.",
      -  "enum": [
      -    "fetch",
      -    "obscura",
      -    "chromium",
      -    "camoufox"
      -  ],
      -  "type": "string"
      -}
    • changedInput schema / properties / format / description
      Previous value: -"Output format. 'markdown' (default) is best for feeding to an LLM; 'html' returns the raw document; 'json' returns a structured envelope; 'pdf' prints the page in a browser and returns the file as a resource content block (needs `render` or `engine: \"chromium\"`)."New value: +"Output format. 'markdown' (default) is best for feeding to an LLM; 'html' returns the raw document; 'json' returns a structured envelope; 'pdf' prints the page in a full browser (routed there for you) and returns the file as a resource content block."
    • removedInput schema / properties / headless
      Removed value: -{
      -  "description": "false runs Chromium on a real display (1920x1080 screen). chromium engine only.",
      -  "type": "boolean"
      -}
    • changedInput schema / properties / stealth / description
      Previous value: -"Coming soon: not available yet, do not send. Stealth mode: render in the hardened Camoufox browser. Default false."New value: +"Coming soon: not available yet, do not send. Stealth mode: render in a full browser hardened against bot detection. Default false."
  3. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Goes well beyond the annotations: credits billing per successful call with failures free, cache-hit billing parity (cache saves time, not credits), the warning that non-GET methods and click/fill/script actions can mutate the target site, and the tier escalation behavior. The annotations only say readOnly=false, openWorld=true, destructive=false, idempotent=false; the description explains why those are true and what the practical consequences are.

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

Conciseness4/5

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

Front-loads purpose, then options, then billing, then safety, then return shapes, so an agent can stop reading early. It is dense and long (heavy parentheticals), but with 39 parameters and several cross-cutting behaviors almost every clause carries non-redundant information.

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

Completeness5/5

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

For a highly complex open-world tool, the description covers cost model, caching semantics, state-change risk, format-dependent return shapes, screenshot/PDF content blocks, and the JSON envelope fields. Even with an output schema present, nothing an agent needs to invoke it safely is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter semantics the schema does not state as a whole: 'With format: json, or when extract, ai_extract, autoparse, links, screenshot or network_capture is set, it returns the JSON envelope.' It also flags unavailable parameters (ai_extract) and clarifies defaults, which helps an agent pick among the 39 options.

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?

Opens with a specific verb and resource ('Retrieve a web page and return its content as markdown (default), text, HTML, a JSON envelope, or a printed PDF'), and the enumeration of output formats plus the fetch/browser handling makes it unmistakably the general-purpose single-URL scraper among its batch/session/usage siblings.

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

Usage Guidelines4/5

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

Gives concrete usage conditions: 'set `cache=false` for time-sensitive pages', 'set them only when the user asks for that' for state-changing methods and actions, and 'With the defaults it only reads the page.' It does not route the agent to siblings (e.g. batch_submit for multiple URLs), but within the tool the when-to-use guidance is explicit.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources