grocery-deals-mcp
Provides access to Lidl's weekly circulars, enabling deal searches, price checks, and shopping plan creation for Lidl stores near a given ZIP code.
Provides access to Target's weekly circulars, enabling deal searches, price checks, and shopping plan creation for Target stores near a given ZIP code.
Provides access to Walmart's weekly circulars, enabling deal searches, price checks, and shopping plan creation for Walmart stores near a given ZIP code.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@grocery-deals-mcp Where can I get the cheapest chicken this week near 10001?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
grocery-deals-mcp
An MCP server that tells an AI assistant what's actually on sale at grocery stores near any US ZIP code this week.
It reads the weekly circulars that supermarkets publish — the same ads that used to arrive in the newspaper — and turns them into something an agent can query: "what protein is cheap this week?", "where should I buy this list?", "is $1.99/lb a good price for chicken, or should I wait?"
Typical coverage for a suburban ZIP is 15–25 grocery chains and several thousand advertised items, including Aldi, Costco, Food Lion, Giant, Harris Teeter, H Mart, Lidl, Publix, Safeway, Sprouts, Target, Walmart, Wegmans and Weis, depending on what operates in your area.
Why it's fast
Every query tool reads a local SQLite index and never touches the network.
Only refresh_deals goes out to fetch circulars (10–20 seconds), and it
self-heals — the first query of the week builds the index, and every call after
that returns in milliseconds until the circulars turn over.
Related MCP server: TilbudsTrolden
Tools
Tool | What it does |
| Which stores near a ZIP have an active ad, and how many deals each is running |
| Find a product across every local store's ad, cheapest first |
| Dump one store's entire weekly ad |
| Turn a shopping list into a per-store trip plan, capped at N stores |
| Judge a price against the history this server accumulates |
| Force an index rebuild mid-week |
| Exact SKU-level regular/promo prices (optional, see below) |
| Look up a Kroger-banner store ID (optional) |
Setup
Requires Python 3.10+ and uv.
git clone https://github.com/tx-smitht/grocery-deals-mcp.git
cd grocery-deals-mcp && uv syncVerify it starts:
uv run grocery-deals-mcpIt will sit silently waiting for MCP traffic on stdin — that's correct. Ctrl-C to exit.
Setting your location
The agent passes the ZIP code. Every location-aware tool takes a
zip_code argument, so you can just say "what's on sale near 12345?" and it
works with no configuration at all. Nothing about any location is stored in
this repository.
If you'd rather not repeat your ZIP every conversation, set GROCERY_ZIP in
your client config (below) and the argument becomes optional. Note that this
writes your ZIP into a local config file — keep that file out of version
control. .mcp.json and .env are already in .gitignore.
All configuration
Every setting is an environment variable, all optional:
Variable | Default | Purpose |
| (none) | Default ZIP, so tools don't need the argument |
| (all) | Comma-separated allowlist, e.g. |
|
| How long the index stays fresh |
|
| Where the cache and price history live |
| (none) | Enables |
| (none) | Default Kroger-banner store |
To change what counts as a grocery store, edit GROCERY_CATEGORY in
src/grocery_deals_mcp/config.py — Flipp
also tags circulars as Pharmacy, Pets, Home & Garden, Electronics and
others, so the same code will happily index those instead.
Connecting it
Claude Code
One command, from anywhere:
claude mcp add grocery-deals -- uv run --directory /absolute/path/to/grocery-deals-mcp grocery-deals-mcpWith a default ZIP baked in:
claude mcp add grocery-deals --env GROCERY_ZIP=12345 -- uv run --directory /absolute/path/to/grocery-deals-mcp grocery-deals-mcpThen /mcp inside Claude Code to confirm it connected.
Claude Desktop
Edit claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"grocery-deals": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/grocery-deals-mcp", "grocery-deals-mcp"],
"env": { "GROCERY_ZIP": "12345" }
}
}
}Restart Claude Desktop. Drop the env block to pass ZIPs per-question instead.
Codex CLI
Add to ~/.codex/config.toml:
[mcp_servers.grocery-deals]
command = "uv"
args = ["run", "--directory", "/absolute/path/to/grocery-deals-mcp", "grocery-deals-mcp"]
env = { GROCERY_ZIP = "12345" }Anything else
It's a standard stdio MCP server. Any client that speaks MCP can run
uv run --directory <path> grocery-deals-mcp.
A copyable starting point is in
.mcp.json.example.
Optional: exact Kroger-banner pricing
The circular tells you "Boneless Chicken Breast $1.99/lb". Kroger's official API tells you the exact SKU, size, regular price and promo price at one specific store. It covers every Kroger banner — Kroger, Harris Teeter, Ralphs, Fred Meyer, King Soopers, QFC, Smith's, Fry's.
Register a free app at developer.kroger.com and request the Products API
Set
KROGER_CLIENT_IDandKROGER_CLIENT_SECRETAsk the agent to run
kroger_find_stores, then setKROGER_LOCATION_IDto the store you use (or passlocation_idper call)
kroger_find_stores accepts everyday chain names — "Harris Teeter" works, and
so does Kroger's internal code for it (HART). Matching happens client-side
because Kroger's own filter.chain takes undocumented codes and answers an
unrecognized one with an empty list rather than an error.
Free tier allows 10,000 calls/day. Everything else in this server works without it.
How it works, and what that implies
Circular data comes from Flipp's backend — the service behind the weekly-ad app used by most large US grocers. These endpoints are undocumented and unofficial. They require no key and are the same calls Flipp's own web app makes, but there is no API contract behind them: they can change shape or disappear without notice, and this project isn't affiliated with or endorsed by Flipp or any retailer.
Accordingly, the server caches aggressively and fetches rarely — one refresh per ZIP per 12 hours by default, six concurrent requests at most. Please don't lower those defaults to hammer someone else's servers.
Some real limits worth knowing:
Trader Joe's will never appear. They don't run weekly sales or publish a circular. That's a fact about Trader Joe's, not a gap in the data.
Prices are what the ad claims. Loyalty-card qualifiers (
MVP,with card), digital-coupon requirements and quantity limits are captured when the ad states them, but the ad is the source of truth, not the register.Flyer dumps lack units. A store's full circular gives names and prices;
search_dealsfalls back to Flipp's search index, which addsLB/EAunits and loyalty qualifiers, when a term is thin locally.A ZIP's feed can include chains that aren't local. Flipp's radius is generous. Use
GROCERY_STORESto pin it down to stores you'd actually drive to.
Privacy
Nothing leaves your machine except circular requests to Flipp (a ZIP code and search terms) and, if you enable it, product lookups to Kroger.
The SQLite database records your ZIP and accumulated price history. It lives in
data/ and is gitignored. So is .env and .mcp.json — if you set a default
ZIP, that's where it should go.
License
MIT
Available Tools
8 toolskroger_find_storesA
Find nearby Kroger-banner store IDs, needed once to use kroger_search.
Args: zip_code: 5-digit US ZIP code. Optional if GROCERY_ZIP is set. chain: optional banner filter, e.g. "Harris Teeter", "Kroger", "Ralphs". Matched against store name and chain code, so the everyday spelling works.
Inputs: chain, zip_code. Returns: result
kroger_searchA
Exact SKU-level prices (regular and promo) from a Kroger-banner store via Kroger's official API — Kroger, Harris Teeter, Ralphs, Fred Meyer, King Soopers, QFC, Smith's. More precise than the circular. Requires Kroger API credentials; without them the other tools still work.
Args: query: product term, e.g. "greek yogurt". location_id: store ID from kroger_find_stores. Optional if KROGER_LOCATION_ID is set. limit: max products (default 15).
Inputs: query (required), limit, location_id. Returns: result
list_storesA
List grocery stores near a ZIP code that have an active weekly ad, with how many deals each is running. Start here.
Args: zip_code: 5-digit US ZIP code, e.g. "12345". Optional if the server has a GROCERY_ZIP default configured.
Inputs: zip_code. Returns: result
price_checkA
Judge whether a current price is actually good, using the price history this server accumulates. Gets more useful the longer it has been running.
Args: item: the product to evaluate, e.g. "boneless chicken breast". zip_code: 5-digit US ZIP code. Optional if GROCERY_ZIP is set.
Inputs: item (required), zip_code. Returns: result
refresh_dealsA
Force a rebuild of the deal index from Flipp. Takes 10-20 seconds. Only needed mid-week; the index otherwise refreshes itself.
Args: zip_code: 5-digit US ZIP code. Optional if GROCERY_ZIP is set.
Inputs: zip_code. Returns: result
search_dealsA
Search this week's ads across every local grocery store for a product.
Args: query: what you're looking for, e.g. "chicken breast", "greek yogurt". zip_code: 5-digit US ZIP code. Optional if GROCERY_ZIP is set. stores: optional store names to restrict to, e.g. ["Aldi", "Costco"]. max_price: only return items at or below this price. limit: max results (default 25).
Inputs: query (required), limit, stores, zip_code, +1 more. Returns: result
shopping_planA
Turn a shopping list into a trip plan: which store to buy each item at.
Args: items: things you want to buy, e.g. ["chicken thighs", "blueberries"]. zip_code: 5-digit US ZIP code. Optional if GROCERY_ZIP is set. max_stores: how many stores you're willing to visit (default 2).
Inputs: items (required), zip_code, max_stores. Returns: result
store_circularA
Show everything in one store's current weekly ad.
Args: store: store name, e.g. "Giant Food", "Aldi", "Costco". zip_code: 5-digit US ZIP code. Optional if GROCERY_ZIP is set. limit: max items to return (default 150).
Inputs: store (required), limit, zip_code. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Most tools have distinct purposes, but there is overlap between list_stores and kroger_find_stores (both find stores) and between search_deals and kroger_search (both search for products, though against different data sources). Descriptions clarify the differences well enough.
Naming style is mixed: list_stores, search_deals, price_check, and refresh_deals follow verb_noun, while store_circular and shopping_plan are noun phrases, and kroger_search/kroger_find_stores add a brand prefix. All use snake_case, but the inconsistent verb/prefix usage is noticeable.
Eight tools is well-scoped for a grocery deals server. Each tool serves a clear purpose within the domain, and none feel redundant or excessive.
The set covers the core lifecycle: discover stores, search deals, view circulars, plan shopping, check price history, and refresh data. The Kroger-specific tools add precision. Minor gaps exist (e.g., no store details or deal detail endpoint), but agents can accomplish primary workflows.
Maintenance
Related MCP Connectors
MCP server aggregating developer infrastructure deals, free tiers, and startup programs
Hosted MCP server exposing US hospital procedure cost data to AI assistants
Unlock the power of food transparency with our Open Food Facts MCP server. Easily look up any food
MCP server that lets your AI assistant build and deploy apps, hosting each one at a live URL.
Related MCP Servers
- FlicenseAqualityAmaintenanceA Model Context Protocol server for real-time Swiss grocery shopping that searches and compares products across 8 major Swiss retailers (Migros, Coop, Aldi, Denner, Lidl, Farmy, Volgshop, Otto’s), normalizes per-unit prices, surfaces promotions, computes optimal multi-store shopping plans, and works with any MCP-compatible client without API keys or accounts.7524 npm42-
- AlicenseAqualityBmaintenanceAn MCP server for Nordic grocery shopping that finds deals across supermarkets in Denmark, Norway, Sweden, and Finland, plans weekly dinners around cheap ingredients, and generates shopping lists grouped by store.1848MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server for grocery shopping at Kroger-owned stores, enabling product search, store finder, cart management, and more through AI assistants.4 npmMIT
- AlicenseAqualityDmaintenanceMCP server that queries Norwegian grocery store flyers (kundeaviser) to help AI agents plan cheap meals based on current offers.71MIT