Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Fordeal

REMOTE · FORDEAL.AI

Price comparison for CZ/SK: product prices, shops, digital plans via Streamable HTTP.

Available components

68 Trust /100

Last scanned (4 hours ago)

Scores higher than 53% of remote servers

Reachable. Last reached 5 Nov 2026.

Category E-commerce

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security63
Transport & Reachability100
Schema Quality & AI Usability71
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (good).Pass
  • Context-footprint check failed: tool/resource definitions use about 20213 tokens (~315/item across 64 items; 62 tools + 2 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management20
  • Stability observed for 6 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage95
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 84% of tool parameters carry a description.Partial
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • All 9 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 64 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 5 Nov 26 0
    • New tool “delete_my_account”, which the server declares destructive security
    • New tool “manage_price_watch”, which the server declares destructive security
    • New tool “sign_out”, which the server declares destructive security
    • Tool “add_to_list” rewrote its description, which is the text the model reads security
    • Tool “compare_energy” rewrote its description, which is the text the model reads security
    • Tool “digital_price_history” rewrote its description, which is the text the model reads security
    • Tool “find_best_price” rewrote its description, which is the text the model reads security
    • Tool “list_my_lists” rewrote its description, which is the text the model reads security
    • Tool “price_history” rewrote its description, which is the text the model reads security
    • Tool “remove_from_list” rewrote its description, which is the text the model reads security
    • Tool “save_favorite” rewrote its description, which is the text the model reads security
    • Tool “search_products” rewrote its description, which is the text the model reads security
    • Schema quality: 18271 → 20213 ▼ functional
    • New tool “get_my_profile” functional
    • New tool “price_watch_status” functional
    • New tool “update_my_profile” functional
    • “add_to_list” added an optional parameter “digital_id” cosmetic
    • “daily_deals” added an optional parameter “locale” cosmetic
    • “price_history” added an optional parameter “locale” cosmetic
    • “remove_from_list” added an optional parameter “digital_id” cosmetic
    • “save_favorite” added an optional parameter “deliver_to_country” cosmetic
    • “search_products” reworded the description of “brand” cosmetic
    • “add_to_list” made “product_slug” optional cosmetic
    • “remove_from_list” made “product_slug” optional cosmetic
    • Tool “add_to_list” changed its title: Add a product to a named list → Add a product or a digital plan to a named list cosmetic
    • Tool “remove_from_list” changed its title: Remove a product from a named list → Remove a product or a digital plan from a named list cosmetic
  • 4 Nov 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 13 to 17. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 5 at this one. The score rises as the window fills, whether or not the server changes.

  • 3 Nov 26 0
    • Tool “compare_energy” rewrote its description, which is the text the model reads security
    • New tool “watch_product_price” functional
    • “search_products” reworded the description of “attr” cosmetic
    • “search_products” reworded the description of “facets” cosmetic
  • 2 Nov 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

  • 31 Oct 26 0
    • Stability: unverified → 0.03 ▲ functional
  • 30 Oct 26 66

    First indexed and scored.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 5 Nov 2026 · Probed https://fordeal.ai/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=fordeal.ai CN=YE1,O=Let's Encrypt,C=US 15 Oct 2026 13 Jan 2027 ECDSA 256 ECDSA-SHA384 61df9cbd8d6691f206711da9209dd904ebf
SANs: *.fordeal.ai, fordeal.ai
CN=YE1,O=Let's Encrypt,C=US (CA) CN=Root YE,O=ISRG,C=US 3 Sept 2025 2 Sept 2028 ECDSA 384 ECDSA-SHA384 5ddd70dd31f801c85c186a7a04b80afe
CN=Root YE,O=ISRG,C=US (CA) CN=ISRG Root X2,O=Internet Security Research Group,C=US 13 May 2026 2 Sept 2032 ECDSA 384 ECDSA-SHA384 872165fc34b6e5fba8add5b3705fb53a
CN=ISRG Root X2,O=Internet Security Research Group,C=US (CA) CN=ISRG Root X1,O=Internet Security Research Group,C=US 13 May 2026 2 Sept 2032 ECDSA 384 SHA256-RSA 6c8f1dc727c7117f7baf853ac980f9cd

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of fordeal.ai. — Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
ai. present 1814, 3799 8, 8 Verified
fordeal.ai. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200
Header Value
strict-transport-security max-age=63072000; includeSubDomains; preload
content-security-policy default-src 'none'; frame-ancestors 'none'
x-content-type-options nosniff
x-frame-options DENY
referrer-policy no-referrer
permissions-policy camera=(), microphone=(), geolocation=()

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://fordeal.ai/mcp Verified 200
http (plaintext) http://fordeal.ai/mcp HTTPS enforced 301 https://fordeal.ai/mcp
MCP tools · 62 exposed · ~19,653 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
add_to_list ~276

Adds a product (`product_slug`) or a digital service plan (`digital_id`, a plan id of compare_digital / compare_mobile, e.g. claude-pro) to one of the signed-in person's lists with an optional private note; send exactly one of the two. For a product its total for `deliver_to_country` today is kept as saved_total (for "the price changed since you saved it"); a plan keeps no saved price. Adding it again only changes the note. At most 200 items per list. Another person's list answers not_found.

NameTypeReqDescription
deliver_to_countrystring–ISO 3166-1 alpha-2 country code, e.g. "CZ". Optional: normally derived from the address.
digital_idstring–A plan id of compare_digital / compare_mobile rows (e.g. claude-pro).
list_idstringyesThe list's id from list_my_lists.
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
note––A private note to the product (at most 280 characters); never shown on the share link.
product_slugstring–The product's slug (search_products, find_best_price).

No output schema declared.

No examples provided.

api_price_breakdown ~484

What a month of AI API use costs per bill item for every model we compare (or one provider / chosen models): fresh input, input read from the cache, input written into the cache, output, and the total, per request and per month in the price list's currency (USD) and in the buyer's currency by the Czech National Bank rate (fx_date), each item's whole-percent share, every other item the price list names (batch discount and whether it applied, the dearer long-prompt band and whether the request is in it, the context window, cache_write_not_stated when the price list names no write price and writes were billed as ordinary input), what is included, and the official source_url with verified_on. Default scenario: 1 000 requests a month, 1 500 input and 600 output tokens each, 40 % of the input read from the cache and 10 % written; every field can be changed. Nothing is estimated beyond the stated prices.

NameTypeReqDescription
batchstring–Batch processing at the provider's batch discount, where it offers one.
cache_sharenumber–Share of the input read from the cache (0-1). Default 0.4.
cache_write_sharenumber–Share of the input written into the cache (0-1, with cache_share at most 1). Default 0.1.
currencystring–Override the local currency.
deliver_to_countrystring–The buyer's country; decides the local currency.
input_tokensinteger–Input tokens of one request. Default 1 500.
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
messages_per_monthinteger–Requests a month. Default 1 000.
modelsstring–Comma-separated plan ids from /digital/plans (category ai-api), e.g. claude-sonnet-5-5.
output_tokensinteger–Output tokens of one request. Default 600.
providerstring–Only this provider's models (Anthropic, OpenAI, Google, DeepSeek, Mistral, xAI, AI21 Labs, Amazon...), case-insensitive.

No output schema declared.

No examples provided.

cancel_energy_watch ~44

Deletes the watch behind a token from any watcher e-mail (confirmation or alert). The row is gone at once; the token stops working.

NameTypeReqDescription
tokenstringyes–

No output schema declared.

No examples provided.

cheaper_abroad ~189

Products whose cheapest total (goods + shipping + FX to `deliver_to_country`) comes from a shop abroad and beats the cheapest domestic offer, with the saving in the deliver-to currency (`saving_kind: "estimate"`: the difference at the prices and shipping captured at `captured_at`, with `saving_basis`; present it as an estimate, never a guaranteed result). Cross-border offers carry EU warranty and returns but support may be in another language; find_best_price shows the `cross_border` block for one product.

NameTypeReqDescription
deliver_to_countrystring–ISO 3166-1 alpha-2 country code, e.g. "CZ". Optional: normally derived from the address.
limitinteger––
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.

No output schema declared.

No examples provided.

check_shop_feed ~596

Before or instead of registering: reads one product feed and answers whether Fordeal can use it. Give the feed's public address in `feed_url` (read through the SSRF guard: public hosts only, FordealBot, robots.txt respected, 20 s cap) or the file itself in `feed_content` (XML or CSV text, at most 8 MB) or `feed_base64` (a gzip-packed file; ZIP is refused), plus the shop's delivery `country` and, with a file, its `domain`. The answer: health ok | warn | fail, counts (items, skipped, with EAN, price, picture, availability, shipping, category), coded issues (no_items, items_skipped, feed_unreadable, price_zero, currency_mismatch, url_not_shop_host, duplicate_item_id, encoding_suspect, price_outlier, missing_ean, availability_unknown, shipping_missing, image_missing, category_missing, stale_feed) with the first affected items by the shop's own id and name, `blocking` = the error codes to fix first, `validation` = the required-field check (title, price, URL, EAN) in Czech sentences for Heureka, Zboží, Google and CSV feeds, and `preview.shown` = the first items as the comparison would show them (goods price, shipping to the country from the feed, total, stock, picture, what each lacks). Nothing is stored and nothing is mailed. A feed that cannot be read answers health fail with `read_error` {code, message, fix}. Next: register_shop with the same feed. Public; ten checks a minute per caller.

NameTypeReqDescription
countrystringyesThe shop's delivery country (ISO code from GET /api/v1/deals/countries): its currency and the shipping the total uses.
domainstring–The shop's host, e.g. www.obchod.cz; required with a file, the feed's host by default.
feed_base64string–The feed file's bytes as base64, for a gzip-packed file (.xml.gz). ZIP is refused.
feed_contentstring–The feed file as text (XML or CSV), at most 8 MB. Over MCP the whole request is limited to 2 MB; send bigger files to POST /api/v1/shops/feed-check.
feed_urlstring–The feed's public address (Heureka, Zboží, Google Merchant, Ceneo, Idealo, Árukereső XML or CSV). Either this or a file.
filenamestring–The file's name, echoed back.
formatstring–The feed format when known; detected from the content otherwise.
preview_itemsinteger–How many items the preview shows (default 6, at most 24).

No output schema declared.

No examples provided.

compare_digital ~1,126

Prices of digital services for a buyer's country, cheapest first, from the providers' official price lists (each row has source_url and verified_on) converted to the buyer's currency by the Czech National Bank rate (fx_date). Categories: ai-chat (ChatGPT, Claude, Gemini, Copilot, Perplexity, Grok, Mistral Vibe, GitHub Copilot, Cursor, Jasper, DeepL… subscriptions), ai-api (price per 1M input and output tokens of the main models: OpenAI, Anthropic, Google, Mistral, xAI, DeepSeek, AI21, Amazon Nova), ai-creative (Midjourney, Runway, Kling, Leonardo, Canva, Firefly, ElevenLabs, Suno… per month, per picture or second of video when stated), streaming, music, vpn, cloud, office (Microsoft 365, Google Workspace, Zoho, Notion, Slack, Zoom… personal, family and business per user; business prices usually exclude VAT), creative (Adobe Creative Cloud, Canva, Figma, CapCut, DaVinci Resolve Studio… monthly, yearly or a one-time purchase: such a row has oneTimeLocal instead of a monthly price), passwords (1Password, Bitwarden, Dashlane). `usage` turns the list into a cost of that use: for ai-api messages_per_month (+ input_tokens and output_tokens per message, default 1 500 and 600) (+ cache_share 0–1 and batch) gives usage_cost a month, usage_breakdown (input, cached input, output; whether the long-prompt band or the batch discount applied) and break_even_messages (below it the API is cheaper than the provider's cheapest paid chat plan); for ai-creative images_per_month and video_seconds_per_month. A null price means the official page did not show one; it is never guessed. Each row carries data_location from the provider's own privacy policy (controller, storedIn country codes, inChina, authoritiesClause, quote, url, checked), null when we have not read it. Where the same plan is also sold inside the app (inAppPrices: the App Store's price for the buyer's country, with VAT, verifiedOn and sourceUrl), inApp compares a month on the web (the price list's price, plus the country's V…

