CrawlForge MCP
InicioPlaygroundCasos de usoIntegracionesPreciosDocumentaciónBlog
CrawlForge MCP v5.2.0: Shopify Product Data Without Parsing HTML
Product Updates
Volver al blog
Novedades del producto

CrawlForge MCP v5.2.0: Shopify Product Data Without Parsing HTML

C
CrawlForge Team
Equipo de Ingeniería
26 de agosto de 2026
11 min de lectura

En esta página

Respuesta rápida

CrawlForge MCP v5.2.0 is a minor release centred on product extraction. The new shopify-product template reads a store's own /products/<handle>.json rather than the rendered page, returning exact price, compare-at price, per-variant stock, options, images and tags from any Shopify storefront including custom domains. scrape_template can now fetch a JSON endpoint instead of HTML; fetch_url reports responseTime; crawl_deep reports cached and crawled_at; and Ollama finally works as an LLM provider with no cloud API key. Major fixes: amazon-product returned nulls against every current Amazon page, track_changes scored price moves by page share so monitors never fired, and scrape_with_actions carried seven Playwright defects. Tool count stays at 28, nothing breaks, and scrape_template is still 1 credit. Upgrade with npm install -g crawlforge-mcp-server@latest.

Every one of our amazon-product tests passed. The tool returned null for the price currency, null for the rating, null for every image, and the string "Brand: Amazon" where the brand should have been. Nothing was broken in CI, because the fixtures had been written to match the selectors instead of the site.

CrawlForge MCP v5.2.0 is largely a release about that. One new template, three tools that now report facts they always had, and a long run of fixes to things that were quietly wrong while their tests were green.

Table of Contents

  • What Shipped
  • The Bug That Passed Six Tests
  • Shopify Prices Without Parsing HTML
  • Templates Can Now Read an API
  • Price Monitoring That Notices Prices
  • Two Tools Report What They Always Knew
  • Browser Automation Against Real Playwright
  • Local LLMs Actually Work Now
  • One Copy of the Extractors
  • Credit Costs
  • How to Upgrade

What Shipped

ChangeToolImpact
New shopify-product templatescrape_templateExact price, compare-at price and per-variant stock from any Shopify store
Templates can read a JSON endpointscrape_templateA template can fetch structured data instead of HTML
amazon-product rebuilt from live pagesscrape_templateCurrency, rating, review count, brand and full-size images actually return
Price moves scored by magnitudetrack_changesA price monitor set up the obvious way now fires
customSelectors scopes the comparisontrack_changesSelector scoping narrows the diff instead of widening it
responseTime in the responsefetch_urlLatency checks without a second tool
cached and crawled_atcrawl_deepA replayed crawl is distinguishable from a fresh one
Ollama registered as a providerextract_structured, deep_researchLocal models work with no cloud API key
Seven Playwright defects fixedscrape_with_actionsScroll-to-element, waits, retries and recovery all run
Renderer leak closedstealth_modeThe hosted browser stops running itself out of memory

Tool count stays at 28. No schema, output-shape or credit-cost change to any existing tool — this is a drop-in upgrade. The suite is 1,122 unit tests, 1,121 passing, and MCP protocol compliance is 100% across all 28 tools.

The Bug That Passed Six Tests

amazon-product was the worst case, so it is worth being specific about how it failed.

Run against three live Amazon pages, the template returned null for currency, null for rating, null for images, null for breadcrumbs, "Brand: Amazon" for the brand and the literal string "(198,594)" for the review count. Six unit tests covered it. All six passed.

They passed because every selector they exercised — a priceCurrency meta tag, #acrPopover .a-size-base, img.a-thumbnail-image — exists nowhere on Amazon today, and the fixture HTML had been written to contain them. The tests were checking that our code agreed with itself.

The fix was to capture three real pages — a first-party device, a branded storefront and a book — and re-derive every selector from what Amazon actually serves:

  • Currency comes from the hidden add-to-cart form field, not a meta tag.
  • Rating is parsed to a number from the title attribute on #acrPopover, so you get 4.7 rather than "4.7 out of 5 stars".
  • Review count is parsed from either "(198,594)" or "198,594 global ratings" — Amazon uses both — and returns 198594.
  • Brand reduces all three byline shapes to the bare name.
  • Images drop Amazon's size token from the URL. The tokened URL is a 1 KB thumbnail; the same URL without it is the 16 KB original.

The rewritten suite has 24 tests, and 15 of them fail against the pre-fix code. That is the property the old suite lacked.

Shopify Prices Without Parsing HTML

The headline addition is a shopify-product template, and it exists because every Shopify failure we hit this cycle came from parsing the rendered page.

Shopify's Dawn theme ships every price badge in the markup unconditionally and hides the inapplicable ones with component CSS. A scraper reading the DOM sees a "Sold out" badge on a product with a hundred units in stock. Ask an LLM for a compare-at price on a product that has none and it will produce a plausible one — in our testing it invented 27.99.

