grocy-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GROCY_API_KEY | Yes | API key for Grocy | |
| GROCY_API_URL | Yes | URL of the Grocy API endpoint | |
| GROCY_MCP_CONFIG | No | Path to optional TOML configuration file | |
| GROCY_MCP_OIDC_ISSUER | No | OIDC issuer URL for HTTP authentication | |
| GROCY_MCP_OIDC_SCOPES | No | Space-separated OIDC scopes (optional) | |
| GROCY_MCP_OIDC_AUDIENCE | No | OIDC audience for HTTP authentication | |
| GROCY_MCP_OIDC_JWKS_URI | No | JWKS URI for OIDC (optional) |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_stockA | List everything currently in the pantry, read live from Grocy. This is always current — it queries Grocy on every call, so there is no need to check a timestamp or work around a cache. Args: location: Optional case-insensitive substring, e.g. "fridge", "freezer". Omit for everything. category: Optional product-group substring, e.g. "spices", "dairy". |
| expiring_soonA | List items already expired or due within N days, worst first. Args: days: Look-ahead window in days. Defaults to the configured window. |
| out_of_stockA | List products with zero stock — candidates for the next shopping trip. This is "there is none left at all", and it needs no minimum stock levels to be set. For products that still have some but have fallen under a configured minimum, use below_min_stock. |
| below_min_stockA | List products that have fallen below their minimum stock amount. This is Grocy's own "missing products" calculation, so it only sees products that have a minimum set (update_product's min_stock). In an instance where few products have one, an empty result means "no minimums are set" at least as often as it means "nothing is low" — out_of_stock is the one that works regardless. |
| list_stock_entriesA | List a product's individual stock entries — one per purchase batch. list_stock shows the total; this shows what that total is made of, since each batch carries its own best-before date and location. Call this to get an entry_id before edit_stock_entry, or to see which pack expires first. Args: product: Product name, description fragment, or barcode. |
| product_detailsB | Everything Grocy knows about one product: stock, dates, and history. Includes when it was last bought and last used, its average shelf life and spoil rate, the amount currently open, and its minimum stock level — the context for deciding whether to restock something or stop buying it. Args: product: Product name, description fragment, or barcode. |
| stock_historyA | What has been bought, used, opened or corrected recently. Grocy's stock journal, newest first. Use it to answer "what did we get through this week", to check a suspicious amount, or to find the transaction_id of something that needs undoing. Args: days: How far back to look. Defaults to a month. product: Optional — restrict to one product. limit: Maximum rows returned, newest first. Defaults to 100. |
| add_stockA | Record newly bought stock, and report the new total. Args: product: Product name, description fragment, or barcode. Must identify exactly one existing product — this does not create new products. amount: How much, in the product's own stock unit. best_before_date: YYYY-MM-DD. Use the package date when it is known; otherwise estimate it, and see get_conventions for whatever estimates this pantry uses. location_id: Where it is being put, if not the product's usual spot — either its id or its exact name. |
| consume_productA | Record that stock was used up, and report what is left. Args: product: Product name, description fragment, or barcode. Must identify exactly one product — this raises rather than guessing between two. amount: How much, in the product's own stock unit. Items tracked by weight need the weight, so "a teaspoon of turmeric" is roughly amount=5, not 1. Check list_stock's qty first if unsure. spoiled: True when it was thrown away rather than eaten. |
| open_productA | Mark stock as opened, without consuming it. Opened items usually keep for less time than the printed best-before date, so flagging them helps expiring_soon stay useful. Args: product: Product name, description fragment, or barcode. amount: How many units were opened, in the product's stock unit. |
| correct_stockA | Set stock to the amount actually counted on the shelf. This is the "I looked, and there are three" fix, for when the tracked amount has drifted from reality — someone used something without recording it, or a purchase was entered twice. It books the difference either way, so it can correct upward as well as down. To record ordinary use, prefer consume_product; to record a purchase, prefer add_stock. Args: product: Product name, description fragment, or barcode. actual_amount: The amount really there, in the product's stock unit. Zero is allowed and clears the product's stock. best_before_date: YYYY-MM-DD. Required when correcting upward, since the extra stock is a new entry and needs a date. location_id: Where the corrected stock is, if not the usual spot. |
| transfer_stockA | Move stock from one location to another — freezer to fridge, and so on. This changes where something is, not how much there is. Both locations take either an id or an exact name. Args: product: Product name, description fragment, or barcode. to_location: Where it is going. amount: How much is moving, in the product's stock unit. from_location: Where it is coming from. Optional when the product is only stored in one place; required when its stock is split, since guessing would move the wrong batch. |
| edit_stock_entryA | Fix one stock entry: its date, its location, or its amount. For correcting a best-before date that was estimated wrong, or a batch filed on the wrong shelf. Get the entry_id from list_stock_entries. Only the arguments given are changed; the rest of the entry is preserved. Args: entry_id: From list_stock_entries. best_before_date: YYYY-MM-DD. location_id: Either an id or an exact location name. amount: New amount for this entry, in the product's stock unit. Prefer correct_stock for "the total is wrong" — this is for when one specific batch is wrong. |
| undo_transactionA | Reverse a stock transaction that should not have been recorded. Every write tool returns a transaction_id; stock_history shows older ones. Undoing is the right way to fix a mistake — booking an opposite consume or purchase instead leaves both entries in the history and gets the best-before dates wrong. Args: transaction_id: From a write tool's response, or from stock_history. |
| search_productsA | Find products by name, description, or barcode — across the whole catalog, not just what's currently on the shelf. A miss means the product genuinely doesn't exist in Grocy. A hit's in_stock flag says whether there's actually any on hand right now — a hit with in_stock: false is a known product sitting at zero, not a false positive. Check this before create_product to catch an existing or near-duplicate product, and before add_stock/consume_product when unsure how something is named. Args: query: Case-insensitive substring, or a full GTIN/EAN barcode. |
| get_conventionsA | This instance's locations (with ids), categories, quantity units, and whatever house rules are configured — the reference every other tool's docstring points at. Call this once at the start of a session rather than guessing or trial-and-erroring an id. Locations, categories and units are read live, so this stays right even after something is renamed in the web UI. |
| create_productA | Add a new product to the catalog, for something never stocked before. This only creates the product record — call add_stock next to record an amount on hand. Refuses rather than guessing if the name already matches an existing product; use add_stock for those instead. A near-duplicate name (e.g. "Applesauce" vs an existing "Apple Sauce") does not block creation, but comes back in possible_duplicates — check that list before assuming the new product is really new. Args: name: Product name. See get_conventions for any naming rule this pantry follows. category: Product group name, exact match. See get_conventions. location_id: Usual storage location — either its id or its exact name. unit: Stock/purchase/consume unit name, e.g. "Piece", "Pack", "Gram". Must already exist in Grocy; see get_conventions. description: Short description identifying the exact item — brand, size, variant. min_stock: Optional minimum to keep on hand, in the same unit. Setting it is what makes below_min_stock and add_missing_to_shopping_list work for this product. |
| update_productA | Edit an existing product's catalog record. For fixing a typo, recategorising something, moving its default shelf, or setting a minimum stock level. Only the arguments given are changed. This does not touch stock amounts — use add_stock, consume_product or correct_stock for those. Args: product: Product name, description fragment, or barcode identifying the product to edit. name: New name. description: New description — brand, size, variant. category: New product group, exact name. See get_conventions. location_id: New default location, id or exact name. unit: New stock unit. Refused while any stock is on hand, since Grocy would reinterpret the existing amount in the new unit — 2 Packs silently becoming 2 Grams. Consume to zero first, or create a separate product. min_stock: Minimum to keep on hand, in the product's stock unit. Zero clears it. This is what below_min_stock and add_missing_to_shopping_list read. |
| add_barcodeA | Attach a GTIN/EAN barcode to a product. Once attached, that code resolves to this product everywhere a tool takes a product argument, so a scanned package can be consumed or restocked without typing a name. Args: product: Product name or description fragment. barcode: The full GTIN/EAN as printed under the bars. |
| remove_barcodeA | Detach a barcode that was attached to the wrong product. Args: barcode: The code to remove. It is removed from whichever product currently holds it. |
| delete_productA | Permanently remove a product with zero stock from the catalog. Refuses if any stock is on hand — consume_product it down to zero first. This is for cleaning up mistakes (a test product, a typo'd duplicate caught by search_products or create_product's possible_duplicates), not for retiring a product still in use. Args: product: Product name, description fragment, or barcode. Must identify exactly one product. |
| list_shopping_listA | Show the shopping list: what to buy, how much, and what's checked off. Rows either point at a catalog product or are free-text notes for things the pantry doesn't track. Checked-off rows stay on the list until clear_shopping_list removes them. |
| add_to_shopping_listA | Add something to the shopping list. If Args: item: Product name, description fragment, barcode, or free text. amount: How much to buy, in the product's stock unit. note: Optional extra text on the row, e.g. "the big tin". |
| remove_from_shopping_listA | Take a row off the shopping list entirely. For something added by mistake or no longer needed. If it was bought, prefer check_off_shopping_item (and add_stock), which leaves a record that the trip covered it. Args: item: Product name or note text, as shown by list_shopping_list. |
| check_off_shopping_itemA | Mark a shopping list row as bought (or un-mark it). Checking off does not add anything to stock — call add_stock for that, with the real best-before date from the package. Args: item: Product name or note text, as shown by list_shopping_list. done: False to un-check a row checked off by mistake. |
| add_missing_to_shopping_listA | Add everything below its minimum stock level to the shopping list. Grocy's own "add missing products". It only sees products that have a minimum set (update_product's min_stock), so in an instance where few do, read out_of_stock and add what's wanted by name instead — that needs no minimums. |
| clear_shopping_listA | Clear the shopping list after a shop. Args: done_only: True (the default) removes only the rows checked off, leaving anything still to buy. Pass False to wipe the list completely — that discards unbought items too. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 27 tools
Every tool targets a distinct resource/action, and overlapping pairs (out_of_stock vs below_min_stock, remove_from_shopping_list vs check_off_shopping_item, correct_stock vs edit_stock_entry) are explicitly cross-referenced so an agent can choose correctly. The stock and shopping-list surfaces are dense, but the descriptions make boundaries unambiguous.
Most tools follow a readable verb_noun style (list_stock, add_stock, create_product, clear_shopping_list) with consistent snake_case. A few status queries are named as noun/adjective phrases rather than verbs (out_of_stock, below_min_stock, expiring_soon, product_details, stock_history), which is a minor deviation from the dominant pattern.
27 tools is on the heavy side and pushes past the comfortable 15-25 range, which can be a lot for an agent to navigate. The breadth is largely justified by Grocy's domain—catalog, stock batches, barcodes, and shopping list—but the set could have been tightened by merging some stock mutations or status queries.
The surface covers product CRUD, barcode management, stock lifecycle (add/consume/open/correct/transfer/edit/undo), stock queries, and shopping-list lifecycle with no dead ends. Two-step flows like create_product then add_stock, or check_off then add_stock, are explicitly documented.