NameTypeReqDescription
batchstring–Flat form of usage.batch (true / false).
cache_sharenumber–Flat form of usage.cache_share.
categorystringyesai-chat | ai-api | ai-creative | streaming | music | vpn | cloud | office | creative | passwords
currencystring–Override the currency (e.g. EUR for a Czech buyer).
deliver_to_countrystring–The buyer's country; decides the currency and the local prices (CZ prices for CZ). Default: the first compared country.
images_per_monthinteger–Flat form of usage.images_per_month.
input_tokensinteger–Flat form of usage.input_tokens.
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
messages_per_monthinteger–Flat form of usage.messages_per_month (REST query strings).
output_tokensinteger–Flat form of usage.output_tokens.
purposestring–ai-chat: what the buyer needs it for. coding = plans whose page states an agent or coding tool, images / voice / video = plans whose page states that feature, writing = every plan. A feature the page…
tierstring–Only plans of this tier: free | basic | pro | max (AI subscriptions and picture/video tools), basic | standard | premium (streaming, music, VPN, cloud). Compare plans only within one tier.
usageobject–How the buyer uses the service; omit for the plain price list.
video_seconds_per_monthinteger–Flat form of usage.video_seconds_per_month.

No output schema declared.

No examples provided.

compare_energy ~1,852

