Skip to main content
Glama
neuratechcompany-ops

Kettu Marketplace Intelligence

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
WB_PROXYNoProxy for Wildberries
OZON_PROXYNoProxy for Ozon
WB_MIN_GAPNoMinimum gap between requests for Wildberries
WB_TIMEOUTNoTimeout for Wildberries connector
AVITO_PROXYNoProxy for Avito
DNS_MIN_GAPNoMinimum gap between requests for DNS
DNS_TIMEOUTNoTimeout for DNS connector
DETMIR_PROXYNoProxy for Detsky Mir
LAMODA_PROXYNoProxy for Lamoda
OZON_MIN_GAPNoMinimum gap between requests for Ozon
OZON_TIMEOUTNoTimeout for Ozon connector
TAOBAO_PROXYNoProxy for Taobao
WB_CACHE_TTLNoCache TTL for Wildberries (0 disables cache)
YANDEX_PROXYNoProxy for Yandex Market
AVITO_MIN_GAPNoMinimum gap between requests for Avito
AVITO_TIMEOUTNoTimeout for Avito connector
CHROME_BINARYNoChrome binary path
DETMIR_REGIONNoRegion for Detsky Mir (e.g., RU-MOW, RU-SPE)
DNS_CACHE_TTLNoCache TTL for DNS
MCP_HTTP_HOSTNoMCP HTTP host
MCP_HTTP_PORTNoMCP HTTP port
MCP_TRANSPORTNoMCP transport (stdio or http)
CHROME_STEALTHNoChrome stealth mode
LAMODA_MIN_GAPNoMinimum gap between requests for Lamoda
LAMODA_TIMEOUTNoTimeout for Lamoda connector
OZON_CACHE_TTLNoCache TTL for Ozon
TAOBAO_MIN_GAPNoMinimum gap between requests for Taobao
TAOBAO_TIMEOUTNoTimeout for Taobao connector
WB_NET_RETRIESNoNetwork retries for Wildberries
YANDEX_MIN_GAPNoMinimum gap between requests for Yandex Market
YANDEX_TIMEOUTNoTimeout for Yandex Market connector
AVITO_CACHE_TTLNoCache TTL for Avito
CHROME_CDP_HOSTNoChrome CDP host
CHROME_CDP_PORTNoChrome CDP port
CHROME_HEADLESSNoChrome headless mode
WB_DEFAULT_DESTNoDefault destination for Wildberries
CITILINK_MIN_GAPNoMinimum gap between requests for Citilink
CITILINK_TIMEOUTNoTimeout for Citilink connector
DETMIR_CACHE_TTLNoCache TTL for Detsky Mir
LAMODA_CACHE_TTLNoCache TTL for Lamoda
OZON_IMPERSONATENoImpersonation setting for Ozon
TAOBAO_CACHE_TTLNoCache TTL for Taobao
YANDEX_CACHE_TTLNoCache TTL for Yandex Market
AVITO_IMPERSONATENoImpersonation setting for Avito
AVITO_LOCATION_IDNoLocation ID for Avito
WB_MAX_BODY_BYTESNoMaximum body bytes for Wildberries
CITILINK_CACHE_TTLNoCache TTL for Citilink
MEGAMARKET_MIN_GAPNoMinimum gap between requests for Megamarket
MEGAMARKET_TIMEOUTNoTimeout for Megamarket connector
MEGAMARKET_CACHE_TTLNoCache TTL for Megamarket
COMPARE_SOURCE_TIMEOUTNoTimeout for compare connector
CHROME_SCRAPING_PROFILENoChrome scraping profile

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {}
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
marketplace_sourcesA

List which connectors this unified server actually mounted.

Why this exists

Connectors are imported defensively, so a missing dependency removes a marketplace instead of killing the server. That is the right failure mode, but it is invisible from the client: absent tools look the same as a source that simply found nothing. Call this before concluding a marketplace has no results — if it is in skipped, it was never queried at all.

Return Format

MarketplaceSourcesResponse: {mounted, skipped, mounted_count, skipped_count, server_version}. skipped maps source name to the import error that removed it, which is usually a missing optional dependency.

wb_cardA

Fetch product card data from WB v4 API.

Returns prices in rubles, brand, supplier, supplier_rating, review_rating, feedbacks count, total_quantity for up to 100 SKUs.

wb_root_infoA

Fetch full card metadata from basket CDN. Returns imt_id (root_id) for review pool.

All variants of one product share imt_id. Reviews indexed by imt_id, NOT by nmId.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

wb_reviewsA

Fetch reviews by imt_id (root_id from wb_root_info).

