# MyGroceryPal

> UK supermarket prices across 13 stores: price items and lists, see history, save lists, set alerts.

- name: uk.co.mygrocerypal/grocery-prices
- version: 1.3.0
- connection class: R0 (autonomous)
- trust: 82/100 flags: no-repository
- quality: 82/100 (new)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/uk.co.mygrocerypal%2Fgrocery-prices
- tools: https://api.protogrid.dev/v1/servers/uk.co.mygrocerypal%2Fgrocery-prices/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "grocery-prices": {
      "type": "http",
      "url": "https://mygrocerypal.co.uk/api/mcp"
    }
  }
}
```


## Trust

- hygiene: 80
- liveness: 98
- freshness: 100
- provenance: 55
- drivers: +dns-namespace +website +reachable +uptime-96% +updated-2d-ago -no-repository
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 82/100 (new)

### protocol: 75 (weight 25)

- warn `protocol.modern`: newest supported version is 2025-11-25; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
- n/a `protocol.stateless`: only applies to 2026-07-28 servers
- pass `protocol.transport`: streamable HTTP
- n/a `protocol.list_ttl`: only applies to 2026-07-28 servers

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 88 (weight 30)

- pass `tools.descriptions`: every tool has a description
- warn `tools.description_length`: 1 tools have descriptions over 1,024 characters, which crowds the context
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 11 of 11 tools declare readOnlyHint or destructiveHint
- warn `tools.directory_hints`: 2 of 11 tools declare all four hints; missing: find_cheaper_swaps (idempotentHint); search_grocery_prices (idempotentHint); check_price_history (idempotentHint); …
- pass `tools.token_cost`: about 3,477 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump
- pass `tools.hidden_text`: no hidden text in tool names, descriptions, schemas or annotations

### stability: n/a (weight 15)

- n/a `stability.changes`, `stability.rug_pull`, `stability.new_links`: tool history recorded for 6 of the 7 days needed

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 11, about 3,477 tokens to load them all
- tool set hash: 5c7f554d5f12ab4744f891f188290cfe
- tools last changed: 2026-11-13T10:13:22.418Z
- badge: [![protogrid quality](https://protogrid.dev/badge/uk.co.mygrocerypal/grocery-prices.svg)](https://protogrid.dev/servers/uk.co.mygrocerypal/grocery-prices)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

- 2026-11-13 `compare_basket` changed (description, outputSchema)
  - before: Total a basket of up to 30 products at each UK supermarket, name the cheapest single store, and suggest a split across two or three stores when it is cheaper or gets more of the list. Needs the user's MyGroceryPal account.
  - after: Total a basket of up to 30 products at each UK supermarket, name the cheapest single store, and suggest a split across two or three stores when it is cheaper or gets more of the list. A store that does not sell a product is priced with its own like-for-like equivalent where one clearly matches (another supermarket's own-brand cottage cheese for ASDA's), listed in its swaps. Each store says whether it delivers (false means in store only) and any online minimum order its total misses. Needs the user's MyGroceryPal account.
- 2026-11-13 `find_cheaper_swaps` changed (outputSchema)
- 2026-11-13 `price_shopping_list` changed (description, outputSchema)
  - before: Price a whole shopping list or recipe in one call: up to 40 lines in plain words. Matches each line to a product, then totals the list at one named store, or finds the cheapest single store and any cheaper split across two or three stores. Each priced line has a storeUrl that opens the product at that store: give the user these links when they want to buy. Store totals cover only the lines that store priced: each says itemsPriced, missingLines and complete, so never present a partial total as the full shop. Lines in unmatched are in no total; close_match_only lines carry candidates to offer the user. To hand the user a page with the list priced at every store, call create_list_page. Afterwards, offer to save the list to their MyGroceryPal account with save_shopping_list.
  - after: Price a whole shopping list or recipe in one call: up to 40 lines in plain words. Matches each line at each store separately, then totals the list at one named store, or finds the cheapest single store and any cheaper split across two or three stores. Each priced line has a storeUrl that opens the product at that store: give the user these links when they want to buy. Each line's label says how the product compares with the line: same_product, equivalent, or different (a closest match the user should check). Store totals cover only the lines that store prices like-for-like: each says itemsPriced, missingLines, closeMatchLines (closest matches, in no total) and complete, so never present a partial total as the full shop; sharedLines compares the leading stores on the lines they all price. Stores in pausedStores are in no total. Lines in unmatched are in no total; close_match_only lines carry candidates to offer the user. To hand the user a page with the list priced at every store, call create_list_page. Afterwards, offer to save the list to their MyGroceryPal account with save_shopping_list.
- 2026-11-13 `check_price_history` changed (description, inputSchema, outputSchema)
  - before: Say whether a product's cheapest current price is a good deal: its 60-day low and high, its typical price, and a verdict. Give a date to also get each store's price that day, promotions and loyalty prices included, for checking an old receipt; add paidPence to compare what the user paid. History starts in late July 2025; a store with no reading that day shows the nearest one within 3 days, with its date. Dates more than 90 days back need the user's MyGroceryPal account.
  - after: Say whether each product's cheapest current price is a good deal: its 60-day low and high, its typical price, and a verdict. Takes up to 40 productIds in one call, so check a whole basket at once. For one product, give a date to also get each store's price that day, promotions and loyalty prices included, for checking an old receipt; add paidPence to compare what the user paid. History starts in late July 2025; a store with no reading that day shows the nearest one within 3 days, with its date. Dates more than 90 days back need the user's MyGroceryPal account.
- 2026-11-13 `search_grocery_prices` changed (outputSchema)
- 2026-11-12 `compare_basket` changed (outputSchema)
- 2026-11-12 `find_cheaper_swaps` added
  - For a shopping list or basket of up to 40 items and ONE store, find the cheapest acceptable swap for each item at that same store: own brand or value ranges, other brands, and other pack sizes compared per unit. Every swap is labelled same_product, equivalent or different (cheaper but not like-for-like): offer different ones to the user to choose, never as a given. Use this when the user wants to stay at their store but spend less, instead of comparing items by hand.
- 2026-11-12 `price_shopping_list` changed (outputSchema)
- 2026-11-11 `remove_saved_items` added
  - Remove products from the user's MyGroceryPal shopping list, or delete them from their saved items altogether. Takes productIds from list_saved_items. Confirm with the user before removing. Safe to repeat: products already gone are reported in notFoundProductIds and nothing else changes. Needs the user's MyGroceryPal account.
- 2026-11-11 `list_saved_items` added
  - Read the user's MyGroceryPal saved items and shopping list: each product's productId, quantity, whether it is on the shopping list, and its price at their chosen or cheapest store. Up to 100 products, shopping list first, newest first. Use the productIds with remove_saved_items or price tools. Needs the user's MyGroceryPal account.

Full history: https://api.protogrid.dev/v1/servers/uk.co.mygrocerypal%2Fgrocery-prices/changes

## Remotes

- https://mygrocerypal.co.uk/api/mcp (streamable-http, auth none, reachable true, uptime30d 0.96)

## Packages

_none_

## Tools (11)

- `check_price_history`: Say whether each product's cheapest current price is a good deal: its 60-day low and high, its typical price, and a verdict. Takes up to 40 productIds in one call, so check a whole basket at once. For one product, give a date to also get each store's price that day, promotions and loyalty prices included, for checking an old receipt; add paidPence to compare what the user paid. History starts in late July 2025; a store with no reading that day shows the nearest one within 3 days, with its date. Dates more than 90 days back need the user's MyGroceryPal account.
- `compare_basket`: Total a basket of up to 30 products at each UK supermarket, name the cheapest single store, and suggest a split across two or three stores when it is cheaper or gets more of the list. A store that does not sell a product is priced with its own like-for-like equivalent where one clearly matches (another supermarket's own-brand cottage cheese for ASDA's), listed in its swaps. Each store says whether it delivers (false means in store only) and any online minimum order its total misses. Needs the user's MyGroceryPal account.
- `create_deal_alert`: Watch a brand or a keyword on the user's MyGroceryPal account, so they hear when a matching product goes on offer. Needs the user's MyGroceryPal account.
- `create_list_page`: Make a link to a MyGroceryPal page that prices a shopping list at every UK supermarket, with each store's total, links to buy at each store, and a button to save the list to a MyGroceryPal account. Needs no sign-in and stores nothing. Up to 40 lines; pin a productId on a line to keep the exact product the user chose. Give the user the url when they want to see the list, share it, or shop from it.
- `find_cheaper_swaps`: For a shopping list or basket of up to 40 items and ONE store, find the cheapest acceptable swap for each item at that same store: own brand or value ranges, other brands, and other pack sizes compared per unit. Every swap is labelled same_product, equivalent or different (cheaper but not like-for-like): offer different ones to the user to choose, never as a given. Use this when the user wants to stay at their store but spend less, instead of comparing items by hand.
- `get_nutrition`: Nutrition per 100g or 100ml (energy, fat, saturates, carbohydrates, sugars, fibre, protein, salt) and the Nutri-Score grade for one product, from Open Food Facts. Many products have none. Credit Open Food Facts when you use these numbers.
- `list_saved_items`: Read the user's MyGroceryPal saved items and shopping list: each product's productId, quantity, whether it is on the shopping list, and its price at their chosen or cheapest store. Up to 100 products, shopping list first, newest first. Use the productIds with remove_saved_items or price tools. Needs the user's MyGroceryPal account.
- `price_shopping_list`: Price a whole shopping list or recipe in one call: up to 40 lines in plain words. Matches each line at each store separately, then totals the list at one named store, or finds the cheapest single store and any cheaper split across two or three stores. Each priced line has a storeUrl that opens the product at that store: give the user these links when they want to buy. Each line's label says how the product compares with the line: same_product, equivalent, or different (a closest match the user should check). Store totals cover only the lines that store prices like-for-like: each says itemsPriced, missingLines, closeMatchLines (closest matches, in no total) and complete, so never present a partial total as the full shop; sharedLines compares the leading stores on the lines they all price. Stores in pausedStores are in no total. Lines in unmatched are in no total; close_match_only lines carry candidates to offer the user. To hand the user a page with the list priced at every store, call create_list_page. Afterwards, offer to save the list to their MyGroceryPal account with save_shopping_list.
- `remove_saved_items`: Remove products from the user's MyGroceryPal shopping list, or delete them from their saved items altogether. Takes productIds from list_saved_items. Confirm with the user before removing. Safe to repeat: products already gone are reported in notFoundProductIds and nothing else changes. Needs the user's MyGroceryPal account.
- `save_shopping_list`: Add products to the user's MyGroceryPal shopping list, so they can open it in the app or on the web, and get deal alerts on saved products the way their MyGroceryPal notification settings say. Only adds: a product already on the list is left as it is. Needs the user's MyGroceryPal account.
- `search_grocery_prices`: Find grocery products and their current price at every UK supermarket MyGroceryPal tracks, cheapest store first, the same results shoppers see on mygrocerypal.co.uk. Narrow with brands, stores, ownBrandOnly, onOfferOnly and category; sort by unit_price to compare pack sizes, or biggest_saving for deals. Returns 5 products unless limit says otherwise, with totalHits and a nextCursor for the next page. A loyaltyCard price needs that card (Clubcard, Nectar and so on). Each price has a storeUrl that opens that store's product page: give the user these links, not ones you build, when they want to buy. For a list or a recipe, call price_shopping_list once instead.