An indicative calculation, not yet checked by an independent expert (verified: false): present the result as an estimate, never as a guaranteed price; show estimate_note (the sentence with the day of the data, in `locale` cs | sk | en) with every result. Household electricity and gas offers (Czechia for now) ranked by the yearly bill for a stated consumption in one distributor's area, with VAT. The bill is split into the regulated part (distribution, system services, renewables support, market operator, tax: set by the energy regulator for the distributor, the same with every supplier) and the supplier part (commodity price and monthly fee: what switching changes). Every offer has the supplier's official price list (source_url, verified_on, valid_from) and says whether the price is fixed (fixed_months or fixed_until) or variable. Spot and formula prices are never ranked; they are listed in not_ranked. Offers whose price list was read only for another distributor's area are left out. Electricity: distributor (cez-distribuce | egd | pre-distribuce), rate (D01d, D02d, D25d, D26d, D27d, D35d, D45d, D56d, D57d, D61d), mwh = yearly high-tariff (or all) consumption, nt_mwh = low-tariff consumption; breaker = main breaker (1x25, 3x10, 3x16, 3x20, 3x25 default, 3x32, 3x40, 3x50, 3x63; it sets the fixed monthly distribution price from the regulator's table); postcode (5 digits) instead of distributor picks the distributor area as an estimate (area.estimate = true; two candidates when the postcode spans an area boundary: then pass distributor). Every result is an estimate (result_type: estimate, guaranteed: false): the binding bill depends on the actual consumption, the distributor stated on the bill and the contract. Gas: distributor (gasnet | gas-distribution | ppd), mwh = yearly consumption up to 63 MWh; postcode instead of distributor picks the gas area the same way (estimate; two candidates around Prague or on an area boundary: then pass distributor). Call without a dist…

