Skip to main content
Glama
ScrapeUnblocker

ScrapeUnblocker MCP Server

Official

ScrapeUnblocker MCP server

A Model Context Protocol server that lets Claude (and any other MCP client) fetch any web page's HTML through the ScrapeUnblocker scraping API, bypassing anti-bot protection (Cloudflare, DataDome, PerimeterX, Akamai, Shape).

You bring your own API key. Nothing is shared or proxied through us.

Tools

Tool

What it does

fetch_html

Fetch the fully rendered HTML of a URL (optionally after running interactive browser steps).

list_elements

List a page's notable elements with a ready-to-use selector for each (selector discovery).

fetch_parsed

Fetch a page and return AI-parsed structured JSON.

google_search

Run a Google search and return organic results as JSON.

Browser steps (interact, then capture)

Some pages only reveal what you need after you interact with them - accept a cookie banner, click a tab, type into a search box and submit, or scroll to trigger lazy loading. Pass an optional steps array to fetch_html and those actions run in a real browser, in order, after the page loads; the resulting HTML is then returned.

Available actions:

Action

Fields

wait_for

selector, selector_type? (css/xPath/className/tagName), timeout_ms?

wait_for_text

value, timeout_ms?

wait

value (ms)

click

selector, selector_type?, timeout_ms?

type

selector, selector_type?, value, clear?, timeout_ms? (typed human-like)

select

selector, selector_type?, value, timeout_ms?

press_key

value (Enter, Tab, Escape, Backspace, Delete, Space, Arrow*, Home, End, PageUp, PageDown)

scroll

value ("bottom" or a pixel offset)

Steps are not idempotent - they run once per call. If a step fails, fetch_html returns which step failed, why, and the page HTML at that moment so you can fix the selector and retry.

List elements (discover selectors first)

list_elements loads a page and returns a JSON list of its notable elements (links, inputs, buttons, selects, ...), each with a ready-to-use selector plus tag, text and useful attributes (name, id, type, placeholder, aria_label, href, ...):

{ "url": "https://example.com", "count": 42, "elements": [ { "tag": "input", "selector": "#search", "type": "text", "placeholder": "Search", "aria_label": "Search" } ] }

The natural workflow is discover, then act: call list_elements to find the selectors you need, then pass matching steps to fetch_html to click/type/ select and capture the resulting HTML.

Related MCP server: Fetch MCP Server

Get an API key

Sign up and grab your key at app.scrapeunblocker.com. The server reads it from the SCRAPEUNBLOCKER_KEY environment variable.

Install

Claude Code

The easiest route is the official plugin, which installs this server for you, prompts for your API key (stored in your OS keychain rather than an environment variable), and adds a /scrape-url command plus reference skills:

/plugin marketplace add ScrapeUnblocker/claude-code-plugin
/plugin install scrapeunblocker@scrapeunblocker

See ScrapeUnblocker/claude-code-plugin.

To add the bare server instead:

claude mcp add scrapeunblocker \
  --env SCRAPEUNBLOCKER_KEY=your_api_key_here \
  -- npx -y scrapeunblocker-mcp

Claude Desktop

Add this to your claude_desktop_config.json (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "scrapeunblocker": {
      "command": "npx",
      "args": ["-y", "scrapeunblocker-mcp"],
      "env": {
        "SCRAPEUNBLOCKER_KEY": "your_api_key_here"
      }
    }
  }
}

Restart Claude Desktop and the ScrapeUnblocker tools appear.

Any other MCP client

Run the server over stdio:

SCRAPEUNBLOCKER_KEY=your_api_key_here npx -y scrapeunblocker-mcp

Example prompts

  • "Fetch the HTML of https://www.example-shop.com/product/123 and list the price."

  • "This page keeps blocking me: . Use fetch_html to get it."

  • "List the elements on , then use fetch_html steps to type 'laptop' into the search box, press Enter, wait for the results, and give me the HTML."

  • "Search Google for 'best running shoes 2026' and give me the top 5 links."

Development

npm install
npm run build      # bundles to dist/ with tsup
npm run typecheck
SCRAPEUNBLOCKER_KEY=... node dist/index.js   # run the server

License

MIT

Available Tools

4 tools
fetch_htmlFetch page HTMLA

Fetch the fully rendered HTML of any web page through ScrapeUnblocker, bypassing anti-bot protection (Cloudflare, DataDome, PerimeterX, Akamai, Shape). Use this when a normal fetch is blocked (403/429, captcha, 'access denied') or when the page needs a real browser to render. Returns the raw HTML as text.

