--- name: marktguru license: Apache-2.0 description: Query weekly supermarket offers, flyer discounts, and price comparisons across German supermarkets (ALDI Süd, ALDI Nord, Lidl, EDEKA, REWE, Kaufland, PENNY, Netto, dm, ROSSMANN, etc.) via the Marktguru API and local MCP server. Use when the user asks to check supermarket discounts, find deals in brochures/prospekte, compare grocery prices for a postal code (PLZ), or create shopping lists from current promotions without needing fragile PDF OCR. --- # Marktguru Supermarket Offers & MCP Server > Query live promotional flyers and circular offers from German supermarkets and drugstores without brittle PDF scraping or layout OCR. This skill is inspired by and expands upon the Home Assistant integration pattern (`thorschtn/ha-marktguru`), leveraging Marktguru's backend API (`api.marktguru.de`) to retrieve structured deal data for any German postal code. --- ## Supported Supermarkets & Retailers Marktguru covers **over 450 retail chains** across Germany. The primary supported chains are: * **Discounter**: * **ALDI SÜD** (`127153`) & **ALDI NORD** (`127139`) * **Lidl** (`126679`) * **PENNY** (`126765`) * **Netto Marken-Discount** (`126735`) & **Netto (mit Hund)** (`126734`) * **NORMA** (`126745`) * **Supermärkte & Vollsortimenter**: * **EDEKA** (`127093`) & **E center** (`126699`) + regionale Kaufleute (Simmel, Zurheide, etc.) * **REWE** (`126802`) & **REWE Center** (`126804`) * **nahkauf** (`137320`), **HIT** (`126598`), **tegut** (`126866`) * **Großfläche / Hypermarket**: * **Kaufland** (`126654`) * **Globus** (`127177`) * **Drogerien & Reform**: * **dm-drogerie markt** (`127057`) * **ROSSMANN** (`126811`) * **Müller Drogeriemarkt** (`126720`) Full details and ID mappings are documented in [`references/supermarkets.md`](references/supermarkets.md). --- ## Components The skill provides two primary components: 1. **CLI & Python Client (`scripts/marktguru_client.py`)**: Zero external dependencies (uses standard library `urllib` and `json`). 2. **MCP Server (`scripts/marktguru_mcp.py`)**: Standard JSON-RPC 2.0 stdio server providing AI tools for search, comparison, and catalog retrieval. --- ## 1. CLI Usage Run directly with standard `python3` (uses default postal code **`93059` Regensburg** if `--zip` is omitted): ### A. Search for Deals ```bash # Search for butter in Regensburg (93059 default) across Aldi, Lidl, and Edeka python3 scripts/marktguru_client.py search "Butter" --supermarket "Aldi,Lidl,Edeka" # Search for coffee with raw JSON output python3 scripts/marktguru_client.py search "Kaffee" --json ``` ### B. Price Comparison (Sorted Ascending) ```bash # Compare chocolate prices across all supermarkets in 93059 python3 scripts/marktguru_client.py compare "Schokolade" # Compare beer prices between Lidl and Rewe in another postal code (e.g. 80331) python3 scripts/marktguru_client.py compare "Bier" --zip 80331 --supermarket "Lidl,Rewe" ``` ### C. List Supported Chains ```bash python3 scripts/marktguru_client.py supermarkets ``` --- ## 2. Model Context Protocol (MCP) Integration The MCP server exposes three tools to any MCP-compatible AI agent: * `search_supermarket_offers(query, zip_code="93059", supermarkets=None, limit=20)` * `compare_supermarket_prices(query, zip_code="93059", supermarkets=None)` * `list_supported_supermarkets()` ### MCP Server Configuration (`mcp_config.json`) To enable the server in Antigravity or other MCP hosts: ```json { "mcpServers": { "marktguru": { "command": "python3", "args": [ "/Users/moritz/src/infrapuzzle/.agents/skills/marktguru/scripts/marktguru_mcp.py" ] } } } ``` --- ## 3. Python Integration You can import the module directly in Python scripts or agent sidecars: ```python import sys sys.path.append("/Users/moritz/src/infrapuzzle/.agents/skills/marktguru/scripts") from marktguru_client import search_offers, compare_prices, DEFAULT_ZIP_CODE # Search deals (defaults to 93059) results = search_offers("Kaffee", supermarkets=["Aldi", "Lidl"]) for offer in results["offers"]: print(f"[{offer['supermarket']}] {offer['product_name'] or offer['description']}: {offer['price']} €") # Compare prices comparison = compare_prices("Milch") cheapest = comparison["cheapest_offer"] print(f"Cheapest milk: {cheapest['price']} € at {cheapest['supermarket']}") ``` --- ## Data Extracted Per Offer Each item returned from the Marktguru API includes: * `id`: Internal Marktguru offer ID. * `supermarket`: Retailer name (e.g. "ALDI SÜD", "Lidl", "EDEKA"). * `product_name`: Generic product name (e.g. "Butter", "Filterkaffee"). * `brand`: Brand name (e.g. "Kerrygold", "Melitta", "Milka"). * `description`: Promotional description / pack size (e.g. "je 250g Packung"). * `price`: Promotional sale price in Euros (€). * `old_price`: Regular price or crossed-out price (UVP). * `discount_percent`: Calculated percentage savings (e.g. 28%). * `reference_price`: Unit price (e.g. 5.16 € / kg). * `loyalty_app_required`: Boolean flag indicating if a digital store app (Lidl Plus, Edeka App, Penny App) is required to receive the discount. * `valid_from` & `valid_to`: Start and end dates of the promotion. * `image_url`: High-resolution product image hosted on CDN.