NameTypeReqDescription
breakerstring–Electricity main breaker: 1x25 | 3x10 | 3x16 | 3x20 | 3x25 (default) | 3x32 | 3x40 | 3x50 | 3x63.
commoditystring–electricity (default) | gas
comparestring–Comma-separated offer ids (2–3) for a side-by-side comparison in `comparison`.
countrystring–CZ (default).
current_fee_monthnumber–Today's monthly fee of the supplier (stálá platba).
current_monthlynumber–What the household pays today a month with VAT (the current advance), in the country's currency. Each offer then carries saving_year = current_monthly × 12 − total_year (positive = cheaper than today…
current_nt_pricenumber–Today's low-tariff commodity price per MWh (two-tariff electricity rates; required when nt_mwh > 0).
current_offerstring–Id of the household's current product from `products` (energy v2): today's yearly total is then priced from that price list for the same need, and saving_year compares like with like (saving_basis: o…
current_prices_vatstring–Whether current_*_price and current_fee_month include VAT: excluded (default, as price lists state them) | included (as a bill often shows them).
current_vt_pricenumber–Today's commodity price per MWh from the household's bill or price list (electricity: high tariff or all; gas: the gas price). With current_fee_month it gives today's yearly total (saving_basis: own_…
distributorstring–Distributor of the place: electricity cez-distribuce | egd | pre-distribuce; gas gasnet | gas-distribution | ppd.
fixationstring–Filter, one of none | 12 | 24 | 36: none = variable price without fixation; 12 / 24 / 36 = fixed price up to 1 / 2 / 3 or more years.
greenstring–Filter, true: only products whose price list states electricity of renewable origin (none stated yet).
householdstring–Household type (energy v3) instead of rate + consumption: electricity byt | chata | bojler | akumulace | elektromobil | tepelne-cerpadlo | elektricke-topeni; gas plyn-vareni | plyn-voda | plyn-byt |…
limitinteger––
localestring–Language of estimate_note: cs | sk | en (default en).
mwhnumber–Yearly consumption in MWh (electricity: high tariff or all; default 2.5 electricity, 10 gas).
no_penaltystring–Filter, true: only products whose terms state no fee for leaving (an indefinite term).
nt_mwhnumber–Electricity low-tariff consumption a year in MWh (two-tariff rates only).
postcodestring–Postcode of the supply point (e.g. 602 00), electricity or gas; picks the distributor when none is given. An estimate from the post's postcode list and the distributors' coverage by district.
pricingstring–Filter: fixed | variable (price-list products, ranked) | spot (market-price products: listed in not_ranked without a total, never ranked).
ratestring–Electricity distribution rate, e.g. D02d (default) or D25d (two tariffs).
sortstring–score (default: forDeal score, highest first) | price (yearly total, lowest first).

No output schema declared.

No examples provided.

compare_energy_from_bill ~382

An indicative calculation (verified: false, with estimate_note like compare_energy). Pass the values from the household's electricity or gas bill (as read by POST /api/v1/digital/energy/bill, by yourself from the document, or typed by a person) and get the same ranked answer as compare_energy: yearly totals of every priced offer for that distributor area, rate and breaker, with the saving against the bill's own prices (saving_basis: own_prices) or against the monthly advance. Consumption of a billed period other than a year is scaled to 365 days by period_days. Confirm the values with the person before calling; nothing is stored.

NameTypeReqDescription
breakerstring–Main breaker, e.g. 3x25.
commoditystringyeselectricity | gas
distributorstringyescez-distribuce | egd | pre-distribuce | gasnet | gas-distribution | ppd
fee_monthnumber–Supplier's monthly fee without VAT.
limitinteger––
localestring–Language of estimate_note: cs | sk | en (default en).
monthly_advancenumber–Monthly advance with VAT (used when the prices are missing).
nt_mwhnumber–Low-tariff consumption in MWh in the billed period.
nt_price_mwhnumber–Supplier's low-tariff price per MWh without VAT.
period_daysinteger–Days of the billed period (default 365).
ratestring–Electricity distribution rate, e.g. D25d.
vt_mwhnumberyesConsumption in MWh in the billed period: high tariff or all (gas: all).
vt_price_mwhnumber–Supplier's commodity price per MWh without VAT.

No output schema declared.

No examples provided.

compare_internet ~195

Compare provider-level home internet summaries from docs/data/internet.json. Filter by country, technology, advertised speed, listed monthly price, commitment duration, or provider; sort by price, indicative price per advertised Mbps, or speed. Each result includes the provider's address-availability checker and source links. This source contains summarized ranges, not individual address quotes; unknown values stay null, and availability must be confirmed with the provider.

NameTypeReqDescription
commitment_monthsinteger––
countrystringyesISO 3166-1 alpha-2 country code, e.g. "CZ". Optional: normally derived from the address.
limitinteger––
max_pricenumber––
min_pricenumber––
min_speed_mbpsnumber––
offsetinteger––
providerstring––
sortstring––
technologystring––

No output schema declared.

No examples provided.

compare_mobile ~262

Compare the sourced CZ and SK mobile tariff records in docs/data/mobilni-tarify.json. Filter by country (required), operator, minimum data, unlimited calls, commitment, eSIM and 5G; legacy needs filters for minutes, SMS, no commitment and EU roaming also work. Sort by listed monthly price or the sourced price per GB. Every result includes its source URL, checked date and quote. Unknown values remain null and never satisfy positive filters.

NameTypeReqDescription
commitment_monthsinteger––
countrystringyesCZ | SK; required so results and currency stay within one market.
data_gbnumber–GB of mobile data a month (default 0).
esimboolean––
five_gboolean––
limitinteger––
minutesinteger–Call minutes a month (default 0).
no_commitmentboolean–Only tariffs without a contract period.
operatorstring––
roaming_eu_gbnumber–EU roaming data needed a month.
smsinteger––
sortstring––
unlimited_callsboolean–Filter to tariffs with unlimited calls (true), or explicitly finite calls (false).

No output schema declared.

No examples provided.

confirm_energy_watch ~48

The double opt-in click: the confirmation token from the first watcher e-mail turns the watch on. Only the person who received the e-mail holds the token.

NameTypeReqDescription
tokenstringyes–

No output schema declared.

No examples provided.

create_list ~109

Creates an empty private list (e.g. Narozeniny, Nová kuchyň) in the signed-in person's account; add products with add_to_list. At most 50 lists per person.

NameTypeReqDescription
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
namestringyesThe list's name, e.g. Narozeniny (1 to 80 characters).

No output schema declared.

No examples provided.

daily_deals ~402

Discounts at rated shops today, biggest absolute saving first: with 30 days of our own history for the offer, the discount is measured only against its lowest price in the 30 days before the reduction (EU Omnibus, CJEU C-330/23; discount_basis "lowest_30d", price_before = lowest_30d); until that history exists, only against the old price the shop itself states (discount_basis "shop_stated", not verified by us, at most 50 %). Never an average or other shops' prices. For one country, optionally one category of any level and a minimum percent. for one country and optionally one category slug (from the deal categories). Shops on a risk list and shops without a rating are never included. Each row carries the current price, the previous price, the drop, the shop with its trust label and the capture time. Next: find_best_price with the product name for the full comparison.

NameTypeReqDescription
categorystring–Category slug of any level of the tree, e.g. mobily, elektronika, televize.
countrystring–Country of the shops. Default: the first compared country.
limitinteger––
localestring–Language of `product.url` (/cs/p/…, /sk/p/…) and the parameters. Defaults to the default locale of `country` (CZ cs, SK sk).
max_per_shopinteger–Shop diversity: the first 48 rows take the shops in turns, at most this many rows per shop; the rest follows by saving. The website asks 4.
min_percentnumber–Only discounts of at least this many percent.
stated_onlyboolean–Kept for compatibility; every row carries a struck price (the offer's 30-day low or, until 30 days of history exist, the shop's stated price), with or without it.

No output schema declared.

No examples provided.

delete_comparison ~43

Deletes one of the signed-in person's saved comparisons; its share link stops working.

NameTypeReqDescription
comparison_idstringyesThe comparison's id from list_my_comparisons.

No output schema declared.

No examples provided.

delete_list ~48

Deletes one of the signed-in person's lists with its products; its share link stops working. Another id answers not_found.

NameTypeReqDescription
list_idstringyesThe list's id from list_my_lists.

No output schema declared.

No examples provided.

delete_my_account ~199

Deletes the signed-in person's account and cannot be undone. Ask the person first and pass `confirm` = the account's e-mail exactly as they type it; without it nothing happens (validation, confirmation_required). In order: every session is revoked; every row of the account is deleted or anonymised in one transaction (favourites, lists and share links, comparisons, price watches including watches set without an account from the same e-mail, energy watches, reviews, devices, every queued or sent mail; error reports, page notices and the audit trail keep their text without the person); the sign-in itself is deleted; one last notice goes to the address. Answers deleted, scope, counts per table, notice and `what` (deleted / anonymised / kept). The token stops working.

NameTypeReqDescription
confirmstringyesThe account's e-mail, typed by the person as confirmation.
localestring–Language of the last notice.

No output schema declared.

No examples provided.

delete_price_watch ~55

Deletes one of the signed-in person's watches; no more mails for it. Only the token's own watches; another id answers not_found.

NameTypeReqDescription
watch_idstringyesThe watch's id from list_my_price_watches.

No output schema declared.

No examples provided.

digital_price_history ~245

Every recorded change of a digital plan's price, newest first: plan_id, verified_on (the day it changed), from and to (price and currency), source (person = confirmed against the official page in our review; catalog = the stored price list changed between two daily snapshots) and source_url. Recording started on tracking_since; nothing before it is known and nothing is back-filled, so an empty list means no change since tracking_since. An unchanged price renewed by the daily check is no change. Also rises: the price rises of the last 45 days (from -> to in one currency, period month | year, detected_on, source_url; status proposed = the official page shows the higher price and our list waits for confirmation, confirmed = our price list holds it; a yearly price is compared per month, two currencies never), and watch_coverage: how many priced plans a robot reads daily or weekly and which wait on the manual weekly list. Filter by plan (the id from /digital/plans).

NameTypeReqDescription
limitinteger–At most this many changes (default 100).
planstring–One plan id from /digital/plans.

No output schema declared.

No examples provided.

energy_price_history ~109

Development of household electricity and gas prices per kWh (Czechia), as published by Eurostat (semi-annual, all taxes and levies included, the most common consumption band), with the dataset link and the day it was fetched; never interpolated. Our own price-list readings start on own_history_since and are not yet a series. Use energy_unit_prices for today's price from the current price lists.

NameTypeReqDescription
commoditystring––
countrystring–CZ (default)

No output schema declared.

No examples provided.

energy_suppliers ~268

Facts from the suppliers' official price lists (verified: false: the yearly calculation built on them is not yet checked by an independent expert; estimate_note gives the sentence and the day of the price lists). Every household electricity and gas supplier of a country we know of (Czechia: 46), or one supplier with `id`: its official price-list page, whether we priced it (status priced | gap with the reason), its products with the prices of the official price lists (electricity: commodity price per MWh by rate and the monthly fee; gas: price and fee by consumption band; all without VAT, with source_url, valid_from and verified_on), whether each price is fixed and until when, and the bill guide (bill_guide: the customer portal and the steps to find and download the bill, from the supplier's own help page). Former suppliers (e.g. Bohemia Energy) are listed with what happened to their customers. No contract can be signed here and no link earns a commission.

NameTypeReqDescription
countrystring–CZ (default)
idstring–Supplier id from the list, e.g. cez-prodej.
localestring–Language of the bill guide steps: cs | sk | en (default en).

No output schema declared.

No examples provided.

energy_unit_prices ~308

An indicative calculation, not yet checked by an independent expert (verified: false); show estimate_note with the result. Price of one kWh with VAT for households of a country (Czechia for now), per distributor area, computed only from the energy regulator's tables and the suppliers' official price lists we read: regulated_kwh (variable regulated part: distribution of the rate, system services, renewables support, tax; the same with every supplier), supplier_kwh (commodity price: min, median, max over the priced offers), marginal_kwh (regulated + supplier: the cost of one more kWh, what an appliance costs to run) and all_in_kwh (the yearly total for `mwh` with every fixed fee spread over its kWh). Electricity for one rate (default D02d) and 2.5 MWh a year by default; gas for 9 MWh a year by default. Spot and formula prices are never counted. Use estimate_appliance_energy for an appliance's yearly cost.

