Swissgroceries MCP
The Swissgroceries MCP server provides real-time Swiss grocery shopping data across major chains (Migros, Coop, Aldi, Denner, Lidl, Farmy, Volgshop, and Otto's).
Search Products: Search by keyword across all chains with filters for price (max CHF), size range, and tags (organic, vegan, gluten-free, etc.). Returns normalized prices, unit prices, and promotion info grouped by chain.
Product Details: Fetch full details for a specific product (price, brand, size, unit price, tags, category, image URL, active promotions) by chain + product ID.
Price Comparison: Compare prices across chains in a single search.
Promotions: Browse current deals filterable by keyword, chain, store ID, or days until expiry.
Store Locator: Find nearby stores by ZIP code, GPS coordinates, or address, with optional chain and radius filters (up to 50 km).
Stock Check: Check which stores have a given product in stock (supported: Migros, Coop, Otto's).
Shopping Trip Planner: Plan multi-store trips for a list of items using three strategies —
single_store(minimize stops),split_cart(multi-chain with configurable per-stop penalty), orabsolute_cheapest(lowest price per item regardless of stops). Supports generic searches or pinned SKUs.Recipe/Ingredient Shopping: Automatically find the cheapest places to buy ingredients from a list or recipe URL.
Health Check: Probe chain adapters to report status, latency, and supported capabilities for diagnostics.
Real-time Swiss grocery shopping over the Model Context Protocol. Search products, compare prices across Migros, Coop, Aldi, Denner, Lidl, Farmy, Volgshop, and Otto's, see weekly promotions, and plan multi-store shopping trips. Works with any MCP-compatible client (Claude Desktop, Claude Code, Cursor, Cline, Continue, VS Code MCP extensions, custom clients).
Disclaimer
This is a personal fun project. It is not affiliated with, endorsed by, or sponsored by Migros, Coop, Aldi, Denner, Lidl, Farmy, Volg, Otto's, or any other retailer. It uses publicly accessible mobile-app endpoints to make Swiss grocery shopping a bit smarter for end users.
If you represent any of these stores and have concerns (about API usage, branding, scraping rate, or anything else), please reach out to the maintainer through GitHub and we will work it out. No need to escalate.
API stability: the chain APIs used here are unofficial and can change at any time. The maintainer is not responsible for failures caused by upstream changes; please open an issue with the response sample so the affected adapter can be updated.
PRs welcome. New chains, better matchers, smarter strategies, bug fixes, doc improvements; all encouraged. See CONTRIBUTING.md.
Install
No accounts, no tokens, no API keys required. The Denner adapter self-registers an anonymous client on first use; everything else uses public endpoints.
Claude Desktop (one-click)
Download swissgroceries-mcp.mcpb from the Releases page and:
macOS: double-click or drag onto the Claude Desktop app icon.
Windows: Settings → Extensions → Advanced → Install Extension → select the file.
Claude Code (one-liner)
claude mcp add swissgroceries -- npx -y @nicktcode/swissgroceries-mcpCursor / Cline / Continue / VS Code / Claude Desktop (manual config)
Most MCP-compatible clients accept the same JSON server entry. Add it to your client's MCP config file (paths vary, see your client's docs):
{
"mcpServers": {
"swissgroceries": {
"command": "npx",
"args": ["-y", "@nicktcode/swissgroceries-mcp"]
}
}
}Common config paths:
Claude Desktop:
~/Library/Application Support/Claude/claude_desktop_config.json(macOS),%APPDATA%\Claude\claude_desktop_config.json(Windows).Cursor:
.cursor/mcp.jsonin the project, or~/.cursor/mcp.jsonglobally.Cline / Continue / VS Code: see each client's MCP documentation.
Custom clients: any stdio-based MCP client can spawn
npx -y @nicktcode/swissgroceries-mcpdirectly.
Related MCP server: trundler
What you can ask
Price comparison
"Where is milk cheapest near 8001 Zürich right now?"
"Compare pasta prices across Migros and Coop."
"Show me organic milk options under CHF 3."
Shopping planning
"I need milk, bread, eggs, chicken, and pasta near 8050. Where should I shop to keep costs down?"
"Plan my weekly shop for 5 items near 4052 Basel, one stop only."
"Split my cart across stores for the absolute lowest total, but add a 2 CHF penalty per extra trip."
Promotions and deals
"What is on sale at Aldi this week?"
"Any Migros deals on cheese ending this week?"
"Show me all promotions across chains for pasta."
Stores and stock
"Find Coop stores within 3 km of Bern Hauptbahnhof."
"Which Migros near me has product 4389992 in stock?"
"List Denner branches near 8050."
Tools
Tool | What it does |
| Find grocery stores near a location, filtered by chain and radius. |
| Cross-chain product search with normalised price, unit price, size, and tags. |
| Full product details for a chain plus product ID pair. |
| Current promotional deals, filterable by chain, keyword, store, or expiry. |
| Stores of a chain that have a given product in stock. |
| Plan a multi-store trip for a shopping list near a location. |
| Probe each registered chain adapter and report status, latency, and capabilities. |
Each tool exposes rich JSON Schema with field-level descriptions, so the LLM knows when and how to call it.
Prompts
Prompt | What it does |
| Summarise this week's best grocery deals across the configured chains. Optional category, chains, and location filters. |
| Compare a shopping basket across all chains and recommend single-store vs split-cart strategies. |
| From an ingredient list (or recipe URL) find the cheapest place to buy each item and produce a consolidated shopping plan. |
Prompts are surfaced as one-click templates in MCP-aware clients (Claude Desktop, Cursor, Cline). They produce structured user messages that drive the right tool calls — useful as a starting point and as discovery of what the server can do.
Resources
URI | Content |
| JSON list of registered chain adapters and their capabilities ( |
Chain coverage
Chain | Product search | Promotions | Per-store stock | Nutrition | Auth |
Migros | Full catalog | Yes | Yes | Yes (product detail) | Guest token (auto, rotated on expiry) |
Coop | Full catalog (coopathome) | Yes | Yes (geo) | Yes (product detail) | None |
Aldi | Full catalog | Yes | No | No (API exposes only allergen claims) | None |
Denner | Full catalog | Yes | No | No | Anonymous self-auth (signup + signin, rotated) |
Lidl | Weekly leaflet only | Yes | No | No ( | None |
Farmy | Full catalog (organic delivery) | Yes (strikeout-price filter) | No (delivery-only) | No | None |
Volgshop | Full catalog | Yes ( | No (delivery-only) | Yes (parsed from free-text attribute, basis assumed 100g) | None |
Otto's | Grocery-adjacent (food, drugstore, baby) | Yes (priceLabels facet) | Yes (per-store stockLevel) | No | None |
NormalizedProduct.nutrition is normalized to a per-100g (or per-100ml) basis with the standard Swiss labelling fields — energyKj, energyKcal, fat, saturatedFat, carbs, sugar, fiber, protein, salt — so consumers can sort across chains ("highest protein per 100g lasagne") even though each upstream API exposes the data on a different surface and in a different shape. Missing or unparseable fields are left undefined; adapters never fabricate values.
Configuration
Env var | Default | Effect |
| (unset) | Optional pre-supplied Denner Bearer JWT. Without it, the adapter self-registers anonymously on first use and rotates the token automatically. |
|
| Default Lidl store ID used when no |
| (default iOS Safari UA) | Override the User-Agent for Coop calls if DataDome ever blocks the default. |
|
|
|
| (unset) | Set to |
How it works
Each grocery chain is wrapped in an independent adapter (src/adapters/<chain>/) that handles authentication, HTTP calls, and raw-to-normalised mapping. Adapters all produce the same NormalizedProduct, NormalizedStore, and NormalizedPromotion shapes (defined in src/adapters/types.ts), so the rest of the system never has to know which chain it is talking to.
The HTTP utility (src/util/http.ts) underpins every adapter except Migros (which delegates to the migros-api-wrapper library): in-memory response caching with a 5-minute TTL, retry with exponential backoff (3 attempts, 250 ms base), per-host rate limiting (~10 requests per second), and a per-host circuit breaker that opens after 5 consecutive failures and resets after 60 seconds.
The shopping planner (src/services/planner.ts) fans out store and product searches in parallel across all active adapters, then feeds results into a strategy solver (src/services/strategy.ts) that supports three modes:
single_store: minimise the number of stops.split_cart: cheapest split across chains, with a configurable per-stop penalty.absolute_cheapest: cheapest split, ignoring stop count.
Cross-chain comparisons are kept fair by a category-text canonicality filter (src/services/matcher.ts, isCanonical). When at least one chain returns a product whose category text matches the query, results from chains that only returned tangential products (for example, Apfelschorle when searching for "apfel") are dropped from the comparison matrix for that item.
MCP client (any LLM)
│
│ MCP tool call
▼
src/index.ts ── buildRegistry() ────────────────────────────────────────┐
│ │
│ routes to tool handler │
▼ ▼
src/tools/ src/adapters/
find_stores.ts ──► geocoding ──► adapter.searchStores migros/
search_products.ts ──────────────► adapter.searchProducts coop/
get_product.ts ──────────────► adapter.getProduct aldi/
get_promotions.ts ──────────────► adapter.getPromotions denner/ (auto-auth)
find_stock.ts ──────────────► adapter.findStoresWithStock lidl/
plan_shopping.ts ──► geocoding ──► planner ──► strategy solver
│
NormalizedProduct
NormalizedStore
NormalizedPromotionBuild from source
node --version # requires Node.js >=20
git clone https://github.com/nicktcode/swissgroceries-mcp
cd swissgroceries-mcp
npm install
npm run buildTo also build the .mcpb bundle locally:
npx tsx scripts/build-mcpb.tsTroubleshooting
Coop "DataDome challenge" error
You hit Coop's bot protection. Set SWISSGROCERIES_USER_AGENT_COOP to a freshly captured iOS Safari User-Agent string and try again.
Denner "auth_expired" error
Rare, since the adapter rotates its token automatically. If it persists, unset any custom DENNER_JWT and let the adapter re-bootstrap from scratch.
Lidl returns 0 results
Lidl only indexes products from the current weekly campaign leaflet. If your search term is not in this week's campaigns, you will get 0 results. This is expected.
ZIP unknown error
The static lookup table covers all 3,190 official Swiss postcodes. If yours is missing, pass { lat, lng } directly or open an issue with the missing PLZ.
Migros stores nowhere near my location
The Migros store-search API caps at ~10 results per query. The adapter passes a city hint derived from your ZIP. If you call the adapter directly without ZIP-based geocoding, pass cityHint explicitly.
Development
npm test # full test suite, no network calls
RUN_LIVE=1 npm test # also runs live smoke tests against real chain APIs
npm run dev # tsx watcher for local iteration
SWISSGROCERIES_DISABLE_CACHE=1 RUN_LIVE=1 npm test # cache off, useful for debugging
SWISSGROCERIES_LOG_LEVEL=debug npm run dev # verbose loggingThe test suite uses Vitest. Fixture JSON files live under tests/fixtures/<chain>/. Capture scripts in scripts/ show how to refresh them.
Adding a new chain
See CONTRIBUTING.md for the full guide. Quick version:
Capture API responses with Charles Proxy or mitmproxy on the chain's iOS or Android app.
Create
src/adapters/<chain>/{client,tags,normalize,index}.tsfollowing the existing patterns. Usesrc/adapters/aldi/as the simplest reference.Map raw responses to
NormalizedProduct,NormalizedStore, andNormalizedPromotion.Declare capability flags accurately.
Register the adapter in
src/index.ts'sbuildRegistry().Add fixture-based tests under
tests/adapters/.
License
Dual-licensed:
Open-source use: AGPL-3.0-only. If you run a modified version of this software as a network service, you must publish your modifications.
Commercial use: if AGPL-3.0 is incompatible with your project (e.g. a closed-source SaaS or proprietary app), a commercial license is available — see LICENSING.md or contact
nick@thommen.it.
Versions ≤ 0.7.4 were released under MIT and remain MIT-licensed in their existing published form. Starting with 0.7.5 the license is AGPL-3.0-only.
Available Tools
7 toolsfind_stockA
Check which stores of a given chain have a specific product in stock. Optionally filter by proximity to GPS coordinates or query a single store by ID. Not all chains support per-store stock queries; unsupported chains return a clear error. Use for "is this product available near Zurich HB?", "which Coop has item X in stock?".
| Name | Required | Description | Default |
|---|---|---|---|
| chain | Yes | The chain to query for stock. Only chains with perStoreStock capability are supported. | |
| productId | Yes | Chain-specific product ID to check stock for. Obtain via search_products or get_product. | |
| near | No | Optional location to filter nearby stores. Pass coordinates, a Swiss ZIP, or a free-text address. If omitted, all stores may be queried. | |
| storeId | No | Query a single specific store by its chain-specific store ID. Takes precedence over `near`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that not all chains support per-store stock queries and that unsupported chains return a clear error. It also mentions that storeId takes precedence over near. With no annotations, the description carries the burden, but it omits details about response format, rate limits, or authentication.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no redundant information. The first sentence states the core purpose, followed by filtering options and a note about chains. It is front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of an output schema and annotations, the description adequately covers the main purpose, filtering options, and chain limitations. However, it does not describe the output returned (e.g., list of stores with availability), leaving a gap in completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the input schema already describes each parameter in detail. The description adds a high-level summary but does not provide new semantic information beyond what is in the schema, resulting in a baseline score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'check' and resource 'stores of a given chain have a specific product in stock'. It clearly distinguishes from siblings like find_stores (which finds stores) and get_product (which gets product info) by focusing on stock availability.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases ('is this product available near Zurich HB?', 'which Coop has item X in stock?') and notes that unsupported chains return a clear error. However, it does not explicitly contrast with sibling tools or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_storesA
Find grocery stores near a location, filtered by chain and search radius. Accepts a Swiss ZIP code, GPS coordinates, or a free-text address as the search center. Returns store name, address, chain, location, and opening hours where available. Use for "find a Migros near me", "which Coop branches are in 8001?", or before checking stock.
| Name | Required | Description | Default |
|---|---|---|---|
| near | Yes | Center of the search radius. Pass either coordinates, a Swiss ZIP, or a free-text address. | |
| chains | No | Limit results to specific chains. Omit to search all configured chains. | |
| radiusKm | No | Search radius in kilometers (1–50). Defaults to 5 km. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It explains that the tool returns store details including opening hours where available, indicating a read-only operation. However, it does not disclose potential rate limits, authentication needs, or any side effects, which is acceptable for a simple search tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences: first states purpose, second describes inputs, third summarizes outputs and examples. It is front-loaded with key information, no redundant phrases, and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with 3 parameters and no output schema, the description adequately covers inputs, outputs, and example usage. It mentions return fields (name, address, chain, location, hours). It could have explicitly stated the default radius, but that is detailed in the schema. Overall, it is sufficiently complete for an agent to use effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with descriptions for each parameter. The description adds minor context (e.g., prefer zip or lat/lng for speed, geocoding via Nominatim) but mostly restates schema information. The baseline score of 3 is appropriate as the description provides some additional guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool finds grocery stores near a location with filters for chain and radius, using specific verbs and resource. It also provides example use cases that distinguish it from siblings like find_stock and get_product.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete examples of when to use this tool ('find a Migros near me', 'which Coop branches are in 8001?') and hints at its role before checking stock. However, it does not explicitly state when not to use it or provide alternatives for non-store queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_productA
Fetch full product details for a specific chain + product ID pair. Returns { product, fetchedAt, fromCache }: the product carries price, brand, size, unit price, tags, category, image URL, and active promotions, while fetchedAt + fromCache report how fresh the data is. Obtain product IDs from search_products. Useful for drilling into a search result. Use for "get details for this Migros product" or "what is the unit price of this item?".
| Name | Required | Description | Default |
|---|---|---|---|
| chain | Yes | The grocery chain that owns this product ID. | |
| id | Yes | Chain-specific product identifier, e.g. Migros cumulus ID or Coop product number. Obtain via search_products. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility. It discloses the return structure ({ product, fetchedAt, fromCache }), the contents of product (price, brand, etc.), and data freshness (fetchedAt, fromCache). It does not cover authentication or rate limits, but for a read-only operation this is acceptable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long plus a brief list of return fields, with no wasted words. The most critical information (what the tool does) appears first, and subsequent details are efficiently structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description fully covers the return object's shape and semantics. It explains how to obtain input IDs, what the tool does, and how to interpret results. For a two-parameter read tool, this is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (both parameters have descriptions). The description adds context by explaining where to get IDs ('Obtain product IDs from search_products') but does not significantly extend the schema's own parameter explanations. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair ('Fetch full product details') and clearly identifies the scope ('specific chain + product ID pair'). It distinguishes from siblings by noting it is used after search_products and lists alternative fields (price, brand, etc.) that differentiate it from other tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states explicit use cases ('drilling into a search result', 'get details for this Migros product') and advises obtaining IDs from search_products. It does not explicitly mention when not to use, but the context signals and sibling names imply alternatives (e.g., find_stock for inventory).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_promotionsA
List current promotional deals across configured Swiss grocery chains. Filter by chain, keyword, store ID, or how many days until the promotion expires. Returns promotion name, discount, validity dates, and applicable stores. Use for "what is on sale this week?", "any Migros deals on cheese?", or "promotions ending today".
| Name | Required | Description | Default |
|---|---|---|---|
| chains | No | Limit to specific chains. Omit to fetch promotions from all configured chains. | |
| query | No | Optional keyword to filter promotions by product name, e.g. "Käse", "wine". | |
| endingWithinDays | No | Only return promotions ending within this many days (1–60). Useful for "ending soon" queries. | |
| storeIds | No | Restrict to promotions valid at these store IDs (chain-specific). Obtain store IDs from find_stores. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description transparently explains the tool's behavior: it lists promotions, returns specific fields (name, discount, validity dates, stores), and supports filters. It doesn't mention potential limitations like rate limits or authentication, but the read-only nature is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (two sentences) and front-loaded: first sentence states the main function and filters, second lists returns and usage examples. Every sentence is meaningful and directly contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description adequately covers what the tool returns (name, discount, validity dates, applicable stores). It doesn't mention pagination or result limits, but for a promotional listing query, the essential information is provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All 4 parameters have schema descriptions (100% coverage). The description adds value by providing concrete examples (e.g., 'Käse', 'wine' for query) and referencing the helper tool find_stores for store IDs, enriching the schema information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists current promotional deals across Swiss grocery chains, with a specific verb and resource. It distinguishes itself from sibling tools like search_products (general product search) and get_product (single product details) by focusing on promotions and filtering options.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage examples (e.g., 'what is on sale this week?', 'any Migros deals on cheese?'), guiding when to use the tool. It does not explicitly state when not to use it, but the context contrasts well with sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
health_checkA
Probe each registered chain adapter with a trivial query and report status, latency, and capability flags. Use this when a chain seems missing from results or when debugging adapter problems.
| Name | Required | Description | Default |
|---|---|---|---|
| chains | No | Chains to probe. Default: all configured. | |
| timeoutMs | No | Per-chain timeout in milliseconds. Default 5000. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It describes the operation as 'probe with a trivial query' and reports status/latency/capability flags, implying a read-only health check. However, it does not explicitly confirm no side effects, auth requirements, or rate limits. The description is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: first states functionality, second provides usage guidance. No wasted words, front-loaded with key action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple diagnostic tool with 2 optional params and no output schema, the description covers purpose, trigger, and high-level output. Could be slightly more detailed on output format, but sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with both parameters documented. The description adds no new meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'probe' and resources 'chain adapters' and states outputs: status, latency, and capability flags. It also positions it for debugging missing chains, distinguishing it from sibling data tools like search_products or find_stock.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'chain seems missing from results' or 'debugging adapter problems'. Does not mention when not to use or contrast with alternatives, but the context with sibling tools makes the purpose distinct.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_shoppingA
Plan a multi-store shopping trip near a location, picking the best products across configured Swiss grocery chains. Items can be generic ("milch", "pasta") or pinned to a specific SKU. Returns a primary plan plus alternatives. Use when the user gives a list of items and asks "where should I shop?" or "what's cheapest?". Strategies: single_store (one chain), split_cart (multi-chain with stop penalty), absolute_cheapest (no penalty).
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | The list of items to shop for. At least one item required. | |
| near | Yes | Shopper's location — used to find nearby stores. Pass coordinates, ZIP, or address. | |
| chains | No | Restrict the plan to these chains. Omit to consider all configured chains. | |
| strategy | Yes | single_store: buy everything at one chain (minimises trips). split_cart: allow multiple chains but add splitPenaltyChf per extra stop. absolute_cheapest: pick the cheapest source per item regardless of stops. | |
| splitPenaltyChf | No | Cost in CHF added per extra store stop in split_cart strategy. Default 2.00. | |
| radiusKm | No | Only consider stores within this radius of the provided location (1–50 km). Default 5 km. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full responsibility. It mentions return of 'primary plan plus alternatives' and strategies, but does not elaborate on side effects, rate limits, or error behavior (e.g., no stores found). It is adequate but not detailed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with purpose, no redundant text. Each sentence contributes context: purpose, item types, usage hint, and strategy options.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers high-level purpose, item flexibility, and strategies. However, it lacks details on the return format (no output schema) and does not describe what happens when constraints fail (e.g., no matching products). Still, it is largely complete for a planning tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description adds little new information beyond strategies, making it a baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly specifies the tool's function: planning a multi-store shopping trip near a location, picking the best products across Swiss grocery chains. It distinguishes itself from siblings like find_stock and find_stores, which handle single-store queries or product lookups.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'Use when the user gives a list of items and asks "where should I shop?" or "what's cheapest?"' and outlines three strategies. However, it lacks explicit when-not-to-use guidance compared to alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_productsA
Search for products across configured Swiss grocery chains (Migros, Coop, Aldi, Denner, Lidl) by keyword. Supports optional filters for price, size range, and product tags (organic, vegan, budget, etc.). Returns results grouped by chain with normalised price, unit price, size, and promotion info. A sources map reports each chain's data freshness (fetchedAt timestamp + fromCache flag) so you can tell the user how current the prices are. Use for "find organic milk under 2 CHF", "compare pasta prices", or "search for gluten-free bread".
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search term in any language, e.g. "Milch", "pâtes", "Bier". At least 1 character. | |
| chains | No | Restrict search to specific chains. Omit to search all configured chains in parallel. | |
| storeIds | No | Filter results to products available in these store IDs (chain-specific internal IDs). | |
| filters | No | Optional product filters applied after search. | |
| limit | No | Maximum number of results per chain (1–50). Defaults to chain-specific limit. | |
| offset | No | Skip the first N results per chain. Use with `limit` to paginate. Default 0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the behavioral burden. It discloses that results are grouped by chain, includes normalized price and promotion info, and reports data freshness via a sources map with timestamps. It does not explicitly state it is read-only, indicate rate limits, or mention authentication requirements, but the provided details are sufficient for safe usage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences efficiently cover purpose, filters, output format, and usage examples. No extraneous words, and key information is front-loaded. Ideal structure for an AI agent to quickly parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 6 parameters (including nested objects) and no output schema, the description adequately explains the return structure, filter logic, and data freshness. It lacks error handling or edge-case guidance, but the usage examples and parameter details cover typical scenarios. Minor gap in describing limit/offset pagination behavior, but overall complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters are individually described. The description adds value by explaining how filters combine (e.g., 'All tags must match') and contextualizes the output. However, it does not provide deeper semantic nuance beyond what the schema already conveys. Score reflects the baseline for full schema coverage with modest additive value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description specifies the core action 'Search for products' and the exact resource scope: 'across configured Swiss grocery chains (Migros, Coop, Aldi, Denner, Lidl)'. It provides concrete example queries like 'find organic milk under 2 CHF', which help distinguish this tool from siblings like get_product (single product lookup) and find_stock (inventory check).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description lists explicit use cases ('Use for ...') and demonstrates how to combine filters. It implies the tool is for cross-chain price comparisons and attribute searches. However, it does not explicitly state when not to use it or differentiate from get_product (single item) and find_stock (availability). The guidance is clear but lacks exclusionary context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
7 tool updates
v0.7.10- First observed
find_stock - First observed
find_stores - First observed
get_product - First observed
get_promotions - First observed
health_check - First observed
plan_shopping - First observed
search_products
TDQS
Each tool has a distinct, well-defined purpose without overlap. For example, 'find_stock' checks inventory at stores while 'search_products' searches for items by keyword, and 'plan_shopping' integrates multiple steps.
All tool names follow a consistent verb_noun pattern (e.g., 'find_stock', 'get_product', 'plan_shopping'), making them predictable and easy for an agent to understand.
With 7 tools, the set is well-scoped for a grocery shopping assistant. It covers search, detail retrieval, stock checking, promotions, store finding, health monitoring, and trip planning without being excessive.
The tool surface covers the core workflow: search, details, stock, stores, promotions, and multi-store planning. A minor gap is the lack of a persistent shopping list or saved favorites, but it's not essential for the primary purpose.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Unlock the power of food transparency with our Open Food Facts MCP server. Easily look up any food
Live prices, deals & optimal multi-stop shopping routes for German grocery & drug stores.
Hosted MCP for e-commerce: live product catalog, stock, and pricing for AI agents.
Google Shopping products, prices, sellers, and deals as structured data via a hosted MCP server.
Related MCP Servers
- AlicenseCqualityCmaintenanceA Model Context Protocol server enabling product searches across e-commerce platforms, price history tracking, and product specification-based searches using natural language prompts.219MIT
- AlicenseAqualityAmaintenanceA local MCP server for grocery shopping, enabling product search, specials, and browsing across NZ supermarkets, with cart and order history for Countdown/Woolworths via browser-assisted login.141MIT
- AlicenseAqualityCmaintenanceMCP server that queries Norwegian grocery store flyers (kundeaviser) to help AI agents plan cheap meals based on current offers.7MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for Dutch supermarkets and drugstores, enabling product search, price comparison, promotions, shopping lists, meal planning, price alerts, and budget tracking via natural language.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nicktcode/swissgroceries-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server