So the template does not read the page. Shopify serves the same data as JSON at /products/<handle>.json, on every storefront including custom domains, and that is what it reads:

Json
{
  "tool": "scrape_template",
  "params": {
    "template": "shopify-product",
    "url": "https://shop.example.com/products/kelpie-bandana"
  }
}

You get the exact price, the compare-at price, on_sale, currency, the price range across variants, per-variant stock, options, images and tags — with no HTML parsing and no LLM anywhere in the path.

Storefronts differ in ways that only show up against real stores, and the template handles the ones we found in live captures:

  • An absent compare-at price is "" on one store and "0.00" on another. Both read as null, because both render no badge — while a genuinely free product keeps its 0.00 price.
  • Tags arrive as an array on some stores and a comma-joined string on others.
  • The endpoint carries no available flag at all. Stock is derived from inventory management, inventory policy and quantity together, and reports null rather than guessing "in stock" when the payload does not say.

Point it at a site that is not Shopify and it fails with a clear message instead of returning a row of empty fields.

Templates Can Now Read an API

shopify-product needed something the template system could not do: fetch something other than the page the caller named. Rather than let one template open its own socket — which would have put it outside the SSRF guard — TemplateRegistry gained two optional hooks.

resolveUrl(url) redirects the tool's single fetch, and extractRaw(body, url) parses a non-HTML response. The tool still owns the fetch, the guard and the timeout. When a rewrite happens, the response reports the URL that was actually read as fetchedUrl, so nothing is hidden from the caller.

HTML templates are untouched. But the door is now open for any site that publishes structured data next to its rendered page, which is most storefront platforms.

Price Monitoring That Notices Prices

track_changes had a flaw that made its main use case not work.

Change significance was purely volumetric — scored by how much of the page had changed. A price is a handful of characters, so $19.99 → $29.99 and $19.99 → $99.99 both scored "minor". With notificationThreshold defaulting to "moderate", a price monitor configured the obvious way never fired. Unscoped, the change often did not register at all.

Monetary amounts are now compared as numbers, and their relative magnitude raises significance to at least "moderate" — or "major" past 20%. Only currency-tagged numbers count, so view counters and review totals do not trip it, and thousands separators parse, so $1,299 reads as 1299. The before-and-after pair is surfaced in details.valueChanges, so you can see why a monitor fired rather than guessing.

Two more in the same tool:

customSelectors never scoped anything. It was read only inside section-level analysis, where it added hashes. Scoping a comparison therefore made it worse: on an Amazon product page, scoping to the price block took modified elements from 456 to 3,204 and the payload from 5.35 MB to 6.18 MB — and reported changes on a page whose price had not moved. Analysis now narrows the document to the matched subtrees, so hashing, similarity and diffs are all scoped together. A selector that matches nothing falls back to the whole document and says so.

structuralSimilarity reported 0 when it had not measured anything. Zero is a real score meaning the structure changed completely, so opting out of structural tracking produced the strongest possible signal that the structure had changed. It is null when not measured.

Two Tools Report What They Always Knew

fetch_url returned status, headers, body, size and content type — enough to answer "is this URL up?" and nothing that could answer "how slow is it?", despite being the raw-HTTP tool with nothing else to fall back on. It now returns responseTime.

The measurement is more careful than a stopwatch around the call. It starts after the per-host politeness throttle, so a monitor polling one host in a loop does not read its own waiting as the site being slow, and it closes after the body is fully read, so a server that answers instantly and then trickles is correctly reported as slow. Live: example.com at 96 ms, our own health endpoint at 547 ms.

crawl_deep gains cached and crawled_at. A replayed crawl used to be indistinguishable from a fresh one; crawled_at now carries when the pages were really fetched. Both are declared in the tool's output schema.

The same two fields have landed on the hosted REST API this week, so a latency check reads the same on either surface:

Bash
curl -X POST https://www.crawlforge.dev/api/v1/tools/fetch_url \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'

Browser Automation Against Real Playwright

scrape_with_actions carried seven defects, none of which its test suite could see — because its fake pages implemented whatever the executor called, including APIs Playwright does not have.

scroll toElement called scrollIntoView(), which exists on neither a handle nor a locator, so that branch threw every single time it ran. The wait action advertised enabled, disabled and stable and passed them to an API that rejects them. A per-action Promise.race shared its deadline with the work it was racing and won, replacing Playwright's real error with a bare "Action timeout" and leaking a timer per action. Clicks and keypresses did not wait on the document they replaced. A chain retry replayed against whatever the failed attempt had left behind instead of reloading. And every recovery strategy sat behind retries > 0 while the schema defaulted retries to 0, so not one of them could ever run.