All product variants share one review pool, indexed by imt_id NOT nmId.

The WB feedbacks endpoint returns a fixed pool (~1000 most-recent reviews, newest-first) and IGNORES server-side order params (verified Nov 2026), so sort is applied CLIENT-SIDE over that pool. To surface complaints, "worst" reorders the returned pool by lowest rating first.

wb_questionsA

Fetch buyer questions and seller answers by imt_id (root_id from wb_root_info).

Answers this tool exists for: buyers ask what a listing omits — "does it fit a 60cm opening", "is the cable included", "is this the 10A or the 16A model" — and the seller's reply is often the only public statement of that fact. Reviews describe the experience of owning the product; questions clarify what it actually is.

Keyed by imt_id, exactly like wb_reviews: every colour and size variant shares one question pool. Passing an nmId returns an empty pool with no error, so resolve the root id via wb_root_info first.

wb_searchA

Search WB catalog by text query.

Uses the lightweight search-goods.wildberries.ru/search endpoint which returns just product IDs (no PoW protection, very high rate limit). Then enriches via wb_card for full details.

wb_sellerA

Look up the registered legal entity behind a WB seller.

Answers "who actually ships this?" — the question a marketplace listing is worst at. Returns the registered name, tax ids (INN/KPP/OGRN) and legal address, which is how you tell an official brand store from a reseller trading under a lookalike name, and how you spot several storefronts sharing one entity.

Chain from wb_card: its supplier_id field feeds straight into this tool.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

wb_categoriesA

Browse the Wildberries catalog tree.

Use this to discover what exists before searching: wb_search needs a query string, but a shopper's question is often "what categories of humidifiers are there?". Each node carries WB's own shard and query selectors, which are the addressing needed to pull a category feed.

The live menu is ~800 KB, so responses are always a bounded slice — start at 'top', then expand the branch you care about.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

wb_category_productsA

List the products in a catalog category, using the shard and query from wb_categories.

This closes the loop wb_categories opens. That tool hands back WB's own shard and query selectors — the address of a category feed — and this is the tool that fetches it. Browsing "what humidifiers exist" no longer requires inventing a search phrase and hoping WB's relevance ranking agrees with you.

Items come back in the same shape wb_search and wb_card return, so a category walk and a text search are directly comparable.

Not every category has a feed. WB marks those with the shard blackhole, and several of its largest sections (smartphones, laptops, TV and audio) are among them: they exist as navigation, not as a listable endpoint. Asking for one raises a clear error naming the alternative rather than returning an empty list, because an empty list here would read as "this category has no products", which is false.

wb_selfcheckA

Structural drift canary for WB (tri-state: success / drift_detected / inconclusive). Probes EVERY endpoint family the tools depend on:

  • card — card.wb.ru v4 (wb_card / wb_search enrich): critical fields + price extract.

  • reviews — feedbacks2.wb.ru pool (wb_reviews): texts + productValuation.

  • search_goods— search-goods.wildberries.ru (wb_search STEP 1): the id list must still be a non-empty list of recoverable ids on a broad evergreen query, else wb_search silently returns no_results.

  • root_basket — basket-NN.wbbasket.ru (wb_root_info): imt_id must resolve, else wb_root_info AND wb_reviews (indexed by imt_id) break.

Tri-state (audit 2026-06-01): an http!=200 / network error / OOS baseline is inconclusive (transport/baseline rot), NEVER drift. Only a reached-200 body whose parser-critical anchor is gone is drift. Run on demand before trusting a batch.

ozon_cardA

Fetch Ozon product card data via composer-api.bx.

Tier-1 (curl_cffi) tried first. Falls back to Tier-2 (Chrome CDP at port 9222) when Tier-1 hits Cloudflare 403. Tier-2 requires the operator running Chrome via scripts/start_chrome_cdp.ps1 (Windows) or scripts/start_chrome_cdp.sh (Linux/macOS) first.

ozon_reviewsA

Fetch Ozon product review texts + star distribution via composer-api.bx.

Tier-1 (curl_cffi) tried first, Tier-2 (Chrome CDP) fallback — same path as ozon_card. Returns review texts (comment/positive/negative), per-review score, helpfulness votes, author first name, date, plus the overall star distribution and total count.

Pages are walked automatically (30/page) until limit texts are collected or pages run out, deduplicating by review uuid. Hard cap of 10 pages.

Return Format

OzonReviewsResponse: {status, sort, rating_score, reviews_count, distribution, returned, partial, stop_reason, last_error, requested_limit, reviews, meta} on success. A later-page failure with reviews already collected is a PARTIAL SUCCESS (partial=True, stop_reason set), NOT an error.