For pages that need interaction (accept a cookie banner, click a tab, type into a search box, scroll to trigger lazy loading) pass steps: an ordered list of browser actions run in a real browser AFTER the page loads, then the resulting HTML is returned. Workflow: first call the list_elements tool to discover the real selectors on the page, then build steps against them. Steps are NOT idempotent - they run once per call. If a step fails, this tool returns which step failed, why, and the page HTML at that moment so you can fix the selector and retry.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesThe absolute URL to fetch (http/https).
stepsNoOptional ordered browser actions to run in a real browser after the page loads, before the HTML is captured. Use `list_elements` first to find selectors. Runs once (not idempotent).
wait_valueNoThe CSS selector or JS expression paired with wait_method (e.g. '#price' or 'document.readyState==="complete"').
wait_methodNoOptional render-wait strategy: 'css' waits for a selector, 'js' waits for a JS expression to be truthy.
proxy_countryNoOptional ISO 3166-1 alpha-2 country code to route through, e.g. 'US', 'GB', 'DE'.
sleep_secondsNoExtra seconds to wait after load before capturing the HTML.
method_timeout_secondsNoCap in seconds for the render-wait method.

TDQS

A4.5/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses important behaviors: bypasses anti-bot protection, steps are not idempotent and run once per call, and failed steps return the failing step, reason, and page HTML at that moment. This is strong behavioral disclosure, though it omits potential costs, rate limits, or output size caveats.

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 dense but every sentence serves a purpose: the main behavior, the bypass value, the step workflow, the selector discovery guidance, and the failure semantics. It front-loads the core purpose and keeps related operational details together. No filler or repetition.

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 tool with no annotations and no output schema, the description is remarkably complete. It covers the main use case, the fallback trigger, step semantics, failure behavior, return format, and the recommended workflow with list_elements. The 100% schema coverage for parameters fills the remaining gaps, so nothing critical 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. The description adds meaningful semantics beyond the schema by explaining that `steps` are an ordered list run after page load, that selectors should be discovered via list_elements, and that steps are non-idempotent. Other parameters like `wait_method` and `proxy_country` are adequately covered by the schema itself.

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 and resource ('Fetch the fully rendered HTML of any web page') and immediately distinguishes itself by naming the anti-bot bypass use case. The scope is unambiguous and clearly separates it from the sibling tools like fetch_parsed and google_search.

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?

Explicitly tells the agent when to use it: when a normal fetch is blocked (403/429, captcha, 'access denied') or when a real browser is needed for rendering. It also gives a workflow for interactive pages (use list_elements first, then build steps). It doesn't explicitly name the alternative tool for parsed content or state when not to use it, but the usage context is clear.

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

fetch_parsedFetch AI-parsed page dataA

Fetch a web page through ScrapeUnblocker and return AI-parsed structured JSON instead of raw HTML (e.g. product details, article content). Best for extracting fields from product, listing or article pages without writing your own HTML parsing.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesThe absolute URL to fetch and parse.
rules_hintNoOptional natural-language hint about what to extract, to guide parsing.
proxy_countryNoOptional ISO country code to route through, e.g. 'US'.

TDQS

A3.9/5.0
Behavior3/5

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

No annotations are provided, so the description carries full responsibility for behavioral disclosure. It mentions the ScrapeUnblocker mechanism and that output is AI-parsed structured JSON, providing some transparency about the process. However, it does not disclose potential non-determinism of AI parsing, possible errors, or side effects of scraping (e.g., rate limits, target site load).

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, front-loaded with the core function, and every sentence adds value. It avoids unnecessary elaboration and is highly scannable.

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

Completeness3/5

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

With no output schema and no annotations, the description is somewhat incomplete: it doesn't describe the expected JSON structure or mention that AI-parsed output may vary in shape. It covers the main purpose and use cases, but for a tool with unstructured AI output, a note about variability or potential failure would improve completeness.

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 all parameters are already documented in the schema. The description adds context about typical extraction targets (product details, article content), which implicitly informs rules_hint, but does not add significant new meaning beyond the schema.

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 clearly states the tool's function: fetching a web page through ScrapeUnblocker and returning AI-parsed structured JSON instead of raw HTML. It specifies use cases (product details, article content), distinguishing it from the sibling fetch_html which presumably returns raw HTML.

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?

The description provides clear usage context: 'Best for extracting fields from product, listing or article pages without writing your own HTML parsing.' It implicitly contrasts with raw HTML retrieval, suggesting when not to use it, but does not explicitly name the alternate tool or exclusions beyond that.

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

list_elementsList page elements (selector discovery)A

