Skip to main content
Glama
mysleekdesigns

CrawlForge MCP Server

scrape_with_actions

Read-only

Interact with a page before scraping to handle logins, clicks, forms, and dynamic content, enabling data extraction from SPAs and login-gated sites.

Instructions

Use this when you must interact with a page before scraping - login, click buttons, fill forms, scroll, or wait for dynamic content to load - for SPAs, login-gated content, or multi-step flows. Actions: snapshot, wait, click, type, press, scroll, screenshot, executeJavaScript (disabled unless the server runs with ALLOW_JAVASCRIPT_EXECUTION=true; refused on the hosted API), select (dropdowns), hover, navigate. Start a chain with {type:"snapshot"} to list the page's interactive elements, including those in open shadow roots and iframes, with stable refs (@e1, @e2 ... in document order), then target those refs in later actions instead of guessing CSS selectors; navigation invalidates refs, so snapshot again after one. Set browserOptions.consent:"reject" (or "accept") to answer a cookie/consent banner before the first action; it is off by default. Set browserOptions.stealth:true to run the chain in the stealth browser, and browserOptions.engine to pick its engine ("auto" by default - camoufox when it is installed, Chromium otherwise, and the result says which ran). robots.txt is respected on every navigation, and each navigation is checked: a bot wall is reported as blocked with the vendor named, per navigation in navigations and for the final page at the top level. A click or form submit that loads another page is a navigation too: it gets its own navigations entry (trigger names the action type), and finalUrl is where the chain ended. browserOptions.proxyRotation routes a stealth chain through your own proxies. Screenshots are taken by {type:"screenshot"} actions (and on error) and stored as crawlforge://screenshot/{actionId} resources. Not for pages that render without interaction (scrape) and not as the first attempt on a blocked site (stealth_mode operation:"scrape"). Cost: 5 credits. Example: scrape_with_actions({url: "https://app.com/dashboard", actions: [{type:"snapshot"},{type:"type",selector:"@e2",text:"user@a.com"},{type:"click",selector:"@e4"}]})

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesThe URL to scrape
actionsYesBrowser actions to perform before scraping
formatsNoOutput formats for scraped content. For an image, add a {type:"screenshot"} action where you want it taken.
maxRetriesNoWhole-chain retries on failure (0-3). A retry re-navigates to the starting URL and replays every action; each attempt is reported under attempts[].
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
formAutoFillNoForm auto-fill configuration
browserOptionsNoBrowser configuration options
respect_robotsNoRespect the target site's robots.txt (default: true). Setting this to false is honoured, returns a warning in the response, and is recorded against your API key — it is your decision, not a silent default.
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)
extractionOptionsNoContent extraction options. selectors results are returned as content.json.extracted, so include "json" in formats when passing selectors — without it the extraction is not part of the response.
screenshotOnErrorNoCapture screenshot when an error occurs
continueOnActionErrorNoContinue executing actions if one fails
captureIntermediateStatesNoCapture page state after each action: intermediateStates[] gets one entry per action (capturePoint is the action's 1-based position) with the url, title and the requested formats at that point

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv6.18.1
    • addedInput schema / properties / browserOptions / properties / proxyRotation
      Added value: +{
      +  "description": "Route a stealth chain through your own proxies; requires stealth:true and the Chromium engine, and is refused without stealth or on camoufox (including \"auto\" when it resolves to camoufox), which shares one launch-time proxy across calls. Each entry is a proxy URL — \"http://user:pass@host:port\" (percent-encode a password containing @ : or /), or a bare \"host:port\" for an unauthenticated HTTP proxy; http, https, socks4 and socks5 are accepted. rotationInterval is the minimum ms on one proxy before the list advances. A proxy on a loopback, link-local or cloud-metadata address is refused, and credentials are removed from the result. Cloudflare scores the IP before it serves a challenge, so a residential proxy is what gets past a block that no fingerprint fixes. CrawlForge supplies no proxies.",
      +  "properties": {
      +    "enabled": {
      +      "default": false,
      +      "type": "boolean"
      +    },
      +    "proxies": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "rotationInterval": {
      +      "default": 300000,
      +      "type": "number"
      +    }
      +  },
      +  "type": "object"
      +}
    • changedInput schema / properties / captureIntermediateStates / description
      Previous value: -"Capture page state after each action"New value: +"Capture page state after each action: intermediateStates[] gets one entry per action (capturePoint is the action's 1-based position) with the url, title and the requested formats at that point"
    • removedInput schema / properties / captureScreenshots
      Removed value: -{
      -  "default": true,
      -  "description": "Take screenshots during action execution",
      -  "type": "boolean"
      -}
    • addedInput schema / properties / formAutoFill / properties / fields / items / properties / type / description
      Added value: +"How the field is filled: text types the value, select picks the option by value or label, checkbox/radio check the input (a selector matching a group checks the member whose value attribute equals value; a checkbox with value \"false\" is unchecked). file is not supported and fails that action"
    • changedInput schema / properties / formats / description
      Previous value: -"Output formats for scraped content"New value: +"Output formats for scraped content. For an image, add a {type:\"screenshot\"} action where you want it taken."
    • changedInput schema / properties / formats / items / enum
      Previous value: -[
      -  "markdown",
      -  "html",
      -  "json",
      -  "text",
      -  "screenshots"
      -]New value: +[
      +  "markdown",
      +  "html",
      +  "json",
      +  "text"
      +]
  2. Changed5 schema fields changedv6.14.0
    • changedInput schema / properties / actions / items / properties / selector / description
      Previous value: -"A CSS selector, or a @e1 ref from an earlier snapshot action in this chain"New value: +"A CSS selector, or a ref from an earlier snapshot action in this chain (@e1, including elements inside shadow roots and iframes)"
    • addedInput schema / properties / actions / items / properties / type / description
      Added value: +"executeJavaScript is disabled unless the server runs with ALLOW_JAVASCRIPT_EXECUTION=true; on the hosted API it is refused."
    • addedInput schema / properties / browserOptions / properties / consent
      Added value: +{
      +  "default": "off",
      +  "description": "Cookie/consent banner handling, using DuckDuckGo autoconsent's rules for known consent platforms (OneTrust, Sourcepoint, Didomi ...). \"reject\" declines non-essential cookies and \"accept\" accepts them, once after the initial page load and again after each navigate action, for at most 2s each; the result's `consent` ({cmp, action, ms}) and each navigate result say what was found and done. A banner no rule matches is left in place (action \"none\") and never fails the chain. Default \"off\": the page is left as it loads, so a chain that clicks the banner itself works unchanged.",
      +  "enum": [
      +    "off",
      +    "reject",
      +    "accept"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / maxRetries / default
      Previous value: -1New value: +0
    • changedInput schema / properties / maxRetries / description
      Previous value: -"Maximum retry attempts on failure"New value: +"Whole-chain retries on failure (0-3). A retry re-navigates to the starting URL and replays every action; each attempt is reported under attempts[]."
  3. Changed1 schema field changedv6.8.0
    • addedInput schema / properties / browserOptions / properties / engine
      Added value: +{
      +  "default": "auto",
      +  "description": "Stealth engine for the chain, with stealth:true. \"auto\" (default) runs camoufox when it is installed and Chromium otherwise; the result's `engine` says which ran. \"camoufox\" is Firefox-based with a higher anti-detect score; \"chromium\" (= \"playwright\") forces Chromium. Refused without stealth:true, where the browser is always Chromium.",
      +  "enum": [
      +    "auto",
      +    "chromium",
      +    "camoufox",
      +    "playwright"
      +  ],
      +  "type": "string"
      +}
  4. Changed4 schema fields changedv6.6.0
    • addedInput schema / properties / actions / items / properties / interactiveOnly
      Added value: +{
      +  "description": "snapshot: only interactive elements (default true)",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / actions / items / properties / maxNodes
      Added value: +{
      +  "description": "snapshot: cap on nodes listed (default 200, max 1000); the result says truncated when the cap stopped the walk",
      +  "maximum": 1000,
      +  "minimum": 1,
      +  "type": "number"
      +}
    • addedInput schema / properties / actions / items / properties / selector / description
      Added value: +"A CSS selector, or a @e1 ref from an earlier snapshot action in this chain"
    • changedInput schema / properties / actions / items / properties / type / enum
      Previous value: -[
      -  "wait",
      -  "click",
      -  "type",
      -  "press",
      -  "scroll",
      -  "screenshot",
      -  "executeJavaScript",
      -  "select",
      -  "hover",
      -  "navigate"
      -]New value: +[
      +  "snapshot",
      +  "wait",
      +  "click",
      +  "type",
      +  "press",
      +  "scroll",
      +  "screenshot",
      +  "executeJavaScript",
      +  "select",
      +  "hover",
      +  "navigate"
      +]
  5. Changed11 schema fields changedv6.0.0
    • removedInput schema / additionalProperties
      Removed value: -false
    • removedInput schema / properties / actions / items / additionalProperties
      Removed value: -false
    • addedInput schema / properties / actions / items / properties / args / items
      Added value: +{}
    • removedInput schema / properties / actions / items / properties / position / additionalProperties
      Removed value: -false
    • removedInput schema / properties / browserOptions / additionalProperties
      Removed value: -false
    • removedInput schema / properties / extractionOptions / additionalProperties
      Removed value: -false
    • addedInput schema / properties / extractionOptions / properties / selectors / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • removedInput schema / properties / formAutoFill / additionalProperties
      Removed value: -false
    • removedInput schema / properties / formAutoFill / properties / fields / items / 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"
      +}
  6. Changed1 schema field changedv5.6.6
    • changedInput schema / properties / extractionOptions / description
      Previous value: -"Content extraction options"New value: +"Content extraction options. selectors results are returned as content.json.extracted, so include \"json\" in formats when passing selectors — without it the extraction is not part of the response."
  7. Changed7 schema fields changedv5.4.0
    • changedInput schema / properties / actions / items / properties / type / enum
      Previous value: -[
      -  "wait",
      -  "click",
      -  "type",
      -  "press",
      -  "scroll",
      -  "screenshot",
      -  "executeJavaScript"
      -]New value: +[
      +  "wait",
      +  "click",
      +  "type",
      +  "press",
      +  "scroll",
      +  "screenshot",
      +  "executeJavaScript",
      +  "select",
      +  "hover",
      +  "navigate"
      +]
    • addedInput schema / properties / actions / items / properties / url
      Added value: +{
      +  "description": "navigate: URL to navigate to — goes through the same SSRF and robots.txt gate as the initial URL",
      +  "format": "uri",
      +  "type": "string"
      +}
    • addedInput schema / properties / actions / items / properties / value
      Added value: +{
      +  "description": "select: option to choose, matched by value or label",
      +  "type": "string"
      +}
    • addedInput schema / properties / actions / items / properties / values
      Added value: +{
      +  "description": "select: options to choose in a multi-select, matched by value or label",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / actions / items / properties / waitUntil
      Added value: +{
      +  "description": "navigate: when to consider navigation complete",
      +  "enum": [
      +    "load",
      +    "domcontentloaded",
      +    "networkidle",
      +    "commit"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / browserOptions / properties / stealth
      Added value: +{
      +  "default": false,
      +  "description": "Run the action chain in the stealth browser (randomized fingerprint, WebRTC/canvas spoofing) instead of the standard browser pool. Renders JavaScript; it does not solve challenges.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / respect_robots
      Added value: +{
      +  "description": "Respect the target site's robots.txt (default: true). Setting this to false is honoured, returns a warning in the response, and is recorded against your API key — it is your decision, not a silent default.",
      +  "type": "boolean"
      +}
  8. Changed3 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"
    • addedInput schema / properties / actions / items / properties / x
      Added value: +{
      +  "description": "scroll: absolute X coordinate to scroll to (window.scrollTo; with y, takes precedence over direction/distance)",
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / actions / items / properties / y
      Added value: +{
      +  "description": "scroll: absolute Y coordinate to scroll to (window.scrollTo; with x, takes precedence over direction/distance)",
      +  "minimum": 0,
      +  "type": "number"
      +}
  9. First observedv4.10.0

TDQS

A4.8/5.0
Behavior5/5

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

Beyond annotations (which only cover safety/idempotency), it discloses robots.txt enforcement, per-navigation bot-wall reporting with `blocked`/`navigations`/`finalUrl` fields, ref invalidation on navigation, consent-banner semantics, stealth engine resolution, proxy-rotation constraints, and screenshot resource storage. It also states cost (5 credits) and the executeJavaScript env-var gate, which no structured field conveys.

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?

The when-to-use clause is front-loaded and nearly every sentence carries operational value (workflow, restrictions, cost, example). It is nonetheless a single dense paragraph with no visual structure, which makes it heavier to scan than it needs to be.

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 13-parameter tool with nested objects, no output schema, and heavy side effects, the description covers the workflow, failure/blocking semantics, navigation result shape, screenshot retrieval, and a worked example. Details it omits (formAutoFill, redact_pii, max_inline_chars/read_result routing) are fully documented in the schema itself.

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 description coverage is 100%, so the schema already documents the 13 parameters and baseline is 3. The description adds procedural meaning the schema cannot: the snapshot-first workflow, stable @e1 refs in document order (including shadow roots and iframes), and that refs are invalidated by navigation so a re-snapshot is required.

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 states a specific verb and resource ('interact with a page before scraping') and enumerates the interactive capabilities (login, click, fill forms, scroll, wait). It explicitly distinguishes itself from siblings by naming what it is NOT for: 'Not for pages that render without interaction (scrape) and not as the first attempt on a blocked site (stealth_mode operation:"scrape").'

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?

It opens with an explicit when-to-use clause ('Use this when you must interact with a page before scraping... for SPAs, login-gated content, or multi-step flows') and closes with explicit when-not-to-use plus the alternative tool for each exclusion. Alternative routing is unambiguous.

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