MCP server wrapping rema1000-cli — REMA 1000 products, campaigns, receipts and shopping lists (personal use)
Strong tool naming (all verb-prefixed, clear intent). Descriptions are detailed and context-rich (avg 180 chars), well above the 10-char minimum. Input schemas use Zod with proper types and constraints. However, output schemas are undocumented (tools return JSON via jsonResult() but no schema is declared to the MCP client), and error handling lacks recovery guidance. Missing tool annotations (readOnlyHint, destructiveHint). Composition is sound, tools chain well (search_products → add_list_item via gtin). No security issues detected (no secrets in params). Destructive operations (delete_shopping_list) require confirmation string, which is good practice.
Add an item to a REMA 1000 shopping list. Pass gtin (from search_products) to link a catalog product; without it the item is free text.
Create a new shopping list in the user's REMA 1000 Æ app.
Delete a REMA 1000 shopping list and all its items. Cannot be undone and the list may have been made by the user in the Æ app — confirm with the user first. Requires confirmation string 'DELETE LIST'.
Check whether the user is logged in to REMA 1000. If not, ask the user to run 'rema auth login' in a terminal (opens a browser for phone authentication) — the agent cannot log in for them.
List current REMA 1000 sales campaigns with product-level sale prices and before-prices (the weekly 'Superpriser' flyer). This is REMA's main public price surface — the catalog search has no prices.
Output schemas are not documented. Tools return JSON via jsonResult() but MCP client receives no schema declaration. LLMs cannot plan downstream calls or validate response structure.
Tool annotations missing. No readOnlyHint on read-only tools (get_*), no destructiveHint on delete_shopping_list, no idempotentHint on idempotent operations. Agents cannot infer safety/retry semantics.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
List the user's current REMA 1000 offers, missions and price cuts (personalized via the Æ program).
List the user's REMA 1000 purchases (receipt headers with store, date and total). Use get_receipt for line items.
Get the line items of one REMA 1000 receipt: product names, EAN barcodes, quantities, prices and discounts. These are real observed prices — useful as ground truth for price comparison.
Get one REMA 1000 shopping list with its items.
List the user's REMA 1000 shopping lists (synced with the Æ app).
Remove one item from a REMA 1000 shopping list.
Search REMA 1000's product catalog. Norwegian terms work best (e.g. 'melk'). NOTE: results have NO prices (REMA does not expose catalog prices) — only GTIN/EAN, name and packing size. For REMA prices use get_campaigns (sale prices), get_offers (personal price cuts) or get_receipt (observed prices from purchases).
Search REMA 1000 physical stores by name or postal code.
Update a shopping list item: check it off (checked=true), rename, or change quantity.
Error handling lacks recovery guidance. Tools delegate to rema CLI and getCampaigns() but do not document what errors can occur or how to recover. E.g., if auth fails, should agent retry or ask user to login?
get_shopping_list and get_shopping_lists lack descriptions of the returned data structure. What fields does a shopping list contain? What does an item object look like?
update_list_item has optional parameters (checked, name, quantity) but no guidance on which combinations are valid. Can you update only quantity? Only name? All three together?