Superzoo MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Superzoo MCP Find Brit Care salmon oil and tell me which Bratislava stores have the 250 ml bottle."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Superzoo MCP
An unofficial, read-only Model Context Protocol server for finding Super zoo products, prices, and store availability. Supports Slovakia, Czechia, and Poland, over stdio or Streamable HTTP. No Super zoo account is required.
Strict TypeScript compiled to JavaScript. Requires Node.js 22 or newer. MIT licensed. This project is not affiliated with Super zoo or the Plaček Group.
Quick start
Clone this repository, then run:
npm ci
npm run build
npm startThe default is stdio with the Slovak shop. It waits for an MCP client rather than showing an interactive prompt.
Stdio client configuration
Replace the script path with your checkout's absolute path. Some desktop clients also require the absolute path to Node.
{
"mcpServers": {
"superzoo": {
"command": "node",
"args": ["/path/to/superzoo-mcp/dist/index.js"],
"env": {
"SUPERZOO_COUNTRY": "SK",
"SUPERZOO_TRANSPORT": "stdio"
}
}
}
}HTTP
SUPERZOO_COUNTRY=CZ SUPERZOO_TRANSPORT=http npm startConnect an MCP client to http://127.0.0.1:3000/mcp. For clients that support URL configuration:
{
"mcpServers": {
"superzoo": {
"url": "http://127.0.0.1:3000/mcp"
}
}
}HTTP uses stateless MCP Streamable HTTP with JSON responses. Each request gets a fresh protocol instance; there are no persistent sessions, standalone GET streams, or legacy SSE endpoint. GET /health checks process health and reports the selected country; it does not test upstream availability.
No bearer token is required or implemented. For remote access, place the service behind a TLS reverse proxy with access control and request limits. For example, Pocket ID can supply login for an OIDC-aware proxy. Verify your MCP client supports that authentication flow. The backend must remain reachable only through the proxy. See SECURITY.md.
On SIGINT or SIGTERM, HTTP stops accepting connections, lets active responses finish for up to five seconds, then closes remaining connections and cancels their upstream subscriptions. Stdio closes its protocol transport and cancels pending handlers.
The server validates Host headers and rejects browser Origin headers unless explicitly allowed. For a reverse proxy that forwards Host: mcp.example.com:
SUPERZOO_TRANSPORT=http \
SUPERZOO_HOST=0.0.0.0 \
SUPERZOO_ALLOWED_HOSTS=mcp.example.com \
node dist/index.jsSet SUPERZOO_ALLOWED_ORIGINS=https://client.example.com only when a browser client needs CORS. Origin and Host checks do not authenticate clients. Non-browser MCP clients normally send no Origin header.
Related MCP server: Czech DIY Retail MCP Server
Countries and configuration
One server instance serves one country. Start separate instances to use multiple markets simultaneously. Product IDs may exist across markets; prices and availability always come from the selected shop.
| Shop | Language | Currency |
| Slovak | EUR | |
| Czech | CZK | |
| Polish | PLN |
These are the verified Super zoo storefronts. Other brands within the parent group, such as Dino Zoo, are outside this project's current scope. Unsupported country codes fail at startup; the server never falls back silently to a different market.
Environment variable | Default | Meaning |
|
|
|
|
|
|
|
| HTTP bind hostname or IP |
|
| HTTP port, 1–65535 |
| Loopback names/IPs plus a specific bind host | Comma-separated accepted HTTP hostnames/IPs, without port or scheme. Binding |
| Empty | Comma-separated exact HTTP(S) browser origins; no wildcards |
Environment variables work with both transports. For Windows or file-based configuration, copy .env.example to .env and run:
node --env-file=.env dist/index.jsThe server does not load .env automatically. Bounded request diagnostics (market, operation, status, duration, cache hit) go to stderr, without queries, addresses, headers, or response bodies; stdout is reserved for MCP in stdio mode.
Tools
Tool | Arguments | Returns |
|
| Product IDs, links, price offers, variants, and availability summaries |
|
| Product identity, brand, EAN, variants, price offer, delivery and available-store count |
|
| Store names, addresses, links, opening hours, stock status and pickup text |
|
| Input-ordered products with per-product errors and original fetch timestamps |
|
| Stores grouped by stable ID, every requested product's observation, and |
Example workflow:
search_products({"query":"brit care lososovy olej","limit":3})Choose the correct bottle size using its variant-specific product ID.
get_product_availability({"product_id":"294-101115","city":"Bratislava"})
Ask your assistant: “Find Brit Care salmon oil and tell me which Bratislava stores have the 250 ml bottle.” For CZ or PL, select that market at startup and use a relevant city or omit the city filter.
Search filters and shopping examples (use IDs discovered in your selected market):
search_products({ query: "brit care", brand: "Brit Care", min_price: "0.10", max_price: "20.00", online_only: true, limit: 5 })
compare_products({ product_ids: ["294-101115", "294-172197"] })
find_common_stores({ product_ids: ["294-101115", "294-172197"], city: "Bratislava" })Brand matching is exact after case/accent normalization. Price bounds are inclusive nonnegative decimal strings; reversed ranges are rejected. Filters combine with AND. online_only: true requires explicit delivery status available; absent, unknown, or unavailable statuses are omitted. can_buy and branch stock do not establish delivery availability. online_only: false adds no delivery filter.
Search filters apply locally to enriched candidates within the first 200 upstream items, preserving upstream order. coverage: "bounded_candidates" means omitted candidates may contain matches. filters_applied echoes normalized supplied filters; products_checked counts attempted detail lookups, including cache hits and failures; detail_failures counts failed lookups. When filters are active, failed or missing required fields exclude a candidate. With no active filters, detail failures retain discovery data with price: null and detail_error.
Both batch tools return complete: false when any product lookup fails, with per-product stable errors. Comparison preserves input order. Common-store results include the union of observed stores and an entry for every requested product at each store. Missing observations have null status/timestamp; failed lookups also carry an error. all_in_stock is true only when every requested product explicitly has status inStock at that store. Store identity uses its ID; first successful observation in input order supplies display metadata. Stock never guarantees pickup timing. Observed raw available values can include pickup within hours, while inStock can include a later day. The conservative all_in_stock: false does not prove a store cannot supply the products; inspect each status and pickup text. See the branch-status evidence.
Every tool publishes a success output schema and returns the same data as JSON text and structuredContent. Tool failures use isError: true and JSON text {code, message, retryable}, without success-shaped structured content. Codes are not_found, rate_limited, upstream_unavailable, invalid_response, timeout, cancelled, overloaded, and internal_error. Input validation uses MCP SDK/Zod errors separately. Cancellation can reject the protocol request before a tool-error response is delivered.
Prices, stock, and limits
Prices come from anonymous online lookups in the market's currency. Decimal amounts remain strings.
price.contextispublic_online;price.variantpreserves the upstream offer label. AfamilyPriceoffer can appear without login and may require membership. It is not proof of your eligibility or a physical-store price.original_amountandlowest_amountpreserve upstream reference prices when present.Stock is a status, not an exact quantity.
quantityis alwaysnull; missing stock status becomesunknown. Stock status andpickup_textstay separate: an in-stock product may only be ready tomorrow.Single-product, availability, and search results include
market,source, and an ISOchecked_attimestamp. Batch results includemarketand a completionchecked_at; nested products and store observations retain their own retrieval timestamps. Successful validated details cache for 60 seconds and raw stock for 15 seconds, in one 256-entry in-memory LRU cache per client. Cache hits retain the originalchecked_at; expired data and failures are never served from cache. Prices and stock can change afterward; these tools never reserve products.City filtering matches store names and addresses locally, ignoring case and accents. It does not measure distance or establish municipal boundaries. Pickup text remains in the shop's language.
opening_hours_htmlcontains upstream HTML. Treat it as untrusted data in any UI.Search checks at most 200 mixed candidates and filters non-products, forbidden products, and price restrictions. The verified default levels are SK
22and CZ1. The Polish default level is unverified, so PL conservatively excludes any candidate with explicit price-level restrictions. This may omit eligible products.upstream_total_countis not a product count.candidate_limit_reachedsignals that upstream candidates were omitted. Fewer than the requested number may be returned.One long-lived client shares a maximum of four upstream operations across searches, batches, and HTTP callers, with at most 128 queued operations. A full queue returns
overloaded. Search and batch enrichment also use at most four local lookups.Each upstream operation has a 15-second total deadline, including queueing, retries, and response validation. At most two attempts retry network failures and HTTP 429/502/503/504. Valid
Retry-Afterseconds/dates are honored only if the delay fits the deadline; otherwise the current error returns. Without a valid header, jitter is 200–500 ms. Validation errors, cancellation, and other HTTP statuses are not retried. Multi-step searches/batches can take longer than one operation deadline.Identical detail/stock lookups share in-flight work. Each caller cancels independently; upstream work stops when no callers remain. SDK cancellation propagates over stdio; closing an HTTP response cancels that request's handlers. Cancellation stops queued enrichment rather than returning an apparently complete batch. City filtering runs after raw stock retrieval, including cache hits. Markets never share cache entries or upstream work.
HTTP request bodies are limited to 64 KiB. Remote request limits and authentication belong to your deployment infrastructure.
Unit prices, distance ranking, full-catalog search/pagination, and Polish price-level changes remain deferred pending further evidence. Account features are outside scope.
These are undocumented upstream APIs. They may change. There are no account, cart, ordering, or mutation tools.
Docker
docker build -t superzoo-mcp .
docker run --rm -p 127.0.0.1:3000:3000 -e SUPERZOO_COUNTRY=PL superzoo-mcpA separate build stage compiles TypeScript. The final image contains production dependencies and compiled JavaScript, and runs HTTP as a non-root user. For a proxy, connect it through a private container network and set SUPERZOO_ALLOWED_HOSTS to the forwarded hostname. Avoid publishing the backend directly on a public interface.
Development and validation
npm ci
npm run typecheck
npm test
npm run test:package
SUPERZOO_COUNTRY=SK npm run smoke
SUPERZOO_COUNTRY=CZ npm run smoke
SUPERZOO_COUNTRY=PL npm run smoke
npm audit --omit=dev
npm pack --dry-runThe TypeScript runtime lives in src/ and compiles to ignored dist/ output. npm test builds first, then runs JavaScript tests against the compiled runtime. npm run smoke and npm pack also build automatically. After changing source, rebuild before using npm start. Installed packages and the final Docker image run compiled JavaScript without TypeScript development dependencies.
Unit and protocol tests use small public-data fixtures and temporary localhost HTTP listeners, without external requests. SIGTERM tests cover stdio cancellation, HTTP response draining, forced closure after the existing five-second HTTP grace period, cancellation of active/queued work, and clean process exit. npm run test:package is a separate gate: it builds and packs the package, installs the tarball with runtime dependencies in a temporary consumer directory, then tests the installed executable with fixture data. It can access the npm registry, but makes no Super zoo requests. CI runs this consumer-install check on Node 22 and 24. Each live smoke invocation checks search, product detail, and store availability; detail enrichment and bounded retries may add upstream requests. The separate upstream smoke workflow runs daily at 06:00 UTC and supports manual dispatch, sequentially across SK/CZ/PL. A valid empty search is a canary failure, not proof of an API outage. Smoke output contains bounded operation results and latency, without product/store bodies. CI continues to run offline tests on Node.js 22 and 24. See CONTRIBUTING.md and API notes.
The npm package includes only compiled runtime JavaScript, README, license, and package metadata. The GitHub repository also contains tests and development files. Downloaded apps and raw research stay in ignored local storage and are not redistributed. Super zoo trademarks and third-party storefront content remain their owners' property.
Available Tools
3 toolsget_productBRead-onlyIdempotent
Get product details, variants, public online EUR offers in Slovakia, delivery availability and available-store count. Price variant identifies conditional offers such as familyPrice; membership eligibility and branch prices are not verified.
Inputs: product_id (required).
get_product_availabilityARead-onlyIdempotent
Get availability in Slovakia stores for one product variant. Optional city filters store name/address locally, ignoring accents. Stock status and pickup text are separate. No exact quantities or branch prices. Check checked_at for freshness.
Inputs: product_id (required), city.
search_productsBRead-onlyIdempotent
Find Superzoo products in Slovakia, with public online EUR offers and availability summaries. Default 10, max 50 results. Search checks up to 200 mixed candidates; upstream totals are not product counts. Partial detail failures are marked on each product. Use variant-specific product IDs for stock lookups.
Inputs: query (required), limit.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
search_products, get_product, and get_product_availability target distinct actions (discovery, detail, store-level stock), and the descriptions clarify that get_product includes only availability summaries while get_product_availability is for one variant's store availability. There is mild overlap around availability, but the variant-specific scope of get_product_availability makes the boundary workable.
All three names follow a consistent snake_case verb_noun pattern: search_products, get_product, get_product_availability. The shared get_product prefix also makes the detail/availability relationship predictable.
Three tools are reasonable for a focused read-only product catalog: search, detail, and availability. The surface is slightly thin, but each tool has a clear role and the server does not appear to need broader mutation operations.
The core read-only product workflow is covered: find products, inspect product details and variants, and check store availability for a variant. Minor gaps exist, such as no standalone store listing or category browsing, but agents can work around these through search and product details.
Maintenance
Related MCP Connectors
Search ~8.5M products from 2,500+ Central European e-shops. Semantic, keyword, GTIN lookup.
Search and look up products across thousands of online stores, normalized into one schema.
Search and look up products across thousands of online stores, normalized into one schema.
Read-only product discovery, merchant trust, shipping and returns for SVV-Schatzoekers.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceSearch product catalogs across thousands of Central European e-shops. Semantic search, keyword matching, GTIN/EAN lookup — via REST API or MCP. \~2,500 e-shops | ~8.5M products | 7 countries (CZ, SK, PL, HU, RO, DE, AT)MIT
- AlicenseAqualityCmaintenanceEnables searching products, retrieving product details, listing stores, checking stock availability, and comparing prices across Czech DIY retailers.5MIT
- AlicenseAqualityCmaintenanceEnables read-only search and retrieval of the public Reknihy.cz book catalog, including filtering, sorting, ISBN lookup, category browsing, and access to product details such as price, availability, and images.4ISC
- AlicenseAqualityCmaintenanceEnables querying live offers and prices from 10 Dutch supermarket chains through a single normalised JSON API. Exposes 26 curated tools, including product search and category lookups, over stdio or authenticated Streamable HTTP.201MIT