MCP server for grocery shopping — search products and manage carts across Swedish grocery stores.
Matkorgen demonstrates solid foundational tool design with clear verb-noun naming and consistent schema patterns. All 8 tools have explicit descriptions and Zod-validated input schemas. However, several patterns from the 54 Agentic Tool Patterns are missing or underutilized: output schemas are undocumented (tools return plain text JSON strings rather than structured responses), error handling lacks recovery guidance, and parameter descriptions could be more specific about constraints and dependencies. Tool compositions are logically sound (set_store → login → operations), but the server lacks pagination support, result limits, and the ability to guide the LLM toward recovery when operations fail. Schema quality is above average (all params typed), but descriptions lack the specificity needed to fully disambiguate context (e.g., 'Falls back to ICA_USERNAME env var if omitted' is helpful but doesn't explain what happens if both are omitted). The server scores in the 'Fair' range, noticeable gaps but functional and domain-appropriate.
Add a product to the shopping cart by product ID and quantity. Requires set_store (and login for persistent carts).
Retrieve current cart contents — items, quantities, prices, totals. Requires set_store.
Retrieve the logged-in user's favourite / starred products. Requires set_store and login. Not all stores support this.
Retrieve products from the logged-in user's purchase history. Requires set_store and login. Not all stores support this.
Authenticate with the active store. Must be called after set_store and before cart operations. Credentials are optional — if omitted, falls back to ICA_USERNAME / ICA_PASSWORD environment variables.
Remove a given quantity of a product from the cart. If quantity ≥ current amount the item is removed entirely. Requires set_store.
Output schemas are undocumented. All tools return raw text (JSON.stringify) without declaring the structure of products, carts, or history responses. LLMs cannot plan downstream operations or extract specific fields without trial-and-error parsing.
Error messages lack recovery guidance. When search_products returns no results or login fails, the response is a generic error string with no hint about what the LLM should try next (e.g., 'Try a different search term' or 'Check credentials').
Parameter constraints lack specificity. 'Store chain cannot be empty' is clear, but constraint descriptions for quantities, store IDs, and search queries don't include ranges or format examples. E.g., 'Quantity must be at least 1' doesn't state if there's an upper limit.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 59 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 56 | - | v1 |
Search for products by name or ingredient. Returns IDs, names, prices, and URLs. Requires set_store.
Initialise a grocery store session. Provide the store chain (e.g. "ica") and optionally a store location ID (required for ICA). Must be called first.
No pagination or result limits documented. search_products and get_purchase_history could return hundreds of items, risking context window exhaustion. No limit parameter, no offset/cursor mechanism, and no indication of max results in descriptions.
Dependency documentation incomplete. get_favourites and get_purchase_history require both set_store AND login, but this is only mentioned in descriptions; parameter-level documentation of these dependencies is absent. set_store description says 'Must be called first' but doesn't clarify what 'first' means relative to login.
Error classification absent. When add_to_cart fails, the LLM doesn't know if the error is retryable (network timeout), user-fixable (invalid product ID), or fatal (API down). No guidance on retry logic or user intervention.
No tool annotations for safety. Destructive tools (remove_from_cart, add_to_cart) lack idempotentHint or destructiveHint markers that would signal to the LLM whether repeated calls with the same input produce the same result or accumulate side effects.