Load a page through ScrapeUnblocker and return a JSON list of its notable elements (links, inputs, buttons, selects, etc.) with a ready-to-use selector for each, plus tag, text and useful attributes (name, id, type, placeholder, aria_label, href, ...). Read-only and does not interact with the page. This is the discovery half of interactive scraping: call list_elements to find the selectors you need, then pass matching steps to fetch_html to click/type/select and capture the resulting HTML.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesThe absolute URL whose elements you want to list.
proxy_countryNoOptional ISO country code to route through, e.g. 'US'.

TDQS

A4.4/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses the read-only nature, that it does not interact with the page, and that it loads the page through ScrapeUnblocker. It does not mention rate limits or how 'notable' elements are selected, but for a read-only discovery tool this is reasonable coverage.

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?

Three sentences with no filler: the first states core purpose and output, the second emphasizes read-only behavior, and the third gives the workflow context. All information earns its place and the most important details are front-loaded.

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?

Since there is no output schema, the description explains the return value (JSON list with selector, tag, text, attributes) sufficiently. It also connects the tool to the broader fetch_html workflow. Minor gaps such as empty results or blocked pages are not covered, but they are not essential for correct selection and invocation.

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%: url is described as 'The absolute URL whose elements you want to list' and proxy_country as 'Optional ISO country code to route through'. The tool description adds no extra parameter context, but with full schema coverage the baseline of 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 states a specific verb and resource: loads a page and returns a JSON list of notable elements with ready-to-use selectors and attributes. It also distinguishes itself from the sibling fetch_html by positioning itself as the 'discovery half of interactive scraping' and explicitly noting it is read-only.

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?