Error Format

Raises ToolError on validation (BadRequestError), transport/block (TransportDownError), or parser drift (ParserDriftError) — but ONLY when no reviews have been collected yet. Once at least one page yielded reviews, a later-page failure degrades to a partial-success return.

ozon_searchA

Search Ozon catalog. Tier-1 curl_cffi → Tier-2 CDP fallback.

Returns sku/title/price/rating per item. Schema parses Nov 2026 tileGridDesktop-* widgets with mainState atom structure.

Return Format

OzonSearchResponse: {status, query, page, tier_used, count, items, meta} on success. Zero matching items is NOT an error — it returns a healthy response with count=0 and empty items.

Error Format

Raises ToolError on validation (BadRequestError), transport/block (TransportDownError), or parser drift (ParserDriftError).

ozon_selfcheckA

Structural drift canary for Ozon (tri-state: success / drift_detected / inconclusive). Fetches live search/card/reviews + a non-default reviews sort and compares the widget-prefix SHAPE against the critical set, plus a parse smoke. Detects "a widget we depend on vanished" BEFORE it silently breaks a parser.

Tri-state (audit 2026-06-01): a Cloudflare 403 / CDP-down / non-200 / non-JSON body is inconclusive (transport — Ozon's tier-1 curl_cffi is often blocked), NEVER drift. Only a reached-200 JSON body missing a critical widget or failing the parse smoke is drift. The reviews_sort subcheck exercises the sort-param path (score_asc) that ozon_reviews pagination depends on.

Return Format

OzonSelfcheckResponse: {status, healthy, connector, checks, server_version, server_started_at, process_id} — tri-state per subcheck (healthy/drift/inconclusive). Inconclusive and drift_detected are NOT errors; they are valid canary verdicts returned as a normal response.

Error Format

Raises ToolError (TransportDownError) ONLY on an unexpected internal bug that prevents the canary from producing any verdict. Transport/block/parse failures of individual sub-checks map to inconclusive entries, not errors.

yandex_searchA

Search Yandex Market and return products with both prices, ratings and sellers.

Yandex Market aggregates many sellers per product, which makes it the best single source for "what does this cost right now" across the Russian market — including goods Wildberries and Ozon do not carry.

Each result reports price_rub (what anyone pays) and price_with_plus (requires a Yandex Plus subscription, typically 25-30% lower). Prefer price_rub when quoting a price to a person.

Note rating_count counts star ratings, not written reviews; the written count is available per product via yandex_card.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

yandex_cardA

Fetch full detail for a Yandex Market product: prices, rating breakdown, reviews.

Two things here are hard to get anywhere else. The star distribution (rating_stars) shows whether a 4.8 average hides a cluster of one-star complaints. And reviews arrive with the card in one request, complete with pros, cons and helpfulness votes.

Reviews are capped at the ~13 Yandex renders server-side; the remainder load through an API this connector deliberately does not touch.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

yandex_selfcheckA

Probe Yandex Market's search and card pages and report a tri-state verdict.

success — the SSR state parsed as expected. drift_detected — pages load but no longer parse, so the extraction rules need updating. inconclusive — a transport block, geo restriction or captcha prevented a verdict; that says nothing about the parsers.

This matters more here than for a JSON API: SSR extraction is inherently coupled to Yandex's front-end, so drift is a question of when.

detmir_cardA

Fetch price, rating, stock and seller for one Detsky Mir product.

Covers the kids-and-baby category that the general marketplaces cover unevenly, and distinguishes Detsky Mir's own stock from third-party marketplace sellers.

Region matters most here. store_count is the number of physical shops holding the item, and it swings hard by city — one item verified live sat in 152 Moscow stores, 37 in St Petersburg, 2 in Khabarovsk. Pass region to ask about a specific city; it overrides DETMIR_REGION for this call only, so one session can compare cities.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

detmir_categoryA

List products in a Detsky Mir category, with the total match count.

This is the reliable way to enumerate the catalog: unlike text search, it is a real JSON endpoint with proper pagination and an upstream total, so it supports "what's available and how much does it cost" without scraping.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

detmir_categoriesA

Browse the Detsky Mir catalog tree and get the aliases detmir_category needs.

This is the discovery step: Detsky Mir has no working text search (see the module docstring), so the way to find products is to walk the tree and then list a category. Each node carries its alias and a products_count, so you can see where the inventory actually is before fetching a listing.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

detmir_selfcheckA

Probe every Detsky Mir endpoint family and report a tri-state verdict.

success — everything answered with the expected shape. drift_detected — an endpoint answered but the payload no longer parses; the connector needs updating. inconclusive — transport or geo blocking prevented a verdict, which says nothing about the parsers.

Run it after install and whenever results look wrong.

avito_searchA

Search Avito listings via the internal js/items API.

Return Format

AvitoSearchResponse: {status, query, page, location_id, tier_used, count, total_count, items[], meta}. Items carry item_id, title, price_rub (None when the ad has no price — never 0), url, location, seller fields.

Error Format

ToolError: BadRequestError on malformed arguments; TransportDownError on firewall blocks (with the captcha/proxy guidance inline); ParserDriftError when a reached-200 body no longer parses as the expected envelope.

avito_cardA

Fetch one Avito listing by id or URL.

Return Format

AvitoCardResponse: {status, item_id, title, price_rub, description, location, posted_at, views, images, seller, url, tier_used, meta}. price_rub is None when the ad has no price — never 0.

Error Format

ToolError: BadRequestError when no id can be extracted; NotFoundError on a 404 (deleted or never existed); TransportDownError on blocks; ParserDriftError when the envelope changed.

avito_sellerA

Fetch an Avito seller profile — reputation is the review signal here.

Classifieds have no per-item review pool; the seller's rating, review count and active-listing count are what a buyer checks.

Return Format

AvitoSellerResponse: {status, seller, active_items, tier_used, meta}.

Error Format

ToolError: BadRequestError on empty input; NotFoundError on 404; TransportDownError on blocks; ParserDriftError on envelope drift.

avito_selfcheckA

Structural drift canary for Avito (tri-state: success / drift_detected / inconclusive). Runs live probes against search, card and seller endpoints.

A 403 firewall block or CDP-down is inconclusive (transport), NEVER drift: from a datacenter IP that is the expected state. Only a reached-200 JSON body that fails the parse smoke is drift.

Return Format

AvitoSelfcheckResponse: {status, healthy, connector, checks, server_version, server_started_at, process_id}.

taobao_searchA

Search Taobao listings, rendered in the operator's Chrome.

Return Format

TaobaoSearchResponse: {status, query, page, tier_used, count, items[], meta}. Items carry item_id (string), title, price_cny (None when hidden — never 0), shop_name, sales label, url.

Error Format

ToolError: TransportDownError when Chrome/CDP is unreachable or the page lands on a login wall (log into taobao.com in the scraping profile, then retry); ParserDriftError when a rendered page yields zero items, which means the DOM shape moved.

taobao_cardA

Fetch one Taobao item card.

Return Format

TaobaoCardResponse: {status, item_id, title, price_cny, shop_name, sales, description_images, url, tier_used, meta}. price_cny is None when the page hides it or prices by variant — never 0.

Error Format

ToolError: BadRequestError when no id can be extracted; NotFoundError when the item page reports itself gone; TransportDownError on login walls and CDP failures; ParserDriftError when a rendered card has neither title nor price.

taobao_selfcheckA

Structural drift canary for Taobao (tri-state). Renders one live search page in the operator's Chrome and checks the extractor still finds items.

CDP down or a login wall is inconclusive (transport/session), NEVER drift. Only a rendered page that yields zero items is drift.

Return Format

TaobaoSelfcheckResponse: {status, healthy, connector, checks, server_version, server_started_at, process_id}.

megamarket_searchA

Search the Megamarket catalog via the mobile API, inside the operator's Chrome.

Return Format

MegamarketSearchResponse: {status, query, tier_used, count, total_count, items[], meta}. price_rub is None when absent — never 0.

Error Format

ToolError: TransportDownError on ServicePipe refusals (with the fix inline); ParserDriftError when a reached-200 body no longer parses.

megamarket_cardA

Fetch one Megamarket product card.

Return Format

MegamarketCardResponse: {status, item_id, title, price_rub, old_price_rub, is_available, rating, rating_count, url, tier_used, meta}.

Error Format

ToolError: BadRequestError on unparseable input; NotFoundError on a missing goods id; TransportDownError on ServicePipe refusals; ParserDriftError on envelope drift.

megamarket_selfcheckA

Structural drift canary for Megamarket (tri-state). Posts one live search through CDP and checks items parse.

A ServicePipe code-7 refusal or CDP-down is inconclusive (transport), NEVER drift. Only a reached-200 catalog body that fails the parse smoke is drift. From a machine whose Chrome has not passed the challenge, inconclusive is the expected verdict.

Return Format

MegamarketSelfcheckResponse: {status, healthy, connector, checks, ...}.

lamoda_searchA

Search Lamoda, rendered in the operator's Chrome (discovery is blocked tier 1).

Return Format

LamodaSearchResponse: {status, query, tier_used, count, items[], meta}. Items carry sku, title, brand, price_rub (None when absent — never 0), url.

Error Format

ToolError: TransportDownError on CDP/nav failures; ParserDriftError when a rendered page yields zero SKUs, which means the tile shape moved.

lamoda_cardA

Fetch one Lamoda product card via the anonymous GraphQL endpoint (tier 1).

Return Format

LamodaCardResponse: {status, sku, title, brand, price_rub, old_price_rub, is_available, sizes[], url, tier_used, meta}. Lamoda exposes no ratings.

Error Format

ToolError: BadRequestError when no SKU can be extracted; NotFoundError when the SKU has no product; TransportDownError on HTTP failures; ParserDriftError when the GraphQL envelope changed.

lamoda_selfcheckA

Structural drift canary for Lamoda (tri-state). Probes the GraphQL card path (tier 1) and the CDP search path (tier 2).

GraphQL down is inconclusive for the card check; CDP down / a redirect loop is inconclusive for the search check. Only a reached payload that fails its parse smoke is drift.

Return Format

LamodaSelfcheckResponse: {status, healthy, connector, checks, ...}.

dns_searchA

Search DNS-Shop, rendered in the operator's Chrome.

Return Format

DnsSearchResponse: {status, query, tier_used, count, items[], meta}. price_rub is None when absent — never 0.

Error Format

ToolError: TransportDownError on CDP/Qrator failures; ParserDriftError when a rendered page yields zero product tiles.

dns_cardA

Fetch one DNS-Shop product card.

Return Format

DnsCardResponse: {status, product_id, title, price_rub, old_price_rub, is_available, url, tier_used, meta}.

Error Format

ToolError: BadRequestError when the URL carries no product id; TransportDownError on CDP/Qrator failures; ParserDriftError when a rendered card has neither title nor price.

dns_selfcheckA

Structural drift canary for DNS-Shop (tri-state). Renders one live search page in the operator's Chrome and checks tiles extract.

Qrator-blocked or CDP-down is inconclusive (transport), NEVER drift. Only a rendered page that yields zero tiles is drift.

Return Format

DnsSelfcheckResponse: {status, healthy, connector, checks, ...}.

citilink_searchA

Search Citilink, rendered in the operator's Chrome.

Return Format

CitilinkSearchResponse: {status, query, tier_used, count, items[], meta}. price_rub is None when absent — never 0.

Error Format

ToolError: TransportDownError on CDP/Qrator failures; ParserDriftError when a rendered page yields zero product tiles.

citilink_cardA

Fetch one Citilink product card.

Return Format

CitilinkCardResponse: {status, product_id, title, price_rub, old_price_rub, is_available, url, tier_used, meta}.

Error Format

ToolError: BadRequestError when the URL carries no product id; TransportDownError on CDP/Qrator failures; ParserDriftError when a rendered card has neither title nor price.

citilink_selfcheckA

Structural drift canary for Citilink (tri-state). Renders one live search page in the operator's Chrome and checks tiles extract.

Qrator-blocked or CDP-down is inconclusive (transport), NEVER drift. Only a rendered page that yields zero tiles is drift.

Return Format

CitilinkSelfcheckResponse: {status, healthy, connector, checks, ...}.

compare_pricesA

Price one product across every configured Russian marketplace at once.

Queries each marketplace concurrently and returns a single list ranked by price, plus a per-source report of what answered and what did not. This is the tool for "where is X cheapest" — running the per-marketplace search tools one at a time gives the same data far more slowly and without the ranking.

Two things to read carefully in the output:

  • cheapest is chosen on everyday prices. Yandex Market's subscriber price appears as price_with_subscription_rub and is deliberately excluded from ranking, since it requires a paid Yandex Plus subscription.

  • source_outcomes shows which marketplaces answered. A blocked or timed-out source means the comparison is partial, not that the product is absent there — complete tells you which case you are in.

Titles are matched loosely: marketplaces name things differently, so scan the results rather than assuming every row is the identical model.

Error Format

On validation failure, raises ToolError with a JSON message describing the error code and whether it is retryable. Individual source failures do NOT raise — they are reported in source_outcomes.

compare_sourcesA

Report which marketplaces this installation can actually query.

Call this first when a comparison comes back partial: it distinguishes "the connector isn't installed" from "the marketplace refused us", which need completely different fixes.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

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/neuratechcompany-ops/kettu-marketplace-mcp'

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