NameTypeReqDescription
countrystring–CZ (default)
gas_mwhnumber–Yearly gas consumption for all_in_kwh, default 9.
localestring–Language of estimate_note: cs | sk | en (default en).
mwhnumber–Yearly electricity consumption for all_in_kwh, default 2.5.
ratestring–Electricity distribution rate, default D02d.

No output schema declared.

No examples provided.

energy_watch_status ~66

The watch behind a token from a watcher e-mail (the `t` of the link): status pending | confirmed, the end date, the day of the alert, the e-mail masked. Answers not_found when the watch was cancelled or deleted.

NameTypeReqDescription
tokenstringyes–

No output schema declared.

No examples provided.

estimate_appliance_energy ~358

An estimate (verified: false, estimate_note with the day of the prices). kind fridge: label_kwh_year from the EU energy label (kWh/annum). kind washer: kwh_per_100_cycles from the EU energy label and washes_per_week (default 4). kind heating: area_m2 and heat_need_kwh_m2 (specific heat need for heating from the building's energy performance certificate; references: passive house 20, low-energy house 50 kWh/m² a year by ČSN 73 0540-2), source direct | heat_pump | gas_boiler with scop (heat pump, default 3) or efficiency (gas boiler, default 0.9). Answers kWh a year and the yearly and monthly cost at the price of one more kWh (median marginal price in the distributor area from energy_unit_prices, or price_per_kwh if given); `defaults` names every value that was assumed.

NameTypeReqDescription
area_m2number––
countrystring–CZ (default)
distributorstring–Distributor area for the price (default: the first area with priced offers).
efficiencynumber––
heat_need_kwh_m2number––
kindstringyes–
kwh_per_100_cyclesnumber––
label_kwh_yearnumber––
localestring–Language of estimate_note: cs | sk | en (default en).
price_per_kwhnumber–Own price of one kWh with VAT instead of ours.
scopnumber––
sourcestring––
washes_per_weeknumber––

No output schema declared.

No examples provided.

find_best_price ~914

Where to buy a product cheapest today: offers ranked by the real product price (converted to the buyer's currency with a dated rate), the shipping to the buyer's country shown as its own value on every offer, and whether the shop can be trusted. `sort=total` (or include_shipping=true) orders by goods + shipping instead. `query` is free text ("washing machine under 12 000, 60 cm"), a model name, an EAN, or a product URL from any e-shop. Returns one card: `match` (exact | close: close means the nearest product is another variant than the query names, e.g. iPhone 16 Plus for "iPhone 16 256 GB"; `match_note` says how, `warnings` opens with it and `reasons` carries close_match; never present a close card as the asked-for item), verdict (buy_now | wait | buy_alternative | no_offer) with a headline and explanation in `locale`, the recommended offer `best` (shop, trust label verified | rated | unknown, rating 0-1, rating_url = the public page of the source that rating comes from or null, total.goods = the product price and total.shipping in the deliver-to currency, total.total = their sum, FX date, capture time), `cheapest_total` (the offer with the lowest total including shipping), three alternatives (cheapest domestic, cheapest cross-border, best rated), every shown offer with its blockers and `price_status` (verified = goods + stated shipping, the sum the buyer pays; estimate = the shop states only its lowest "from" shipping rate; incomplete = shipping to the country unknown or import duties open, a lower bound that is never the cheapest), a 90-day price history, and `commission_disclosure`. Every offer carries `labels` (lowest_price = the lowest product price; recommended = `best` when it is dearer than that, never call it the cheapest; lowest_verified_total = the cheapest total with a stated, not "from", shipping), `shipping_is_estimate` (a "from" or unknown shipping, the total then a lower bound, or the shop's general shipping rule: an estimate for this item), `shipp…

NameTypeReqDescription
budgetnumber–Budget in the deliver-to currency; a total above it turns the verdict into buy_alternative.
deepboolean–Let the model weigh the verdict and write the explanation (adds seconds). Default false: stored prices and the rules answer in under 2 s; `refresh_pending` true means the shops are being asked again…
deliver_to_countrystring–Where the buyer wants delivery (ISO 3166-1 alpha-2). Default: the first compared country.
include_shippingboolean–Same as sort=total: count shipping in the order (the website's "Zahrnout dopravu"). Default false.
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
querystringyesProduct name, model, EAN, or a product URL.
sortstring–Order of `offers` and the price `best` is chosen by: product = lowest product price (the default; every offer still carries its shipping and total), total = lowest total with shipping to `deliver_to_…
verified_onlyboolean–Only shops with a customer rating.

No output schema declared.

No examples provided.

get_my_profile ~132

The profile of the person whose Supabase access token is sent (an agent API key is refused): id, email, name (shown with reviews), locale (language of our e-mails), country (market: the delivery country they compare for), watch_emails (false = every price-watch e-mail paused; security notices are always sent), how many price watches are active and paused, created_at, last_sign_in_at and `markets` to choose from. `deletion` says in words what delete_my_account removes, anonymises and keeps. Next: update_my_profile, sign_out, delete_my_account.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

get_product ~406

The same card as find_best_price and the website's product page /{locale}/p/{product}, for a product id you already hold (`product.slug` / `product.variant.id` from search_products, find_best_price or product_variants), without reading a query: no risk of landing on another variant. `product.variant` names the variant (storage, colour, model words, connectivity, size, `family_id` shared by its siblings). Answers from stored prices with the rule-based verdict; every offer carries `source_name`, `captured_at`, `blockers`, and the card `reasons` and `warnings`. An unknown id is `error.code` not_found. Next: product_variants for the other capacities or colours, price_history for the trend.

NameTypeReqDescription
aiboolean–Also run the shops live and let the model write the verdict (slower). Default false: stored prices and the rules.
deliver_to_countrystring–Where the buyer wants delivery (ISO 3166-1 alpha-2). Default: the first compared country.
include_shippingboolean–Same as sort=total: count shipping in the order (the website's "Zahrnout dopravu"). Default false.
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
productstringyesProduct slug (the stable product id), e.g. apple-iphone-16-128-gb.
sortstring–Order of `offers` and the price `best` is chosen by: product = lowest product price (the default; every offer still carries its shipping and total), total = lowest total with shipping to `deliver_to_…
verified_onlyboolean–Only shops with a customer rating.

No output schema declared.

No examples provided.

get_shop_feed_diagnostics ~221

The report of a compared shop's last feed read (P04): health ok | warn | fail, counts (items, with EAN, price, picture, availability, shipping, category), and coded issues (no_items, items_skipped, feed_unreadable, price_zero, currency_mismatch, url_not_shop_host, duplicate_item_id, encoding_suspect, price_outlier, missing_ean, availability_unknown, shipping_missing, image_missing, category_missing, stale_feed) each with a count, a share and the first five affected items by the shop's own item id and name. Public: no feed address, no item links (the partner's signed-in view at GET /api/v1/partner/feed-diagnostics carries the item links). `error.code` not_found when the shop is unknown or has no feed run yet. For a feed that is not compared yet use check_shop_feed.

NameTypeReqDescription
slugstringyesThe shop's slug from list_shops or GET /api/v1/deals/shops.

No output schema declared.

No examples provided.

get_shop_registration ~157

What happened to a registration (register_shop answers `id`; the id is the key, nothing else is needed): status diagnosing | received | approved | rejected | active, whether the contact confirmed, the decision with its reason and when, where the feed came from (`feed_source` url | upload, and the upload's fingerprint), the public feed report (health, summary, counts, the first issues without item links), `next` = what happens now, and the shop's page once it exists. The contact e-mail and the feed address are never returned. Older requests of the feeds-job flow answer their own statuses (pending, feed_found, …). Public.

NameTypeReqDescription
idstringyesThe request id from the registration answer.

No output schema declared.

No examples provided.

get_shop_statistics ~228

How many people Fordeal sent to the shop in a window of UTC days (`from`/`to` YYYY-MM-DD, both included; the last 30 days by default, at most 366): the total, every day (zero days included), per delivery country and per channel (web | mcp | api | social). Only counted clicks of people from click_log: robots and the partner's test clicks are left out and reported in `excluded`; no orders or revenue are estimated (own-programme orders are in the partner portal). `truncated: true` when the window held more than 50 000 rows (the numbers are then a lower bound). Needs the signed-in person's Supabase access token and a shop of list_my_shops; another shop answers 403.

NameTypeReqDescription
fromstring–First UTC day (YYYY-MM-DD); 29 days before `to` by default.
shopstringyesThe shop's slug from list_my_shops.
tostring–Last UTC day (YYYY-MM-DD); today by default.

No output schema declared.

No examples provided.

insurance_guide ~571

An information comparison, not a ranking (prices: false, ranking: false, score: null): Fordeal is not an insurance intermediary, sells no insurance, shows no premium and recommends no policy. For a country (CZ for now) it answers the kinds of insurance (motor third-party liability, comprehensive motor, home contents, property, travel, personal liability, accident, life, legal protection, health insurance for foreigners, other) with the four things to compare besides the price, and `cards`: one per insurer with the kinds its public site offers, the products in the insurer's words (products: name, kind, online), the kinds that can be concluded online on the official site (online_kinds; online_unknown_kinds = the site does not say), a nonstop assistance line, a mobile app and an online claim form, each a fact {value: true | false | null, note, source_url, checked_on} where null means the site does not state it (never a no), the IČO from the ČNB register (registry; cross_border: true for an offer without a Czech IČO), the public customer rating (source: Firmy.cz or Google Maps by its link; score, scale, count, source_url, fetched_on; only from 10 reviews, otherwise null = no rating yet), factual tags and the official website (commission: false, affiliate: false, no tracking parameters). Filters: kind, online (online for the asked kind), assistance, app, claim_online (true); filter_counts says how many insurers each option leaves. sort: name (default, alphabetical) | rating (public rating from the highest, insurers without a rating last) | kinds (number of kinds offered). compare = 2–3 insurer ids for `comparison` side by side. Tell the person to read the terms on the insurer's site; the premium and the contract are the insurer's.

NameTypeReqDescription
appstring–true: only insurers with an official mobile app for clients.
assistancestring–true: only insurers whose site states a nonstop (24/7) assistance line.
claim_onlinestring–true: only insurers whose site takes a claim report online.
comparestring–Comma-separated insurer ids (2–3) for `comparison`.
countrystring–CZ (default).
kindstring–Only the insurers of this kind of insurance.
localestring–Language of the guide URLs (cs | sk | en …, default cs).
onlinestring–true: only insurers whose official site concludes the asked kind (or any kind) online.
sortstring–name (default) | rating | kinds. Never a recommendation.

No output schema declared.

No examples provided.

list_coupons ~311

Coupon codes and promotions of compared shops, valid today, from the affiliate network eHUB (refreshed every 3 hours; never from newsletters or e-mails, never a shop on a risk list). For one country (the shop's country), the soonest ending first. Each row: the shop, `type` voucher (has a `code`) | action (no code), the advertiser's `title`, `discount` read from it (percent or amount with currency; `up_to` = "up to"; null when the text states no size of the discount, never a guess), `min_order` {amount, currency} when the text names a minimum order ("nákup nad 1 000 Kč"; it is never the discount), `valid_from`, `valid_until` (a date = the whole day), `url` the network's tracked link (Fordeal earns a commission on a purchase through it; the ranking never depends on it), `image` the card photo with `image_source` "shop_product" (a product of the shop's own offers in its main `category`) or "category" (our picture of that category; null = none, show `logo_url`), and `fetched_at` of the list. Next: find_best_price with a product name to compare the shop's prices.

NameTypeReqDescription
countrystring–Country of the shops. Default: the first compared country.
limitinteger––

No output schema declared.

No examples provided.

list_my_comparisons ~88

Comparisons the person saved (2 to 4 digital plans each), newest first, with the page address and, when the person chose to share one, its share link. Private unless `shared: true`.

NameTypeReqDescription
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.

No output schema declared.

No examples provided.

list_my_favorites ~63

Products (kind product, by slug, with the total saved at that time) and digital plans (kind digital, by plan id) the person saved with the heart, newest first. Needs the person's access token. Live prices: search_products / compare_digital.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

list_my_lists ~165

Every named list of the person whose Supabase access token is sent (Authorization: Bearer <token>; an agent API key is refused), oldest first, each with its items (newest first): products (kind product, the private note and the total saved at that time) and digital plans (kind digital, `digital_id` = plan id of compare_digital / compare_mobile, note only), and the share link when the person chose to share it. The heart's favourites are separate: list_my_favorites. Live prices: GET /api/v1/deals/products?slugs=.

NameTypeReqDescription
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.

No output schema declared.

No examples provided.

list_my_price_watches ~172

Every price watch of the person whose Supabase access token is sent (Authorization: Bearer <token>; an agent API key is refused). Each row: id, product, status (active | paused), target_total and saved_total (the total when the watch was set or of the last alert; alerts fire only below it), the delivery country and currency, last_alert_at and `current` = today's total for that country (goods + shipping, shop, captured_at; recommended: false when no offer passes the trust rules). Next: update_price_watch to pause, resume or change the target, delete_price_watch to cancel.

NameTypeReqDescription
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.

No output schema declared.

No examples provided.

list_my_shops ~135

The shops whose numbers the signed-in person may read: a contact of a shop in Fordeal's own affiliate programme whose partnership the operator approved and whose domain is proven (`access: partner`; a pending partner sees nothing here), or the contact e-mail of a registration the operator approved (`access: registration`). Needs that person's Supabase access token (Authorization: Bearer <token>, the website holds it after the e-mail sign-in link); an agent API key is refused. Each row: slug, name, domain, country, status, access, the shop's page. Next: get_shop_statistics with a slug.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

list_shops ~94

The shops whose prices flow today for a delivery country (with their rating 0..1, rating source and trust label) and the shops still waiting for their feed. Use it to answer "can I trust shop X" or "do you compare shop Y".

NameTypeReqDescription
countrystring–ISO 3166-1 alpha-2 country code, e.g. "CZ". Optional: normally derived from the address.

No output schema declared.

No examples provided.

manage_price_watch ~258

The buttons of /{locale}/hlidac, one action on the one watch the signed token names, no sign-in: `confirm` (only the confirmation token of watch_product_price: the person's double opt-in click, an agent passes it only on the person's word), `pause` / `resume`, `set_target` with `target_total` (in the watch's currency; null = any real drop) and `cancel` (deletes the watch and its trigger history; switched off in one call, repeated calls answer status cancelled). The pause link is also the List-Unsubscribe one-click address of every alert. Answers the watch as price_watch_status shows it.

NameTypeReqDescription
actionstringyes–
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
tstringyesThe `t` parameter of the link in a price-watch mail (/{locale}/hlidac?t=…): the signed token of that one watch.
target_total––For set_target: the new limit in the watch's currency (goods + shipping); null = any real drop under the saved total.

No output schema declared.

No examples provided.

price_history ~373

Daily lowest price of a product across compared shops for up to 365 days (the last point, today, is the product price the product page shows as its main price), plus every current offer with its capture time. `product` is the slug from find_best_price (`product.slug`) or a product id. Use it to say whether today's price is a low, and how much it moved. `price_verdict` {level low|usual|high|short_history|stale, percentile, days, basis} rates the latest price against the last 90 days of our own captured daily lows (no judgement under 14 days; never a discount claim; is_lowest wins: the lowest price of the period is never recently_cheaper; recently_cheaper = more than 8 % above the 30-day low); `advice` (lowest | low | recently_cheaper | usual | high | short | sparse | stale) is the one key derived from it, and find_best_price carries the same object, the same advice and a verdict that never contradicts it (wait only with recently_cheaper, or in the sale season above a lower price of the period). Next: find_best_price for the current recommendation.

NameTypeReqDescription
currencystring–Currency of the points. Default: the currency of the first offer.
daysinteger–Window in days. Default 365.
deliver_to_countrystring–Country whose shown price is the last point (today). Default: the country of the currency.
localestring–Language of `product.url` and the parameters, e.g. "cs", "sk". Defaults to the default locale of `deliver_to_country`, else "en".
productstringyesProduct slug or id from find_best_price.

No output schema declared.

No examples provided.

price_watch_status ~201

What the link in a price-watch mail opens (/{locale}/hlidac?t=…), without an account: the product, status (pending | active | paused | cancelled), target_total and saved_total in the watch's currency, the delivery country, last_alert_at and `last_trigger` (when the watch last fired: total, target, shop and the captured_at of that price; null before the first), and `purpose` manage | confirm (the confirmation link of watch_product_price). No e-mail address, no other watch. Next: manage_price_watch with the same token.

NameTypeReqDescription
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
tstringyesThe `t` parameter of the link in a price-watch mail (/{locale}/hlidac?t=…): the signed token of that one watch.

No output schema declared.

No examples provided.

product_rows ~368

The rows the website shows above the full product list (/produkty) for a buyer country, each a list of up to 12 products with the same summary fields as search_products: `deals` (today's price drops; discount against the offer's lowest price of the 30 days before the drop when 30 days of its history exist, else against the shop's own stated price; never an average), `trending` (trend = (1 + interest) × 0.5^(age_days / 14), interest = searches, product-page views and shop clicks of the last 30 days, age = days since the product entered the catalogue; 2+ shops only) and the seasonal rows of the buyer country's calendar (Black Friday, Christmas gifts by budget and for whom, Valentine's, Mother's Day, Father's Day, back to school, summer), e.g. `christmas:budget-500` or `christmas:for_her`. No product stands in two rows, one shop is behind at most 3 cards of a row, a row under 4 products is left out. `formulas` states every rule; `seasons` the active windows. `date` (YYYY-MM-DD) reads the calendar of another day with today's products. Next: get_product with a product slug for the full comparison.

NameTypeReqDescription
datestring–The day the seasonal calendar is read for (default today).
deliver_to_countrystring–ISO 3166-1 alpha-2 country code, e.g. "CZ". Optional: normally derived from the address.
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.

No output schema declared.

No examples provided.

product_variants ~224

The variants of one product, each with a stable `id` (its product slug), `current` (true for the one asked for, always listed), storage, size, colour and `color_id`, its lowest total for `deliver_to_country` and stock. `family_id` names the set (a garment's item group, or the model line `line:<words>`), `axes` says what tells them apart. Use it to switch from a card to the exact variant the buyer asked for, then get_product with that id. A product without siblings answers itself only. Mirrors GET /api/v1/deals/products/{slug}/variants.

NameTypeReqDescription
deliver_to_countrystring–ISO 3166-1 alpha-2 country code, e.g. "CZ". Optional: normally derived from the address.
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
productstringyesProduct slug (the stable product id).

No output schema declared.

No examples provided.

register_shop ~763

One call registers a shop (P01): name, domain, delivery country, contact e-mail, the feed (its address in `feed_url`, or the file in `feed_content` / `feed_base64`), how commission is paid and the accepted partner terms version. An address is read at once through the SSRF guard (public hosts only, 422 url_rejected otherwise) with a 12 s cap; a file is decoded (at most 8 MB, gzip allowed, ZIP refused: 422 upload_zip_unsupported, 413 upload_too_large) and only its sha-256 and size are kept. Either way the feed is diagnosed (P04) and the 202 answer carries `feed.health` ok | warn | fail with the top three issues; the full report is stored on the request, `feed_source` says url or upload. One open request per domain: a second call updates it and answers the same id with `duplicate: true`; a declined domain may register again. The contact gets the `shop_registration_received` mail (its language: `locale`, else the country's default) with the confirmation link and the status page; the operator gets one notice. `verification.ownership` carries the token for the meta tag or file proof (verify_shop_domain). A shop on the ČOI / SOI risk list is refused (403). A registration never lists a shop by itself: the operator decides. A shop registered with a file only is listed as still being added until it sends a feed address. Follow it with get_shop_registration. Six calls a minute per caller.

NameTypeReqDescription
accept_termsbooleanyestrue = the contact accepts the partner terms of the given version.
affiliatestringyesHow commission is paid: "own" = forDeal's own programme (5 % of the net order value, partner portal), a network name the country lists (ehub, cj, awin, dognet, …), "other", or "none".
countrystringyesDelivery country of the shop, ISO 3166-1 alpha-2 from GET /api/v1/deals/countries.
domainstringyesThe shop's domain or URL, e.g. www.obchod.cz.
emailstringyesContact e-mail of the shop; it receives the confirmation link and the decision. Never shown.
feed_base64string–The feed file's bytes as base64, for a gzip-packed file (.xml.gz, .csv.gz). ZIP is refused: unpack it first.
feed_contentstring–The feed as a file instead of an address: the XML or CSV text itself (at most 8 MB). Checked once and dropped; only its sha-256 and size are kept. Regular price updates still need a feed_url later.
feed_filenamestring–The uploaded file's name, kept with its fingerprint.
feed_urlstring–The product feed (Heureka, Zboží, Google Merchant, Ceneo, Idealo, Árukereső XML or CSV). Read at once; the answer carries the diagnostics report. Public hosts only. Either this or a file.
localestring–Language of the mails (cs, sk, en, …); the country's default language when absent.
notestring––
shop_namestringyesThe shop's name as it should appear in the comparison.
terms_versionstringyesThe partner terms version being accepted; today 2026-10-09 (the terms are at /partner/smlouva).
websitestring–Leave empty (spam trap: a filled value is discarded quietly).

No output schema declared.

No examples provided.

remove_favorite ~48

Removes a product or a digital plan from the signed-in person's favourites. `removed: false` when it was not there.

NameTypeReqDescription
idstringyes–
kindstringyes–

No output schema declared.

No examples provided.

remove_from_list ~143

Removes a product (`product_slug`) or a digital plan (`digital_id`) from one of the signed-in person's lists; send exactly one of the two. `removed: false` when it was not there. Another person's list answers not_found.

NameTypeReqDescription
digital_idstring–A plan id of compare_digital / compare_mobile rows (e.g. claude-pro).
list_idstringyesThe list's id from list_my_lists.
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
product_slugstring––

No output schema declared.

No examples provided.

report_illegal_content ~386

A notice under Article 16 of the Digital Services Act that content on fordeal.ai is illegal (a user review, product information, an offer, an image or anything else). Give `content_kind` review | product_info | offer | image | other, the `page_url` of the content (and the `product_slug` when it is on a product page), an `explanation` of why the content is illegal (20–4000 characters), the notifier's `name` and `email`, and `good_faith: true` confirming the notice is accurate and complete to the best of the notifier's knowledge. A person reviews every notice; the e-mail gets a confirmation of receipt at once and the decision later. For a wrong price or variant use report_issue instead. Public, no key; the anonymous rate limit applies.

NameTypeReqDescription
content_kindstringyesWhat content the notice is about.
emailstringyesThe notifier's e-mail: the confirmation of receipt and the decision go there.
explanationstringyesWhy the content is illegal (Art. 16(2)(a)).
good_faithbooleanyesConfirms the bona fide belief that the information is accurate and complete (Art. 16(2)(d)).
ip_hashstring–sha-256 of the notifier's address with a daily salt (the website computes it); counts the per-visitor limit.
localestring–Language of the confirmation.
namestringyesThe notifier's name (Art. 16(2)(c)).
page_urlstring–The exact page of the content (Art. 16(2)(b)).
product_slugstring–Product slug when the content is on a product page.
websitestring–Leave empty (spam trap).

No output schema declared.

No examples provided.

report_issue ~401

When an offer on a product page is wrong (the shop's page shows another price, the offer is another variant or product, the link leads to the wrong shop or page, or anything else), file a report: `kind` price | variant | category | shop | other, `product_slug` (the stable product id from find_best_price or search_products), the `offer_id` of the offer (from the card's offers; optional) and a `message` saying what you saw (at most 1000 characters). An optional `email` gets the founder's answer; it is never shown. Every report goes to a queue a person reads; the same report sent twice within a day answers the first id with duplicate true. Public, no key; the anonymous rate limit applies.

NameTypeReqDescription
emailstring–Where the answer goes. Optional, never shown.
ip_hashstring–sha-256 of the reporter's address with a daily salt (the website computes it); the per-visitor limit of five reports a minute counts by it. Never stored.
kindstringyesWhat is wrong: the price, the variant or product, the category the product is filed under, the shop or link, or something else.
localestring–Language of the answer.
messagestringyesWhat you saw, e.g. the price on the shop's page and when.
offer_idstring–The offer the report is about (offer_id in the card).
page_urlstring–The page the report was made on.
product_slugstringyesProduct slug (the stable product id).
shop_slugstring–The shop's slug, when known.
user_agent_hashstring–sha-256 of the reporter's user agent (the website computes it); only for spotting floods.
websitestring–Leave empty (spam trap).

No output schema declared.

No examples provided.

save_comparison ~103

Saves 2 to 4 digital plans (plan ids from compare_digital / compare_mobile) as a private comparison in the signed-in person's account. Private: nobody else can open it until share_comparison makes a link.

NameTypeReqDescription
itemsarrayyes–
localestring–BCP 47 locale for human-readable strings, e.g. "en", "cs", "sk". Defaults to the country's default locale.
namestring––

No output schema declared.

No examples provided.

save_favorite ~174

Adds a product (kind product, `id` = slug) or a digital plan (kind digital, `id` = plan id from compare_digital or compare_mobile) to the signed-in person's favourites. For a product its total for `deliver_to_country` today is kept as saved_total (for "the price changed since you saved it", as the website's heart does); a plan keeps no saved price. Saving twice changes nothing (the first saved price stays). Adding it to a named list (add_to_list) or deleting that list leaves the favourite as it is.

NameTypeReqDescription
deliver_to_countrystring–ISO 3166-1 alpha-2 country code, e.g. "CZ". Optional: normally derived from the address.
idstringyes–
kindstringyes–

No output schema declared.

No examples provided.

Install

How do I install the Fordeal MCP server?

Fordeal is a hosted endpoint at https://fordeal.ai/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · fordeal.ai

# add to Claude Code
claude mcp add --transport http ai-fordeal-price-hunter 'https://fordeal.ai/mcp'
Common questions

What is the Fordeal MCP server?

Fordeal is an MCP server listed in the public MCP registry as ai.fordeal/price-hunter. Price comparison for CZ/SK: product prices, shops, digital plans via Streamable HTTP. This page covers its hosted endpoint (https://fordeal.ai/mcp).

Is the Fordeal MCP server safe to use?

Fordeal scores 68 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Fordeal MCP server expose?

Fordeal exposes 62 tools: compare_internet, search_products, cheaper_abroad, list_shops, find_best_price, and 57 more. Their descriptions and schemas cost roughly 19,653 tokens of context every time the server is loaded.

Does the Fordeal MCP server require authentication?

No. We connected to Fordeal without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

Is the Fordeal MCP server still maintained?

Fordeal is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.