The description gives a direct usage workflow: 'call list_elements to find the selectors you need, then pass matching steps to fetch_html'. It also clarifies that the tool does not interact with the page, implying that fetch_html is for interaction, which serves as an alternative and exclusion.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 2 tool updatesv0.2.0
    • Changedfetch_html1 field changed
      • addedInput schema / properties / steps
        Added value: +{
        +  "description": "Optional ordered browser actions to run in a real browser after the page loads, before the HTML is captured. Use `list_elements` first to find selectors. Runs once (not idempotent).",
        +  "items": {
        +    "anyOf": [
        +      {
        +        "additionalProperties": false,
        +        "description": "Wait until an element matching `selector` exists.",
        +        "properties": {
        +          "action": {
        +            "const": "wait_for",
        +            "type": "string"
        +          },
        +          "selector": {
        +            "description": "Selector to wait for (until present).",
        +            "type": "string"
        +          },
        +          "selector_type": {
        +            "description": "How `selector` is interpreted. Defaults to 'css'.",
        +            "enum": [
        +              "css",
        +              "xPath",
        +              "className",
        +              "tagName"
        +            ],
        +            "type": "string"
        +          },
        +          "timeout_ms": {
        +            "exclusiveMinimum": 0,
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "action",
        +          "selector"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "description": "Wait until the given text appears on the page.",
        +        "properties": {
        +          "action": {
        +            "const": "wait_for_text",
        +            "type": "string"
        +          },
        +          "timeout_ms": {
        +            "exclusiveMinimum": 0,
        +            "type": "integer"
        +          },
        +          "value": {
        +            "description": "Text to wait for anywhere on the page.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "action",
        +          "value"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "description": "Pause for a fixed number of milliseconds.",
        +        "properties": {
        +          "action": {
        +            "const": "wait",
        +            "type": "string"
        +          },
        +          "value": {
        +            "description": "Fixed pause in milliseconds.",
        +            "minimum": 0,
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "action",
        +          "value"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "description": "Click the element matching `selector`.",
        +        "properties": {
        +          "action": {
        +            "const": "click",
        +            "type": "string"
        +          },
        +          "selector": {
        +            "description": "Selector of the element to click.",
        +            "type": "string"
        +          },
        +          "selector_type": {
        +            "$ref": "#/properties/steps/items/anyOf/0/properties/selector_type",
        +            "description": "How `selector` is interpreted. Defaults to 'css'."
        +          },
        +          "timeout_ms": {
        +            "exclusiveMinimum": 0,
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "action",
        +          "selector"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "description": "Type text into an input, character by character.",
        +        "properties": {
        +          "action": {
        +            "const": "type",
        +            "type": "string"
        +          },
        +          "clear": {
        +            "description": "Clear the field before typing.",
        +            "type": "boolean"
        +          },
        +          "selector": {
        +            "description": "Selector of the field to type into.",
        +            "type": "string"
        +          },
        +          "selector_type": {
        +            "$ref": "#/properties/steps/items/anyOf/0/properties/selector_type",
        +            "description": "How `selector` is interpreted. Defaults to 'css'."
        +          },
        +          "timeout_ms": {
        +            "exclusiveMinimum": 0,
        +            "type": "integer"
        +          },
        +          "value": {
        +            "description": "Text to type (entered human-like).",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "action",
        +          "selector",
        +          "value"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "description": "Choose an option in a <select> dropdown by value.",
        +        "properties": {
        +          "action": {
        +            "const": "select",
        +            "type": "string"
        +          },
        +          "selector": {
        +            "description": "Selector of the <select> element.",
        +            "type": "string"
        +          },
        +          "selector_type": {
        +            "$ref": "#/properties/steps/items/anyOf/0/properties/selector_type",
        +            "description": "How `selector` is interpreted. Defaults to 'css'."
        +          },
        +          "timeout_ms": {
        +            "exclusiveMinimum": 0,
        +            "type": "integer"
        +          },
        +          "value": {
        +            "description": "The option value to select.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "action",
        +          "selector",
        +          "value"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "description": "Press a single keyboard key.",
        +        "properties": {
        +          "action": {
        +            "const": "press_key",
        +            "type": "string"
        +          },
        +          "value": {
        +            "description": "The key to press.",
        +            "enum": [
        +              "Enter",
        +              "Tab",
        +              "Escape",
        +              "Backspace",
        +              "Delete",
        +              "Space",
        +              "ArrowUp",
        +              "ArrowDown",
        +              "ArrowLeft",
        +              "ArrowRight",
        +              "Home",
        +              "End",
        +              "PageUp",
        +              "PageDown"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "action",
        +          "value"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "description": "Scroll the page to the bottom or by a pixel amount.",
        +        "properties": {
        +          "action": {
        +            "const": "scroll",
        +            "type": "string"
        +          },
        +          "value": {
        +            "anyOf": [
        +              {
        +                "const": "bottom",
        +                "type": "string"
        +              },
        +              {
        +                "type": "integer"
        +              }
        +            ],
        +            "description": "'bottom' to scroll to the end, or a pixel offset."
        +          }
        +        },
        +        "required": [
        +          "action",
        +          "value"
        +        ],
        +        "type": "object"
        +      }
        +    ]
        +  },
        +  "type": "array"
        +}
    • Addedlist_elements
  2. 3 tool updatesv0.1.4
    • Addedfetch_html
    • Addedfetch_parsed
    • Addedgoogle_search
  3. 3 tool updatesv0.1.3
    • Removedfetch_html
    • Removedfetch_parsed
    • Removedgoogle_search
  4. 3 tool updatesv0.1.2
    • First observedfetch_html
    • First observedfetch_parsed
    • First observedgoogle_search

TDQS

A4.1/5.0
Disambiguation4/5

The four tools have mostly distinct purposes: fetch_html retrieves raw HTML with optional interaction, list_elements extracts selectable elements, fetch_parsed returns structured JSON, and google_search performs web searches. However, fetch_html and fetch_parsed could be confused since both fetch pages; the distinction (raw HTML vs. parsed JSON) is clear from descriptions but could still cause misselection if an agent needs structured data but picks fetch_html.

Naming Consistency4/5

Tool names follow a consistent verb_noun pattern: fetch_html, list_elements, fetch_parsed, google_search. All start with a verb (fetch, list, google) followed by a noun. Minor inconsistency: 'google_search' mixes a brand (google) with the action, but the pattern is clear and predictable.

Tool Count5/5

With 4 tools, the server is well-scoped for its purpose of scraping and unblocking web pages. Each tool serves a distinct function: fetching raw HTML, discovering elements, getting parsed data, and searching. This is a tight, purposeful set without redundancy.

Completeness3/5

The set covers the core scraping workflow: discover URLs (google_search), inspect page structure (list_elements), fetch with or without interaction (fetch_html), and extract structured data (fetch_parsed). However, there is no tool to handle common post-fetch actions like saving results or managing sessions, and no tool for custom parsing beyond fetch_parsed's AI output. The fetch_html tool includes browser steps, but there is no tool for handling cookies or persistent sessions. Still, for a minimal scraping server, the workflow is complete.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables web searching through Google, DuckDuckGo, and Bing using a headless Chrome browser, returning structured results with titles, URLs, and snippets. Also supports fetching and extracting text content from any webpage.
    13
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables LLMs to fetch and extract web content using browser automation, OCR, and multiple extraction methods, handling JavaScript rendering and anti-scraping techniques.
    17
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to fetch bot-protected web pages, run structured Google searches, and check domain authority through UnblockingAPI's anti-detection engine and residential proxies.
    3
    15
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides AI agents with reliable web fetching capabilities, handling retries, caching, and anti-bot bypass automatically.
    MIT

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/ScrapeUnblocker/scrapeunblocker-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server