The new suite drives a real Chromium against a local fixture server, and skips cleanly when no browser binary is installed.

stealth_mode had a matching problem in production rather than in tests: create_page never closed its page, leaking a Chromium renderer per call until the hosted instance ran out of memory. A wedged browser was then reused forever behind truthiness-only checks, and cleanup hung on protocol calls to the dead browser, so it could not be unwedged remotely either. v5.2.0 adds corpse detection via isConnected(), a disconnect handler, cleanup that races closes against 5-second deadlines with a SIGKILL fallback and pool recreation, and a mutex around in-flight launches.

Local LLMs Actually Work Now

LLMManager registered OpenAI and Anthropic and nothing else, both gated behind an API key. On a machine running Ollama with no cloud keys, extract_structured skipped LLM extraction entirely and quietly reported css_fallback — producing values like "$79.99$79.99" and dropping fields — while deep_research silently disabled query expansion, semantic ranking and synthesis. extract_with_llm has its own private client, which is why it kept working and masked the gap for so long.

Ollama is now a registered provider. A failed LLM call also stops reporting extraction_method: "llm" with confidence 0.9.

Model selection changed too. Routing hardcoded llama3.2. Benchmarked against three live product pages with verified ground truth, gemma3:4b scored 18/18 at 1,040 ms while llama3.2 scored 16/18 — and its failures were systematic rather than sampling noise: across five runs it invented a compare-at price all five times. Parameter count did not predict accuracy at all. The 4B model beat both a 12B and a 20B. selectOllamaModel() now picks the highest-ranked installed model, and OLLAMA_DEFAULT_MODEL still overrides it.

For hosted setups, every Ollama HTTP call now sends Authorization: Bearer when OLLAMA_API_KEY is set, so a deployment can point at Ollama Cloud or any auth-fronted instance with no OpenAI or Anthropic key at all. Unset, nothing changes.

One Copy of the Extractors

The last change in this release is structural, and it is the reason the amazon-product story could happen twice.

This server and the CrawlForge REST API each carried their own copy of the same eleven site extractors, written in two different languages, with nothing detecting divergence. It diverged twice in two days: amazon-product was repaired here and the REST copy kept returning nulls, and shopify-product existed on one side only.

There is now one implementation, published as crawlforge-extractors, which both surfaces install. TemplateRegistry is re-exported from it with an unchanged API — nothing about the scrape_template tool changes for callers. The per-template tests moved with it.

The alternative was a parity test that told us after the fact which copy was wrong. Deleting the second copy is cheaper than detecting drift in it.

Credit Costs

Nothing changed. scrape_template remains 1 credit per call regardless of which template you use, fetch_url is 1, and track_changes is 3. Failed requests are never charged.

The free plan includes 1,000 one-time credits, which is 1,000 template scrapes — enough to pull a full Shopify catalogue before deciding anything.

How to Upgrade

Bash
npm install -g crawlforge-mcp-server@latest
crawlforge --version   # 5.2.1 or newer

If your MCP client launches the server with npx, it picks up the release on the next restart. There are no breaking changes: no tool was renamed, no output shape changed, and no credit cost moved.

Update: 5.2.1 followed the same day. Two of the fixes above had reached the hosted server on release day but not the npm tarball — shopify-product was missing from the tool description an MCP client reads when it picks a template, and structuralSimilarity could not score below 0.5 because the hierarchy half of it compared an object nothing ever wrote to. Take @latest.

Want structured product data without writing a selector? Start free with 1,000 credits, then read the scrape_template API reference for the full template list and field-by-field output.

Pruébalo tú mismo — sin necesidad de registrarte

Ejecuta cualquiera de las 28 herramientas de scraping y extracción de CrawlForge en el playground y luego empieza gratis con 1,000 credits.

1,000 credits gratis • Por única vez • No se requiere tarjeta de crédito

Etiquetas

releasev5.2.0shopifyscrape_templateMCPweb scrapingchangelog

Sobre el autor

C

CrawlForge Team

Equipo de Ingeniería

Construimos el MCP server de web scraping más completo. Creamos herramientas que ayudan a los desarrolladores a extraer, analizar y transformar datos web para aplicaciones de IA.

Mantente al día con los últimos artículos

Recibe tutoriales, novedades del producto y consejos de web scraping en tu bandeja de entrada.

Sin spam. Cancela tu suscripción cuando quieras.

Ponlo en práctica

Prueba las herramientas de CrawlForge en cualquier URL — gratis, sin registro.

En esta página

Frequently Asked Questions

What is new in CrawlForge MCP v5.2.0?+

