# BasketWatch (remote · basketwatchireland.com)

Irish grocery prices at Aldi, Tesco, SuperValu, Dunnes and Lidl: compare, baskets, offers, history

- Trust score: 87/100 (high trust)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- remote · `basketwatchireland.com`: 87/100 (this document), [markdown](https://verifymcp.io/servers/com-basketwatchireland-basketwatch/basketwatchireland.md), [page](https://verifymcp.io/servers/com-basketwatchireland-basketwatch/basketwatchireland)

## Channel facts

- Endpoint: `https://basketwatchireland.com/mcp`
- Transports: `streamable-http`
- Auth: `required`
- Version: `1.0.1`

## Trust breakdown

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. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Endpoint Security**: 94/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
  - The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 71/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 5792 tokens (~289/item across 20 items; 18 tools + 2 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 80/100
  - Stability observed for 24 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (89% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 18 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 20 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the BasketWatch MCP server?

BasketWatch is a hosted endpoint at https://basketwatchireland.com/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.

### Claude

```bash
claude mcp add --transport http com-basketwatchireland-basketwatch 'https://basketwatchireland.com/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "com-basketwatchireland-basketwatch": {
      "url": "https://basketwatchireland.com/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "com-basketwatchireland-basketwatch": {
      "type": "http",
      "url": "https://basketwatchireland.com/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.com-basketwatchireland-basketwatch]
url = "https://basketwatchireland.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "com-basketwatchireland-basketwatch": {
      "type": "remote",
      "url": "https://basketwatchireland.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add com-basketwatchireland-basketwatch --url 'https://basketwatchireland.com/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  com-basketwatchireland-basketwatch:
    url: "https://basketwatchireland.com/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "com-basketwatchireland-basketwatch": {
      "Transport": "http",
      "Url": "https://basketwatchireland.com/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add com-basketwatchireland-basketwatch -t streamable-http -u 'https://basketwatchireland.com/mcp'
```

### Other

```json
{
  "mcpServers": {
    "com-basketwatchireland-basketwatch": {
      "type": "http",
      "url": "https://basketwatchireland.com/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-04 (score 87, +1)

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

### 2026-11-03 (score 86, 0)

- [security] Tool “best_deals” rewrote its description, which is the text the model reads

### 2026-11-02 (score 86, +1)

- [security] Tool “get_promotions” rewrote its description, which is the text the model reads
- [functional] New tool “best_deals”
- [cosmetic] “get_promotions” added an optional parameter “offset”

### 2026-10-31 (score 85, +1)

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

### 2026-10-30 (score 84, 0)

- [security] Tool “compare_prices” rewrote its description, which is the text the model reads
- [security] Tool “find_products” rewrote its description, which is the text the model reads
- [security] Tool “lookup_barcode” rewrote its description, which is the text the model reads
- [cosmetic] “lookup_barcode” dropped the optional parameter “lidl_store_id”

### 2026-10-29 (score 84, +1)

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

### 2026-10-28 (score 83, 0)

- [security] Tool “compare_prices” rewrote its description, which is the text the model reads
- [security] Tool “get_promotions” rewrote its description, which is the text the model reads

### 2026-10-26 (score 83, +1)

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

## MCP tools (18)

### `status` (~35 tokens)

Data freshness and coverage

A freshness snapshot per supermarket: products tracked, products on
    promotion, the last collection date and the status of the most recent run.

Output parameters:

- `as_of`
- `status`
- `stores`

### `search_products` (~187 tokens)

Search Irish supermarket products

Search products by name across one or all Irish supermarkets.

    Args:
        query: words to match in product names, case-insensitive
            (e.g. "heinz baked beans", "kerrygold butter", "pringles").
        store: optionally filter to one of "aldi", "tesco", "supervalu",
            "dunnes", "lidl". Leave it out to search all five.
        limit: how many results to return in total (default 10).

    Returns the matching product rows: store, SKU id, name, brand, price,
    unit_price (€/kg or €/L), pack_size, category_path, url. Matches on the
    name only: no ingredient, nutrition or offer filters, and no price sorting.

Input parameters:

- `limit` (integer)
- `query` (string, required)
- `store`

Output parameters:

- `result` (array)

### `compare_prices` (~357 tokens)

Where is a product cheapest

Find where a product is cheapest right now. Matches the same product at
    Aldi, Tesco, SuperValu, Dunnes Stores and Lidl and returns each store's
    current price side by side, with unit prices, offers and member prices
    (Tesco Clubcard, SuperValu Real Rewards, Lidl Plus). To list the products most stores stock,
    leave out query and set min_stores, e.g. min_stores=5 for every product
    matched at all five.
    Free: no BasketWatch account needed.

    Args:
        query: the product, e.g. "heinz ketchup" or "kerrygold butter 454g".
            Optional when min_stores is given.
        limit: how many matched products to return (default 5, max 50).
        min_stores: only products matched at at least this many stores, 2 to
            5, with or without query.

    Returns {"as_of", "query", "matches": [{"product", "pack", "prices":
    {store: {name, price, unit_price, unit_basis, offer_text, was_price,
    offer_ends, clubcard_price, url}}, "cheapest_store"}]}. A store missing from "prices" did not have that product in its online range today and may still sell it in store: say "not found online", not that the store lacks it. offer_ends is the last day an
    offer applies (Irish time): say when an offer ends, as online orders are
    priced for the delivery or collection day.

Input parameters:

- `limit` (integer)
- `min_stores`
- `query`

Output parameters:

- `as_of`: Price date, YYYY-MM-DD
- `matches` (array)
- `query`

### `compare_price_across_stores` (~126 tokens)

Compare a product across supermarkets

Raw per-store search results for a product name at all five
    supermarkets: every matching line at each store, including other pack
    sizes, without matching the same product across stores. Returns a dict
    keyed by store, with up to `limit_per_store` matching products per store.

    Args:
        query: product-name substring (e.g. "heinz baked beans 415g").
        limit_per_store: how many matches per store (default 5).

Input parameters:

- `limit_per_store` (integer)
- `query` (string, required)

### `lookup_barcode` (~259 tokens)

Look up products by barcode

Find the products carrying one or more barcodes (GTIN, EAN or UPC)
    at Aldi, Tesco, SuperValu, Dunnes Stores and Lidl in one call.

    Codes are accepted exactly as printed: leading zeros, spaces and hyphens
    are ignored. Needs a signed-in BasketWatch account.

    Args:
        codes: one barcode, or up to 100 separated by commas
            (e.g. "5000127014084" or "5000127014084,5000157024671").
        store: optionally restrict to one of "aldi", "tesco", "supervalu",
            "dunnes" or "lidl".
        include_copy: also return ingredients and per-100g nutrition where
            the retailer publishes them.

    Returns {"products": [...], "not_found": [...], "invalid": [...]}. Each
    product row carries store, matched_barcodes, name, brand, pack_size,
    price and its full barcodes list. One credit per barcode found, however
    many retailers stock it; codes with no match cost nothing.

Input parameters:

- `codes` (string, required)
- `include_copy` (boolean)
- `store`

### `get_promotions` (~245 tokens)

Current promotions at a supermarket

List products currently on promotion at a given supermarket, the
    biggest saving the shop states first. Every promotion can be reached:
    each call returns one page, and offset moves through the whole list.

    Returns offer label (e.g. "3 for €5", "SAVE €0.75"), was-price,
    validity window, offer_ends (the last day the offer applies, Irish
    time), and where applicable Tesco Clubcard prices,
    SuperValu Real Rewards prices, Dunnes member offers or Lidl Plus prices
    (scan the Lidl Plus app at the till).

    Args:
        store: one of "tesco", "supervalu", "dunnes", "lidl". (Aldi doesn't
            publish multibuy promos so isn't supported here.)
        limit: how many promotional rows to return in one page (default 25,
            max 200).
        offset: how many rows to skip, for the next page (default 0). A page
            shorter than limit is the last one.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `store` (string, required)

Output parameters:

- `result` (array)

### `best_deals` (~425 tokens)

Best real deals today

Today's real deals at Aldi, Tesco, SuperValu, Dunnes Stores and Lidl:
    offers at the lowest price on record for that product at that shop, or
    the first offer it has ever had. Each is measured against the product's
    own price history, not the shop's was price, so a recurring or
    long-running price does not count as a deal.

    The biggest saving comes first, and the shops are mixed so one shop does
    not fill the top of the list. Every promotion on sale is judged, so this
    covers them all, and offset reaches every deal. Covers food, drinks,
    alcohol, household, baby and pet products unless another aisle is named.
    Tobacco, infant formula and medicines are never included.

    Args:
        query: words in the product's name or brand, e.g. "coffee" or "heinz".
        category: an aisle or shelf, e.g. "frozen", "household" or "toiletries".
        store: one of "aldi", "tesco", "supervalu", "dunnes", "lidl". Leave it
            out for all five.
        limit: how many deals to return in one page (default 20, max 200).
        offset: how many deals to skip, for the next page (default 0).

    Returns {"as_of", "note", "total", "deals"}. total counts every deal for
    this search, across all pages. Each deal has name, store, pack,
    you_pay, regular_price, saving_eur, saving_pct, card_needed, buy_quantity,
    offer_ends, url and category, and the record behind it: kind, lowest_since,
    low_before, low_before_date, run_start, days_on_offer and started_today.
    One credit per deal returned.

Input parameters:

- `category`
- `limit` (integer)
- `offset` (integer)
- `query`
- `store`

Output parameters:

- `as_of`: Latest collection day behind these deals, YYYY-MM-DD
- `deals` (array): Biggest saving first, with the shops mixed unless one was named
- `note` (string): What these savings are measured against, and the limits of the data
- `total`: How many deals there are today for this search, all pages

### `recent_price_changes` (~119 tokens)

Recent price changes

Price movements at one supermarket between the latest nightly
    snapshot and the previous one: shelf price rises and falls with old price,
    new price and % change, and promotions starting or ending listed
    separately (an offer ending is not a price rise).

    Args:
        store: "aldi" | "tesco" | "supervalu" | "dunnes" | "lidl".
        limit: how many movers to return (default 25).

Input parameters:

- `limit` (integer)
- `store` (string, required)

Output parameters:

- `clubcard_changes`: Member price changes: Tesco Clubcard, SuperValu Real Rewards or Lidl Plus
- `clubcard_changes_total`
- `date`: Snapshot being reported
- `prev_date`: Snapshot compared against
- `promotions`: Offers starting or ending, not shelf moves
- `promotions_total`
- `shelf_decreases`
- `shelf_decreases_total`
- `shelf_increases`
- `shelf_increases_total`

### `newly_added_products` (~112 tokens)

Newly stocked products

Products newly listed at a supermarket within a configurable lookback
    window: range additions and new launches.

    Args:
        store: "aldi" | "tesco" | "supervalu" | "dunnes" | "lidl".
        days_back: how many days back to look (default 7 = since last scrape).
        limit: how many new products to return.

Input parameters:

- `days_back` (integer)
- `limit` (integer)
- `store` (string, required)

Output parameters:

- `result` (array)

### `removed_products` (~111 tokens)

Delisted products

Products that have disappeared from a supermarket's catalogue in the
    given lookback window: delistings and range cuts.

    Args:
        store: "aldi" | "tesco" | "supervalu" | "dunnes" | "lidl".
        days_back: how many days back to consider (default 7).
        limit: how many removed products to return.

Input parameters:

- `days_back` (integer)
- `limit` (integer)
- `store` (string, required)

Output parameters:

- `result` (array)

### `list_products` (~97 tokens)

Browse the catalogue

Page through a supermarket's full catalogue, with no search terms or
    filters.

    Args:
        store: "aldi" | "tesco" | "supervalu" | "dunnes" | "lidl".
        limit: page size (default 100, max 200).
        offset: pagination offset.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `store` (string, required)

Output parameters:

- `result` (array)

### `get_price_history` (~545 tokens)

Price history

A product's recorded daily prices over a date range. BasketWatch has kept
    every night's price at Aldi, Tesco, SuperValu and Dunnes Stores since May
    2026 and at Lidl since 17 October 2026, and, with
    with_nutrition_and_ingredients, each day's nutrition per 100g or 100ml and
    ingredients list as the retailer's own data stated them, kept since
    16 October 2026: for questions like "has the sugar in Frosties changed".

    Takes product ids (as returned in product results; an Aldi id has no store
    prefix, and "aldi:" in front of one is accepted) or a query; with a query,
    the closest matching products are looked up first. A range returns one row
    per product per day, and each row costs one credit; with from_date equal
    to to_date, one day's price is returned.

    Every product gets the same days. When products x days would pass the row
    limit, the range is shortened to its most recent days for all of them and
    note says so; ids with no price in the range are listed in not_found.

    Args:
        product_ids: e.g. ["tesco:300793546", "dunnes:100873410",
            "000000000000387044"], up to 50; each id's store is taken from it.
        query: product name words, used when no product_ids are given.
        store: aldi, tesco, supervalu, dunnes or lidl, to narrow a query.
            Leave it out to look in all five.
        from_date: first day, YYYY-MM-DD. Defaults to 30 days before to_date.
        to_date: last day, YYYY-MM-DD. Defaults to today.
        limit: most rows to return in total (default and maximum 200).
        with_nutrition_and_ingredients: true adds nutrition_per_100 to every
            row and the ingredients list on each product's first day and on
            any day it changed. Days before 16 October 2026 have none.

    Returns rows (id, name, store, scrape_date, price, unit_price, unit_basis,
    clubcard_price, offer_text, was_price), the days covered, not_found, note.

Input parameters:

- `from_date`
- `limit`
- `product_ids`
- `query`
- `store`
- `to_date`
- `with_nutrition_and_ingredients` (boolean)

Output parameters:

- `from_date`: First day covered, YYYY-MM-DD
- `not_found` (array): Requested ids with no price recorded in the range: an unknown id, or a product not on sale then
- `note`: What was left out and why, when anything was
- `products` (integer): How many products have rows
- `rows` (array): One row per product per day recorded, each product's days in order
- `to_date`: Last day covered, YYYY-MM-DD

### `get_product_details` (~338 tokens)

Nutrition, ingredients and product details

Nutrition per 100g or 100ml (energy, fat, carbohydrate, sugars, protein,
    salt), the ingredients list as printed (allergens included), how many
    ingredients it lists, country of origin, alcohol strength, pack size,
    description and today's price, for particular products.

    Products are looked up by product id (store-prefixed, as returned in
    product results), by the retailer's own item numbers (skus with store, as
    printed on its receipts), or by name (query). ingredients_incomplete marks
    an ingredient list on record that is cut short, which cannot show that an
    ingredient is absent. Results carry a note that nutrition and ingredients
    are for information only. Each product returned costs one credit.

    Args:
        query: product name words, e.g. "kellogg's corn flakes".
        product_ids: e.g. ["tesco:300793546", "dunnes:100873410"], up to 50.
        skus: the store's own item numbers, e.g. ["100873410"], up to 50;
            needs store. An Aldi article number can return several variants.
        store: aldi, tesco, supervalu, dunnes or lidl: required with skus,
            narrows a query; leave out for all five.
        limit: most products to return for a query (default 5, max 50).

Input parameters:

- `limit` (integer)
- `product_ids`
- `query`
- `skus`
- `store`

Output parameters:

- `note` (string)
- `products` (array)

### `find_products` (~1351 tokens)

Find products by ingredients and nutrition

Find products that meet ingredient, nutrition, alcohol or offer
    conditions, optionally sorted. For questions like "biscuits without palm
    oil", "nut-free snacks at Tesco", "vegan chocolate", "cereal with the least
    sugar", "high protein yoghurt", "bread with the fewest ingredients",
    "alcohol-free beer", "low salt soup" or "cheapest olive oil at Aldi".
    Every product comes with its nutrition, ingredients, ingredient count,
    country of origin where stated and today's price. Fibre and saturated fat
    are not recorded.

    Ingredient words. exclude_ingredients are ingredients a product is free
    of; include_ingredients ones it contains. These words are expanded to the
    label terms they cover: palm oil, nuts (includes peanuts), peanuts, gluten,
    milk (dairy), eggs, soya, sesame, mustard, celery, fish, crustaceans,
    molluscs, shellfish, sulphites, lupin, gelatine, alcohol, added sugar,
    sweeteners, pork, meat, vegetarian (meat, fish, gelatine and other
    animal-derived ingredients) and vegan (vegetarian plus milk, eggs, honey and
    other animal products). Any other word is matched as written, e.g.
    "coconut" or "oats".

    With no store, results alternate across the stores (each store's best
    match, then each store's next), and matched_by_store gives each store's
    full count.

    A product whose ingredient list or nutrition is not on record, or whose
    ingredient list on record is incomplete, is left out, never assumed to
    pass: left_out_unknown counts them, left_out_by_reason gives the reasons,
    and caveats lists known gaps (Aldi's own ingredient lists are often cut
    short, so an Aldi product is offered as free from something only when its
    full list comes from the same barcode at Tesco, SuperValu or Dunnes). Claims printed in
    a product's NAME, such as "gluten free", "lactose free", "alcohol free" or
    "vegan", are matched through query; exclude_ingredients also checks the
    ingredients. Alcohol s…

Input parameters:

- `category`
- `descending` (boolean)
- `exclude_ingredients`
- `include_ingredients`
- `limit` (integer)
- `max_abv`
- `max_carbs_g`
- `max_fat_g`
- `max_ingredients`
- `max_kcal`
- `max_salt_g`
- `max_sugar_g`
- `min_abv`
- `min_protein_g`
- `on_offer` (boolean)
- `origin`
- `query`
- `sort_by`
- `store`

Output parameters:

- `as_of`: Price date, YYYY-MM-DD
- `caveats` (array): Limits of this answer: pass them on
- `considered`: Products the search looked at
- `left_out_by_reason` (object): Why products were left out, with counts
- `left_out_by_store` (object)
- `left_out_may_contain`: With ingredients excluded: products whose ingredient list passed but whose allergy advice says they contain or may contain one, left out
- `left_out_may_contain_examples` (array): A few of those, each with its allergy advice
- `left_out_other_kind`: Products that only mention the search words but are a different kind of product (honey roast ham for 'honey'), left out
- `left_out_partly_from_origin`: With an origin asked for: products whose label names that country AND another ('Made in Ireland' from 'EU chicken'), left out as not wholly from it
- `left_out_partly_from_origin_examples` (array): A few of those, each with the origin it states
- `left_out_unknown`: Left out because the ingredients, nutrition or value a filter or sort needs is not on record for them, or the ingredient list is incomplete
- `matched`: Products that passed every filter
- `matched_by_store` (object): How many products passed at each store (more than are returned)
- `note` (string)
- `products` (array)

### `price_basket` (~453 tokens)

Price a shopping list or receipt

Price a whole shopping list, or every line of a grocery receipt (up to 100
    lines in one call), at Aldi, Tesco, SuperValu, Dunnes Stores and Lidl: each item
    matched to the same product at every store, the cheapest store for each
    item, each store's basket total, and a cheaper product of the same kind
    (often own-label) where one exists.

    Each line takes name (plain words with brand and size, e.g. "avonmore fresh
    milk 2l"; receipt abbreviations such as "AVNMR FRSH MLK 2L" match poorly)
    and optionally sku (the retailer's item number as printed on its receipts;
    the name is used when the number is not found), barcode, store, quantity,
    and paid (the line total, which gives the saving against what was paid).
    Irish product names say "low fat milk" for what the UK calls "semi
    skimmed". Bags, deposits, discounts and totals are not products.

    Returns, per line, the match and matched_by (sku, barcode or name), the
    cheapest store and price, a cheaper alternative with its pack size and, for
    a receipt, price_at_store_bought; then each store's total with its
    items_missing, cheapest_complete_store, mix_and_match_total and not_found.
    Prices are each retailer's online shelf price from the overnight
    collection; in-store prices can differ. Member prices (Tesco Clubcard,
    Lidl Plus) are reported separately. Each matched item costs one credit;
    items not found are free.

    Args:
        items: e.g. [{"sku": "100685955", "name": "dunnes baked beans",
            "quantity": 2, "paid": 1.30}, {"name": "brennans wholemeal bread"}].
        store: the receipt's supermarket (aldi, tesco, supervalu, dunnes or
            lidl), used for any line that does not name its own.

Input parameters:

- `items` (array, required)
- `store`

Output parameters:

- `as_of`: Price date, YYYY-MM-DD
- `cheapest_complete_store`: The cheapest store among those with every matched item found in its online range today
- `different_pack` (array): Items priced at another pack size than the one asked for, so not like for like
- `items` (array)
- `lidl_plus_total`: Lidl total using Lidl Plus prices where Lidl has one
- `mix_and_match_total`: Each item bought at its cheapest store
- `not_found` (array): Items with no match
- `note`
- `paid_total`
- `saving_vs_paid`
- `supervalu_real_rewards_total`: SuperValu total using Real Rewards prices where SuperValu has one
- `tesco_clubcard_total`: Tesco total using Clubcard prices where Tesco has one
- `totals_by_store` (object)
- `with_alternatives_total`: As mix_and_match_total, taking each cheaper alternative where there is one

### `price_basket_over_time` (~375 tokens)

What a basket cost on an earlier date

How the cost of the same basket changed between two dates, at the store
    it was bought from: each product's price on both dates, whether it was on
    promotion, the basket total on each date, and the products that moved it.
    BasketWatch has recorded every product's price every night since May 2026
    (Lidl's since 17 October 2026).
    Up to 100 lines per call; each line takes name, sku (the retailer's printed
    item number, with the line's words in name), barcode, store and quantity.

    change_pct is the change in what the basket cost (promotions included);
    shelf_change_pct is regular prices only, so the gap between the two is
    promotions starting or ending, not price rises. biggest_rises and
    biggest_falls list the lines that moved most; pack_changed marks a product
    whose pack size changed, confirmed over three days of records (a smaller
    pack at the same price is a hidden rise). Lines in not_compared were not
    found, or not sold on one of the dates.

    Each product compared costs one credit.

    Args:
        items: e.g. [{"sku": "100858349", "quantity": 2}, {"name": "brennans wholemeal bread"}].
        from_date: the earlier date, YYYY-MM-DD, e.g. "2026-08-06".
        to_date: the later date, YYYY-MM-DD; defaults to today.
        store: the receipt's supermarket (aldi, tesco, supervalu, dunnes or lidl).

Input parameters:

- `from_date` (string, required)
- `items` (array, required)
- `store`
- `to_date`

Output parameters:

- `biggest_falls` (array)
- `biggest_rises` (array)
- `change`: total_now minus total_then, euro
- `change_pct`
- `from_date`
- `items` (array)
- `items_unchanged`
- `not_compared` (array): Lines not found, or not sold on one date
- `note`
- `shelf_change_pct`: Change in regular prices only: real price moves, without promotions
- `shelf_total_now`
- `shelf_total_then`
- `to_date`
- `total_now`
- `total_then`

### `price_movements` (~533 tokens)

Price movements in a category

How a whole category's prices moved between two dates, in one call: the
    biggest regular-price rises and falls, promotions starting and ending,
    member price changes (Tesco Clubcard, SuperValu Real Rewards, Lidl Plus)
    and pack-size changes, kept apart, with a
    summary over every product compared (average and median shelf change,
    counts of rises and falls) overall and per store.

    shelf_rise and shelf_fall are changes to the regular price;
    promotion_started and promotion_ended are changes in what was paid while
    the regular price stayed the same (a product at 18 euro on promotion and 23
    euro after is a promotion ending, not a 27.8% price rise); loyalty_change
    is a member price moving; pack_change is the same product in a different
    pack size, confirmed over three days of records (a smaller pack at the same
    price is a hidden rise); was_price_change is an offer running at both
    dates while only its "was" price moved, kept out of the shelf figures
    because nobody paid it. Averages are geometric, so a half-price offer
    starting and ending cancel out; average_member_paid_change_pct uses member
    prices where they apply.

    Each mover returned costs one credit; the summaries are free.

    Args:
        from_date: the earlier date, YYYY-MM-DD (prices recorded since May 2026).
        to_date: the later date, YYYY-MM-DD; defaults to today.
        group: a kind of product: beer, cider, wine, spirits, alcohol, or any
            product type such as breakfast cereal, butter, coffee, crisps,
            nappies. Narrower words work too ("vodka", "red wine").
        query: product or brand words, with or without group
            (e.g. "guinness").
        category: an aisle name to narrow by.
        store: aldi, tesco, supervalu, dunnes or lidl; leave out for all five.
        kinds: which lists to return (default all seven).
        rank_by: "pct" (default) or "eur".
        limit: most products per list (default 10,…

Input parameters:

- `category`
- `from_date` (string, required)
- `group`
- `kinds`
- `limit` (integer)
- `query`
- `rank_by` (string)
- `store`
- `to_date`

Output parameters:

- `from_date`
- `movers` (array)
- `note`
- `summary` (object): Over EVERY product compared, not only those listed
- `summary_by_store` (object)
- `to_date`

### `check_credits` (~39 tokens)

Your credit balance

How many BasketWatch credits the signed-in account has left, and when they
    expire. Free to call. One credit is one record returned.

Output parameters:

- `credits_remaining`: One credit is one record returned
- `expiring` (array): Credits still to expire, soonest first: credits, expires_at (UTC) and bought_at. Credits last 30 days from purchase and the soonest to expire are spent first
- `metered`: True when the account pays per record from credits
- `never_expires`: Credits bought before 15 October 2026, which do not expire
- `next_expiry`: When the next credits expire (UTC), or null
- `plan`

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/com-basketwatchireland-basketwatch/basketwatchireland#diagnostics

## Score history

- 2026-11-05: 87
- 2026-11-04: 87
- 2026-11-03: 86
- 2026-11-02: 86
- 2026-11-01: 85
- 2026-10-31: 85
- 2026-10-30: 84
- 2026-10-29: 84
- 2026-10-28: 83
- 2026-10-27: 83
- 2026-10-26: 83
- 2026-10-25: 82
- 2026-10-24: 82
- 2026-10-23: 81
- 2026-10-22: 81
- 2026-10-21: 80
- 2026-10-20: 80
- 2026-10-19: 79
- 2026-10-18: 79
- 2026-10-17: 79
- 2026-10-16: 78
- 2026-10-15: 78
- 2026-10-14: 77
- 2026-10-13: 77
- 2026-10-12: 76

## Common questions

### What is the BasketWatch MCP server?

BasketWatch is an MCP server listed in the public MCP registry as com.basketwatchireland/basketwatch. Irish grocery prices at Aldi, Tesco, SuperValu, Dunnes and Lidl: compare, baskets, offers, history. This page covers its hosted endpoint (https://basketwatchireland.com/mcp).

### Is the BasketWatch MCP server safe to use?

BasketWatch scores 87 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 BasketWatch MCP server expose?

BasketWatch exposes 18 tools: status, search_products, compare_prices, compare_price_across_stores, lookup_barcode, and 13 more. Their descriptions and schemas cost roughly 5,707 tokens of context every time the server is loaded.

### Does the BasketWatch MCP server require authentication?

Yes. BasketWatch asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

### Is the BasketWatch MCP server still maintained?

BasketWatch 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.

## Links

- Remote endpoint: https://basketwatchireland.com/mcp
- Website: https://basketwatchireland.com/agent-access
- Changelog RSS feed: https://verifymcp.io/servers/com-basketwatchireland-basketwatch/basketwatchireland.xml
- Changelog JSON feed: https://verifymcp.io/servers/com-basketwatchireland-basketwatch/basketwatchireland.json
- HTML version of this page: https://verifymcp.io/servers/com-basketwatchireland-basketwatch/basketwatchireland
