letu-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., "@letu-mcpIs Dior Sauvage available in Moscow? Show price, club card discount, and delivery."
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.
letu-mcp
English · Русский
An MCP server that gives LLM agents live, honestly-labelled data from ЛЭТУАЛЬ (letu.ru), a large Russian cosmetics and perfume retailer: search with pages, sorting, price window, seller and in-stock filters; product cards with every variant priced and the Club Card discount split out; delivery and store stock in your city; per-product ratings and reviews.
Buyer side, anonymous: no ЛЭТУАЛЬ account needed, nothing is put in a cart.
Why this server
The store's own API answers plain HTTP, but several of its numbers mean something other than they seem. This server is built around not passing those on unlabelled:
Store trap | What this server does |
The price shown to a visitor who is not logged in already includes the Club Card discount, which by the club rules applies only when the card is used (the card is free but needs registration with a phone number) |
|
The product-card API reports rating 0 and 0 reviews | Rating comes from the reviews service; |
|
|
The search tile price is the cheapest variant available in the city; |
|
Sponsored inserts in search ignore filters and sort order and duplicate items |
|
With a price window, the price sort pins some items at the top |
|
Filters in a wrong format are silently ignored | Filter formats verified against the live site; tile prices outside the window are flagged; an unknown category URL is an error, not an empty result |
|
|
Two cities named "Москва" (ids 8113 and 55109) with different delivery | The site's main (bold) entry is used, the others reported in |
The price-breakdown endpoint shows a "best price" computed with a 2 500-point bonus balance even to anonymous visitors, and bonus amounts that differ from the page | Neither is passed on; bonuses come from the product card, as on the page |
"From 2 pcs" kit prices do not reconcile with the unit price | Passed on as the site's text only |
Cross-border sellers have OGRN "0000" |
|
Promo codes are order-level conditions with a minimum order sum | Listed with |
The review sort "rating ascending" is silently ignored by the site | Not offered; |
Delivery for an unknown SKU id returns HTTP 200 with empty blocks | Reported as an error, not as "not available" |
Every answer carries fetched_at (UTC) and the city it was computed for:
the name comes from the store's own answer (its city list or geo-IP), with the
source (city parameter, LETU_CITY, or geo-IP). The city id is sent with
every city-dependent request; search, card and delivery answers do not echo
it back, the store list does and is checked (a list for another city is an
error, not data).
Related MCP server: ozon-mcp
Tools
Tool | What it returns |
| Up to 70 items per page; sort |
| Every variant: |
| Date, stars, text, pros, cons, likes, verified purchase, expert, shop answer, reviewer's skin type/age group; sort |
| Stores in the city (ЛЭТУАЛЬ and partner «Подружка» shops) with the site's stock level (Мало / Средне / Много), pickup today or later and when; courier and pick-up point delivery |
| Up to 10 products side by side, one variant each (pinned, or the cheapest one orderable in the city) |
product accepts a product id (71600124), a product URL, or
productId:skuId to pin a variant.
Requirements
Measured on 2026-09-25 (Linux, Python 3.12, Russian residential IP).
Python | ≥ 3.10, with uv (or pip) |
Browser | Not needed. Plain HTTP; no Playwright, no Chromium, no display |
Docker | Not needed |
Disk | ≈ 35–40 MB for the Python environment (mcp, pydantic, requests, …) |
Memory | Server process ≈ 75–82 MB RSS (peak 78 MB during a first search with a fresh session). When started through |
Cold start | MCP |
Per call | One HTTP request takes 0.1–0.9 s; the rest is the deliberate 2 s spacing. Search ≈ 2–5 s, reviews ≈ 2 s, store availability ≈ 5 s, |
Network | A Russian IP. Foreign and VPN addresses were not tested |
Install
Claude Code:
claude mcp add letu -- uvx --from git+https://github.com/SZhukovWork/letu-mcp letu-mcpAny MCP client (claude_desktop_config.json, .mcp.json, …):
{
"mcpServers": {
"letu": {
"command": "uvx",
"args": ["--from", "git+https://github.com/SZhukovWork/letu-mcp", "letu-mcp"],
"env": {"LETU_CITY": "Екатеринбург"}
}
}
}From a checkout: uv venv && uv pip install -e . && .venv/bin/letu-mcp.
Configuration (environment variables)
Variable | Default | Meaning |
| the site's geo-IP city | City name as on letu.ru ( |
|
| Seconds between requests to letu.ru (plus up to 0.5 s jitter) |
| — | Proxy URL, e.g. |
|
| Where the anonymous session is kept (directory 0700, file 0600) |
| a current desktop Chrome UA | Override when the built-in one gets old (the site's firewall answers 403 to non-browser clients) |
What the numbers mean
price_rub— the price the site shows without login. Whenclub_card_discount_in_priceistrueit already includes the ЛЭТУАЛЬ Club Card discount.price_without_club_card_rubis the price without it, from the site's own "applied discounts" breakdown.discounts[]lists every discount with itskind(club_card,sale,payment_method,coupon,other);discount_conditionsexplains each kind present. Sale discounts apply to everyone.price_list_rub— the crossed-out price before all discounts.price_from_rub(search) — the cheapest variant of the product that is available in the city, exactly as on the tile; confirm the variant withget_product.club_card_discount_in_priceabsent in search = discounted, but search does not say which discount.bonuses_back/bonuses_back_premium— points credited to a club member after purchase (with the paid Premium tier); not a discount.delivery_in_city— the only per-city availability signal:orderable_in_city, number of stores for pickup today / later, courier date and cost, pick-up points.courier_cost_rubis the site's price for this item alone; free delivery depends on the order sum.0means free, a missing value means unknown.stock_level— the site's word for a store's stock (Мало / Средне / Много); exact quantities are not published.Ratings — per product: all volumes and shades share one rating, and reviews do not say which variant was bought.
ratings_count= оценки,reviews_with_text= отзывы. Theratingsearch sort puts products with a handful of 5-star ratings first — look atratings_count.Promo codes — conditions on the whole order with
min_order_rub; they are not subtracted from an item price.
Limitations
Unofficial: relies on the storefront's internal JSON API, which ЛЭТУАЛЬ can change at any time. Parsing is isolated in
parse.pyand covered by tests on recorded responses.The NGENIX CDN in front of the site had a JavaScript proof-of-work challenge on this API in 2024; on 2026-09-25 it was off. If it comes back, tools return a clear
ChallengeRequirederror — this server does not solve it.Whether a buyer without the Club Card really pays
price_without_club_card_rubat checkout was not verified in a cart (the club rules say the discount needs the card).Personal prices («Цены только для тебя») and the real bonus balance are shown only after login and are not available.
The site has no price history, no barcode (EAN), manufacturer article or country of origin in its API;
articleis ЛЭТУАЛЬ's own product code.No questions & answers (the site's product "questionnaire" is a poll).
get_productchecks delivery for up to 6 variants and promo codes for one variant per call (passsku_idfor another one). Variants with identical price fields share one price-breakdown look-up, and the answer says so.sellermust match the site's seller name exactly (Лэтуаль,Подружка, …); an unknown name returns no products.in_stock_onlyis the site's own "Есть в наличии" filter; the site does not say which warehouses it counts.Review
has_morecan betruewhile the next page is empty: the site counts ratings without text that the review list does not return.Calls are spaced 2 s apart; a comparison of 10 products takes about two minutes.
Roadmap
Optional account mode (personal prices, real bonus balance) and the cart — later.
Browser fallback for the NGENIX challenge, if the site switches it on again.
Checkout, payment and address changes are out of scope by design.
Development
uv venv && uv pip install -e '.[dev]'
.venv/bin/pytest # offline tests on recorded, anonymised responses
.venv/bin/pytest -m live # end-to-end over MCP stdio against live letu.ru (Russian IP, ~30 requests)Disclaimer
Not affiliated with ЛЭТУАЛЬ. An unofficial server that uses the storefront's internal API; intended for personal price research at a human request rate. Respect the site's terms of use and keep request rates low.
License: MIT.
Available Tools
5 toolscompare_productsARead-onlyIdempotent
Side-by-side rows for up to 10 products, one variant each.
Per product: the pinned variant, or the cheapest one (orderable in the city
when with_delivery), its site price and price without the club card,
list price, rating (all variants) and counts, seller, delivery in the city,
the card's price range and number of variants. Takes ~3–5 requests per
product (~2 s each).
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City name as on letu.ru (e.g. 'Екатеринбург', 'Москва'). Default: LETU_CITY, else the city letu.ru assigns to this IP. Prices do not depend on the city; delivery, store stock and the variants available do. | |
| products | Yes | Up to 10 product ids / URLs; 'productId:skuId' pins a variant | |
| with_delivery | No | Check that the compared variant is orderable in the city (and pick the cheapest one that is) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint. The description adds valuable behavioral details: the variant selection logic (pinned or cheapest orderable when with_delivery) and performance characteristics (~3–5 requests per product, ~2 s each). This goes beyond the structured hints and does not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main purpose, followed by a compact list of per-product details and a performance note. It is efficient with no fluff, though the second paragraph is a dense list that could be slightly streamlined without losing value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values are covered. The description explains the variant selection, the data fields shown, and performance, which is sufficient for an agent to call the tool correctly. Minor gaps like error handling are not essential given the annotations and schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — each parameter already has a detailed description. The tool description does not add new meaning beyond the schema; it reiterates the variant selection and city influence, which are already present in the schema descriptions. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first line 'Side-by-side rows for up to 10 products, one variant each' uses a specific verb (compare) and resource (products), and the focus on multiple products clearly distinguishes it from siblings like get_product (single product) and search_products (search).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for comparing multiple products, but does not explicitly state when to use this tool versus alternatives. No exclusions or alternative routing are provided, though the context is clear enough for an agent to infer the appropriate scenario.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_productARead-onlyIdempotent
Full live card of one product: every variant with its price, the club-card split and delivery in the city.
Per variant (skus): price shown on the site, price without the club card
(from the site's own discount breakdown) and the list price, each discount
with its condition, bonuses back, seller (legal entity, OGRN, cross-border
flag), whether it is orderable in the city (pickup stores today/later,
courier date and cost, pick-up points) and promo markers. Plus the product
rating (all variants together), category path/URL, and — for one variant —
promo codes with their minimum order and kit offers.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City name as on letu.ru (e.g. 'Екатеринбург', 'Москва'). Default: LETU_CITY, else the city letu.ru assigns to this IP. Prices do not depend on the city; delivery, store stock and the variants available do. | |
| sku_id | No | Variant (SKU) to check in depth; default: all variants priced, the first 6 checked for delivery | |
| product | Yes | letu.ru product id (e.g. '71600124'), product URL, or 'productId:skuId' to pin a variant | |
| include_promos | No | Promo codes with order thresholds and kit offers for one variant | |
| include_delivery | No | Delivery/pickup in the city per variant (one request each) | |
| include_description | No | Description, usage, composition, characteristics, perfume notes, conformity documents |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent, and non-destructive behavior. The description adds useful behavioral context beyond those hints: it is a 'live' card, delivery details are city-dependent per variant, promo codes are provided 'for one variant', and the data includes the site's own discount breakdown. This gives the agent a realistic picture of scope without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then organized into a clear variant-by-variant breakdown. It is fairly long, but each sentence contributes substantive detail about what the tool returns; minor redundancy exists between the opening summary and the later enumeration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a rich output schema, fully described parameters, and safety annotations, the description supplies enough high-level context for an agent to select and invoke the tool correctly. It explains the product-card scope, the variant and city dimensions, and the promo/delivery inclusions without needing to restate structured schema content.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning by mapping parameters to output semantics: 'per variant' corresponds to sku_id/include_delivery, and the 'one variant' promo-codes note clarifies include_promos. It also introduces the `skus` framing that helps an agent understand how variant-level results are organized.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Full live card of one product', and then enumerates what that card contains (variants, prices, club-card split, delivery, promos, rating). This clearly distinguishes get_product from siblings like search_products, get_reviews, get_store_availability, and compare_products by its single-product, full-card scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the description says what the tool returns, so an agent can infer it is for retrieving comprehensive data about one product. However, it never explicitly says when to choose this over a sibling tool or when not to use it, leaving routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_reviewsARead-onlyIdempotent
Buyer reviews of a product: date, stars, text, pros, cons, likes, verified purchase, shop answer.
Also returns the product rating (all variants together) with the star split. Reviews are not linked to a variant (volume/shade). Buyer names and order numbers are never returned.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City name as on letu.ru (e.g. 'Екатеринбург', 'Москва'). Default: LETU_CITY, else the city letu.ru assigns to this IP. Prices do not depend on the city; delivery, store stock and the variants available do. | |
| page | No | Page of reviews | |
| sort | No | 'relevant' = the site's default (expert reviews first, then newest). The site has no worst-first order: use max_rating=3 to read complaints | relevant |
| limit | No | Reviews per page (the site allows up to 50) | |
| product | Yes | letu.ru product id (e.g. '71600124'), product URL, or 'productId:skuId' to pin a variant | |
| max_rating | No | Only reviews with at most this many stars | |
| min_rating | No | Only reviews with at least this many stars | |
| with_media | No | Only reviews with photos or videos |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds meaningful behavioral context beyond that: reviews are not linked to a variant, and buyer names/order numbers are never returned. It also clarifies the return includes aggregate rating. This supplements the annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise paragraphs with no filler. The first sentence states the core purpose and returned fields, immediately followed by the aggregate rating note and the variant caveat. Every sentence contributes useful information, and it is appropriately front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's primary function, the data it returns, and key limitations (variant independence, no buyer names/order numbers). With an output schema present and a rich input schema, the agent has everything needed to call this tool correctly. The description does not need to explain pagination or field formats because the schema handles those.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and each parameter (city, page, sort, limit, product, max_rating, min_rating, with_media) has a detailed description in the schema. The tool description does not add further parameter explanations beyond listing returned fields, which are not parameters. Since the schema fully documents parameters, the baseline 3 applies; the description adds no extra value here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves buyer reviews for a product, enumerating the returned fields (date, stars, text, pros, cons, likes, verified purchase, shop answer). It also notes it returns the aggregate product rating with star split. This is a specific verb+resource that distinguishes it from sibling tools like get_product (product details) and search_products (search).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for fetching reviews and aggregate ratings, but does not explicitly contrast it with alternatives. It does provide a useful caveat: 'Reviews are not linked to a variant' and 'Buyer names and order numbers are never returned', which helps the agent decide if this tool is appropriate. However, it does not name sibling tools or explicitly state when not to use it, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_store_availabilityARead-onlyIdempotent
Where one variant can be picked up in the city: stores with the site's stock level and pickup day.
Stores are ЛЭТУАЛЬ shops (letu_store) and partner «Подружка» shops
(podruzhka_partner_store). stock_level is the site's word (Мало /
Средне / Много) for stock in that store now; pickup: Позже means the site
will bring it there (pickup_when). Also returns courier and pick-up point
delivery for the city.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City name as on letu.ru (e.g. 'Екатеринбург', 'Москва'). Default: LETU_CITY, else the city letu.ru assigns to this IP. Prices do not depend on the city; delivery, store stock and the variants available do. | |
| sku_id | Yes | Variant id from get_product(...).skus[].sku_id (not the product id) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive. The description adds valuable behavioral context: it explains stock_level values (Мало/Средне/Много), the semantics of pickup: Позже and pickup_when, and that it returns courier and pick-up point delivery. This goes beyond what annotations provide, without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the main purpose. The first sentence states exactly what it returns; the second adds essential detail on store types and field semantics. No filler or redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, so return values are structured. The description explains the key output semantics (stock_level, pickup_when, courier/delivery) and the relationship to the variant id. An agent has everything needed to call this tool correctly, including the city default behavior (in schema) and the requirement for sku_id.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters have full descriptions in the input schema (city default behavior, sku_id origin). The tool description itself adds no parameter-specific information beyond what the schema already covers. With 100% schema coverage, the baseline of 3 is appropriate; the description doesn't need to repeat schema details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb+resource statement: 'Where one variant can be picked up in the city: stores with the site's stock level and pickup day.' It explicitly names the store types (letu_store, podruzhka_partner_store) and the meaning of stock_level and pickup fields. This distinguishes it from siblings like get_product or search_products, which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies this tool is for store availability of a specific variant in a city, with the sku_id parameter linking to get_product. It doesn't explicitly state when not to use it or name alternatives, but the context and sibling list make the intended use obvious. The 'Also returns courier and pick-up point delivery' broadens scope but doesn't confuse the primary use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_productsARead-onlyIdempotent
Search letu.ru like the site does: pages, sorting, price window, seller and in-stock filters.
Each item: product id and URL, brand, name, price_from_rub (cheapest
variant available in the city, as on the tile) with that variant's id,
pre-discount price, discount and its label (club-card or not), number of
variants in the city, per-product rating and count, markers, sponsored
and cross-border flags. total_variants_found is the site's "найдено N
вариантов товара"; total_products_found caps at "≥10000".
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City name as on letu.ru (e.g. 'Екатеринбург', 'Москва'). Default: LETU_CITY, else the city letu.ru assigns to this IP. Prices do not depend on the city; delivery, store stock and the variants available do. | |
| page | No | Result page (the site pages by `limit`) | |
| sort | No | Order of results, the site's options | popular |
| limit | No | Page size, 1–70 (the site's maximum) | |
| query | No | Search phrase as typed on the site (Russian works best) | |
| seller | No | Only this seller, exactly as the site names it: 'Лэтуаль' (the shop itself), 'Подружка', 'БОРДЕРЛЕСС ПОРТАЛ КО.ЛЛС' (cross-border), … | |
| price_max | No | Upper price bound, rubles | |
| price_min | No | Lower price bound, rubles (the site's price filter) | |
| category_url | No | Category listing instead of (or together with) a query, e.g. '/browse/kosmetika-dlya-glaz/tush' — get_product returns `category_url` for a product | |
| in_stock_only | No | The site's 'Есть в наличии' filter |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, so the description does not need to repeat these. It adds valuable context: the city parameter's effect on delivery/stock, the cap on total_products_found at '≥10000', and the meaning of total_variants_found. It also explains the return fields in detail. This goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured and front-loaded with the core purpose, then elaborates on return fields. It is informative but not excessively long. The list of item fields is comprehensive and useful, and the note about total counts is concise. It avoids unnecessary fluff, though it could be slightly more compact by referencing the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (though not shown), the description still provides a thorough list of returned fields, which is helpful. It covers pagination via page and limit parameters (already in schema), and mentions caps on counts. It does not address potential error cases or rate limits, but these are not strictly required. The description is complete enough for an agent to call the tool correctly without ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, meaning all 10 parameters are documented in the schema. The description adds little beyond that – it mentions 'seller and in-stock filters' and 'price window', but these are already explained in the parameter descriptions. The main description's mention of city's effect on delivery/stock is duplicated in the city parameter description. Thus, the description does not significantly enhance parameter understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches letu.ru with specific filters (pages, sorting, price, seller, stock). The verb 'search' and resource 'letu.ru' are explicit, and it distinguishes itself from siblings like get_product (which returns details for a specific product) and compare_products. It is not a tautology and is immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what the tool does and mentions that city affects delivery/stock, but it does not explicitly state when to use this versus alternatives, nor does it mention any exclusions. The purpose is clear enough that an agent can infer usage, but there is no direct guidance on when not to use it or when to prefer a sibling tool.
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.
5 tool updates
v0.1.0- First observed
compare_products - First observed
get_product - First observed
get_reviews - First observed
get_store_availability - First observed
search_products
TDQS
Scored across 5 tools
Each tool targets a distinct concern: search, product detail, reviews, store availability, and comparison. There is minimal overlap, and even the most similar tools (get_product vs compare_products) are clearly separated by purpose.
All tool names follow a consistent snake_case verb_noun pattern: search_products, get_product, get_reviews, get_store_availability, compare_products. The naming is predictable and makes the tool's action and target easy to identify.
Five tools is well-scoped for a retail product data server. Each tool covers a meaningful, non-redundant part of the shopping research flow without adding clutter or requiring excessive call chains.
The read-only product surface is well covered: search, full product details, reviews, store pickup, and comparison. Minor gaps exist such as no dedicated category/brand listing or bulk variant availability tool, but agents can accomplish the core workflows using the provided tools.
Maintenance
Related MCP Connectors
Web search, page reading and structured extraction for AI agents, with strong RU coverage
AI-agent product catalog: search, lookup & purchase routing over verified merchant data.
Agent-native product catalog: 300M+ products, 150,000+ stores, deliver_to ranking.
Russian company lookup (EGRUL/INN), Cyrillic search, RU page to Markdown. Pay per call in USDC.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables LLM agents to query live Wildberries marketplace data — product search with pages, sorting, price filters, per-article ratings and reviews, weekly price history, and seller legal details — with honest, sanity-checked answers and automatic anti-bot handling.5MIT
- AlicenseAqualityCmaintenanceEnables LLM agents to retrieve live, accurately-labelled product data from Ozon's public storefront, including search with pagination and sorting, all price variants, delivery dates, seller legal details, variants, and SKU-specific ratings and reviews, all without an Ozon account.4MIT
- AlicenseAqualityCmaintenanceEnables LLM agents to access live aliexpress.ru storefront data, including variant-specific ruble prices, order-accurate coupons, delivery quotes to Russian cities, seller info, and paginated buyer reviews with filters.4MIT
- AlicenseAqualityCmaintenanceEnables LLM agents to retrieve live, accurately labeled data from DNS (dns-shop.ru) — city-specific pricing, product search with filters, ratings, reviews, store stock, and price history — while avoiding common data misinterpretations.5MIT