v5.2.0 adds a shopify-product template that reads a store's own /products/<handle>.json for exact prices, compare-at prices and per-variant stock; gives scrape_template the ability to fetch a JSON endpoint instead of a page; adds responseTime to fetch_url and cached/crawled_at to crawl_deep; supports remote Ollama endpoints via OLLAMA_API_KEY; and fixes a long list of defects including an amazon-product template that returned nulls against every current Amazon page, price monitoring that never fired at its default threshold, and seven Playwright defects in scrape_with_actions. Tool count stays at 28 and no existing tool changed shape or price.

Why read /products/<handle>.json instead of scraping the Shopify page?+

Because the rendered page lies about stock and price. Shopify's Dawn theme ships every price badge in the markup unconditionally and hides the inapplicable ones with CSS, so a DOM scraper reads a "Sold out" badge on a product with stock. Asking an LLM to read a compare-at price that does not exist produces an invented one. The JSON endpoint is the store's own data, served on every storefront including custom domains, so the price, the compare-at price and the per-variant inventory are exact rather than inferred.

Does upgrading to v5.2.0 break anything?+

No. No tool was renamed, no output shape changed and no credit cost moved, so it is a drop-in upgrade. The additions are new fields on existing responses — responseTime on fetch_url, cached and crawled_at on crawl_deep, fetchedUrl on scrape_template when a template redirects its own fetch. Run npm install -g crawlforge-mcp-server@latest, or restart your MCP client if it launches the server with npx.

How did the amazon-product template pass its tests while returning nulls?+

The fixtures had been written to match the selectors rather than the site. Every selector the tests exercised — a priceCurrency meta tag, #acrPopover .a-size-base, img.a-thumbnail-image — exists nowhere on Amazon today, but the fixture HTML contained them, so the tests were checking that the code agreed with itself. The template was rebuilt from captures of three live Amazon pages, and its new 24-test suite was written so that 15 of those tests fail against the pre-fix code.

Do I need an OpenAI or Anthropic key to use the LLM-backed tools?+

Not any more, if you run Ollama. LLMManager registered only OpenAI and Anthropic, both gated behind an API key, so on a machine running Ollama with no cloud keys extract_structured silently fell back to CSS extraction and deep_research quietly disabled query expansion, ranking and synthesis. Ollama is now a registered provider, model routing picks the best installed model rather than hardcoding llama3.2, and OLLAMA_API_KEY lets a hosted deployment point at Ollama Cloud or any auth-fronted instance.

What does the shopify-product template cost?+

1 credit per call, the same as every other scrape_template template, and failed requests are never charged. The free plan's 1,000 one-time credits are therefore 1,000 template scrapes. It is available over MCP, over the REST API at /api/v1/tools/scrape_template, and in the browser playground with no setup.

Artículos relacionados

CrawlForge MCP v5.2: todos los cambios en las 28 herramientas
Product Updates

CrawlForge MCP v5.2: todos los cambios en las 28 herramientas

Seis versiones en dos días, encontradas apuntando las 28 herramientas a sitios reales en vez de fiarnos de los tests. Todos los cambios de v5.2, aquí.

C
CrawlForge Team
|
26 ago
|
16m
CrawlForge MCP v5.1.0: busca en Reddit sin la API
Product Updates

CrawlForge MCP v5.1.0: busca en Reddit sin la API

reddit.com bloquea todos nuestros scrapers, así que v5.1.0 lanza reddit_search, nuestra herramienta 28: busca posts y comentarios y lee hilos completos vía archivos comunitarios. Sin API key, sin credenciales, 5 credits.

C
CrawlForge Team
|
24 ago
|
9m
CrawlForge v5.0.4: 34 arreglos probando en vivo 27 herramientas MCP
Product Updates

CrawlForge v5.0.4: 34 arreglos probando en vivo 27 herramientas MCP

Cuatro parches en un día: probamos en vivo las 27 herramientas MCP y cada subcomando de la CLI contra webs reales y arreglamos los 34 defectos encontrados.

C
CrawlForge Team
|
20 ago
|
10m

Pie de página

CrawlForge MCP

Web scraping empresarial para agentes de IA. 28 herramientas MCP especializadas diseñadas para desarrolladores modernos que crean sistemas inteligentes.

Producto

  • Funciones
  • Playground
  • Precios
  • Casos de uso
  • Integraciones
  • Alternativas
  • Registro de cambios

Recursos

  • Primeros pasos
  • Referencia de la API
  • Plantillas
  • Guías
  • Blog
  • Glosario
  • Preguntas frecuentes
  • Mapa del sitio

Desarrolladores

  • Protocolo MCP
  • Claude Desktop
  • Cursor IDE
  • LangChain
  • LlamaIndex

Empresa

  • Acerca de
  • Contacto
  • Privacidad
  • Términos
  • Uso aceptable
  • Cookies

Mantente al día

Recibe las últimas novedades sobre nuevas herramientas y funciones.

Creado con Next.js y el protocolo MCP

© 2025-2026 CrawlForge. Todos los derechos reservados.