Peristyle Grocery Cart
Recipes into a grocery cart
- Category
- Commerce
- Primary Subcategory
- Shopping Assistants & Price Comparison
Integration details
Description
Peristyle turns a recipe into a ready-to-checkout grocery cart. Search a recipe, and it pulls the ingredient list, matches each item to real products at Kroger or Walmart, and shows you the options — with size, price, and brand — before anything is added to a cart. Connect your Kroger account once to shop directly through the assistant, or use Walmart's catalog with no sign-in at all. Peristyle remembers your default store, pickup or delivery preference, dietary needs, and preferred brands, so repeat shopping gets faster over time. You always see and approve product matches before they're added — Peristyle fills the cart but never places the order or handles payment. Checkout happens on Kroger's or Walmart's own site.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Shopping Assistants & Price Comparison
- Secondary Subcategories
- None listed
- Brand
- Peristyle
- Access
- Account required
- First tracked
- 2026-08-20
- Tool count
- 26
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT Shopping Assistants & Price Comparison
View Category26 tools agents can invoke
Add confirmed items to the user's Kroger cart (requires a connected account). `items` is a list of {"upc": "0001111041700", "quantity": 1}. Use the UPCs the user confirmed from match_recipe_to_kroger. Always include "price" per item (the store price you showed the user — promo price if on sale); it powers order-value analytics. If the user has pantry enabled, also include "description" (product name) and "ingredient_name" per item — the purchase confirmation and resulting pantry entries are built from them. `modality` is PICKUP or DELIVERY (defaults to the user's saved preference, then PICKUP). Pass `recipe_id` so the order is attributed to its source recipe and added to local history. The cart is filled but NOT checked out — the user completes checkout in Kroger. This is ADD-ONLY: the Kroger API cannot remove items, change quantities, or clip coupons. If the user wants something removed or resized, tell them to do it in the Kroger app/site — never promise a rebuild or removal you can't do. If the response includes pantry_confirmation_id, keep the id internal (never show it) and tell the user to come back after checkout to confirm the purchase (then call confirm_purchase) so their pantry stays current.
kroger_add_to_cart
Build a Walmart Add-to-Cart link from confirmed items. `items` is a list of {"product_id": "12345", "quantity": 1}. Use the product_ids the user confirmed from match_recipe_to_walmart. Always include "price" per item (the price you showed the user); it powers order-value analytics. store_id sets pickup context on the link; if omitted, falls back to the saved default_walmart_store_id, else the nearest store to the saved default_zip (resolved and cached automatically — no need to ask the user again once set). Returns a checkout_url the user opens in a browser while signed in to Walmart — the API does not place the order or take payment.
walmart_add_to_cart
Check whether the user's Kroger account is connected and ready to shop. You rarely need this: shop_recipe picks the store itself (Kroger when this account has a Kroger link, otherwise Walmart). Call it when the user asks for Kroger by name or about their Kroger connection. Trust the `active` field: when it's true the account is connected and usable right now — do NOT call connect_kroger(). A short-lived access token that lapsed between sessions is refreshed automatically, so a past connection stays valid; only reconnect when `needs_reauth` is true. A 401 here means this client has no API key yet — NOT that a Kroger session expired. If a connect is mid-flight (the user just signed in), the fix is to call finish_kroger_connection() to pull the key, not to reconnect — and if you still have the link_token connect_kroger() returned earlier in this conversation, pass it to finish_kroger_connection(link_token=...) even if this tool reports "No Kroger account connected": that message only reflects what the server session currently remembers, which can lag what you know.
kroger_auth_status
Close the loop on a cart after the user checked out in the store's app. Pass the confirmation_id from get_pantry's pending_confirmations (or the pantry_confirmation_id a cart-add returned). One light question — "did your order go through?" — has three answers: * **yes** — `purchased=True`. The order went through as built. * **no** — `purchased=False`. The cart was never bought. * **modified** — `purchased=True, modified=True`. It went through but was changed outside the chat: swaps, drops, store substitutions. Use this the moment they say something changed, without interrogating them for the list; nothing is stocked from the cart, because a cart known not to match the order is a set of guesses. When they do name the lines that didn't make it, pass those in `removed_refs` and the rest stocks as usual. A receipt settles everything at once: read the one they paste in chat (nothing is uploaded), pass `removed_refs` for carted lines it doesn't show, and put substitutions or extras it does show into update_pantry as "have". Pass its printed basket total as `receipt_total` — the only money figure in the system that isn't an estimate of a cart that may never have been bought. Only ever a number printed on a receipt: not a sum you compute, not the cart's own prices, and never a guess. Omit it if the total isn't legible. For a pantry user the purchased items land as fresh "have" (the response's `stocked` says which); without a pantry the answer is simply recorded — `stocked` comes back empty and nothing about their kitchen is stored. Confirmations are housekeeping: building or adding a new cart works the same whether or not any are pending, so this call can come after the cart task.
confirm_purchase
Start connecting the user's Kroger account. Returns a login URL and a link_token. Ask the user to open the URL in a browser, sign in to Kroger, and approve access. Then call finish_kroger_connection(link_token=...) with the link_token from this response — the user does not copy, paste, or read anything back; the connection is delivered over this tool's own channel. Passing link_token back explicitly (rather than relying on it being remembered here) is what makes the handshake survive the user's round trip through the browser, even if this client's connection to the server is re-established in between.
connect_kroger
Permanently delete the user's Peristyle account and all data stored with it: store connections, saved preferences, the opt-in pantry and product feedback, purchase confirmations, and the API keys this assistant uses. This cannot be undone. Only call it after the user has explicitly asked to delete their account and repeated the confirmation phrase. Usage analytics are kept only in aggregate, no longer linked to the account. To stop shopping without deleting anything, use disconnect_kroger instead.
delete_account
Turn the opt-in pantry off and delete everything it stored: kitchen inventory, product likes/dislikes, and the itemized cart records held as purchase confirmations. Works whether or not the pantry was ever on — those cart records are kept for every signed-in shopper, so this is the erasure control for them too. Confirm with the user first — there is no undo. Preferences and the store connection are untouched. Matching goes back to using only saved preferences. The user can enable_pantry again later, starting empty.
disable_pantry
Remove the user's Kroger connection from Peristyle: the stored OAuth tokens and the link between their Kroger login and this account. Confirm with the user before calling — after this, product matching and cart adds need connect_kroger() again. Recipes, preferences, and pantry are untouched. Kroger keeps its own record of the grant; tell the user they can remove Peristyle under connected apps in their Kroger account settings.
disconnect_kroger
Turn on the user's pantry — server-side kitchen inventory that makes every future cart smarter. Opt-in only: ask the user first and explain that their kitchen inventory and product likes/dislikes will be stored with their Peristyle account, and that answering "did your order go through?" will stock what they bought (recipes viewed and preferences stay local). Don't describe the cart records themselves as something this turns on: those are kept for every signed-in shopper either way, and turning the pantry off erases them. Requires a connected account. Idempotent — safe to call if already enabled.
enable_pantry
Find Kroger-family stores near a ZIP code so the user can pick one. No Kroger sign-in required. Returns stores with location_id, name/chain, and address. Show the user the nearby options and save their choice with set_preference("default_location_id", <location_id>) — matching and product search then use it automatically. The ZIP is saved as default_zip automatically, so store resolution works even before the user picks. Optional chain filters by banner (e.g. "KROGER", "HARRIS TEETER").
find_kroger_stores
Finish connecting Kroger after the user has signed in via connect_kroger(). Pass the link_token connect_kroger() returned — always do this if you still have it in context; it's what lets this call find the connection even if the server-side session doesn't remember starting it. Polls until the user completes Kroger sign-in (up to ~2 minutes), then saves the session. Running locally (stdio) it's written to the device; on a remote server the Kroger account attaches to the user's signed-in Peristyle account (the connector's own OAuth bearer) — the key is never shown. If it returns "waiting", give the user a moment to finish and call this again.
finish_kroger_connection
The user's kitchen picture: pantry items with honest status ("have", "probably_out" once past shelf life, or "out"), product loves/hates, and any purchase confirmation worth asking about from an earlier cart. Without a pantry it answers `enabled: false` and still carries that confirmation — the question reaches every signed-in shopper. Do not call this before matching: every match result (shop_recipe, match_*) already folds in the pantry snapshot as `pantry`. Use it only when the user asks about their pantry directly, or to resolve a pending confirmation outside a cart flow. Returns {"enabled": false} if the user hasn't opted in — offer enable_pantry once, don't nag. Use it to: (1) skip ingredients the user already has (confirm before skipping anything marked probably_out); (2) bias product picks toward loves and away from hates; (3) resolve pending confirmations — a "did that order go through?" aside answered via confirm_purchase, which fits alongside or after the current cart task and never gates it.
get_pantry
Return one recipe including steps and ingredient lines.
get_recipe
Look up ONE product directly by its UPC or a kroger.com product URL. The authoritative check when keyword search can't find something: if the user pastes a kroger.com link or product number ("I see it right here"), call this instead of re-searching or telling them it doesn't exist. Returns the product with store price, `on_sale`, and `stock` (pass/omit location_id same as search). A 404 here — not an empty keyword search — is what "Kroger doesn't have it" actually looks like.
kroger_get_product
Propose Kroger products for a freeform shopping list — no recipe needed. THE main path for a pasted grocery list or a week's meal plan: pass the whole list as plain phrases, one per item, exactly as written ("fage 2% greek yogurt 32 oz", "limes 2", "black beans 2 cans", "bubly 8 pack x3"). Any length — long lists are matched in batches of 50 and returned as one result. Every line comes back with a suggested product plus alternatives, and with `quantity` (packages to add, parsed from the line's "x3" / "2 cans" / trailing count) and `size` (the pack size of one, e.g. "12 oz") — pass `quantity` through to kroger_add_to_cart and check the pick's size against `size`. Nothing is added to the cart; show the user the picks and pass confirmed UPCs to kroger_add_to_cart. Items where `matched` is false or `stock` is "Not available" need a swap — try kroger_search_products with different words, or ask the user. Omit location_id to use the saved default store.
match_items_to_kroger
Propose Walmart products for a freeform shopping list — no recipe needed. THE main path for a pasted grocery list or a week's meal plan: pass the whole list as plain phrases, one per item, exactly as written ("fage 2% greek yogurt 32 oz", "limes 2", "black beans 2 cans", "frozen corn 12 oz x2"). Any length — long lists are matched in batches of 50 and returned as one result. Every line comes back with a suggested product plus alternatives, and with `quantity` (packages to add, parsed from the line's "x2" / "2 cans" / trailing count) and `size` (the pack size of one, e.g. "12 oz") — pass `quantity` through to walmart_add_to_cart and check the pick's size against `size`. Nothing is added to the cart; show the user the picks and pass confirmed product_ids to walmart_add_to_cart. Items where `matched` is false need a swap — try walmart_search_products with different words, or ask the user. Picks carrying `cart_link_warning` may be silently dropped by the Add-to-Cart link — flag them and prefer a warning-free alternative. No Walmart sign-in is required.
match_items_to_walmart
Propose Kroger products for each ingredient of a recipe at a store. Nothing is added to the cart. Returns suggested products (name, size, price, upc, stock) plus alternatives per ingredient so the user can confirm before adding — treat `stock: "Not available"` candidates as not carried at this store and pick an alternative. Ingredients listed in `unmatched` just need a follow-up search (kroger_search_products or match_items_to_kroger with different wording) — they never mean the connector can't search or add to cart. Omit location_id to use the user's saved default store (set via set_preference). If no default_location_id is saved but default_zip is, the nearest Kroger is resolved automatically and saved for future calls.
match_recipe_to_kroger
Propose Walmart products for each ingredient of a recipe. Nothing is added to the cart. Returns suggested products (name, size, price, product_id) plus alternatives per ingredient so the user can confirm before adding. No Walmart sign-in is required. Each product also carries `stock` ("Available"/"Not available"), `available_online`, and `offer_type` ("ONLINE_ONLY"/"ONLINE_AND_STORE"/ "STORE_ONLY") — catalog-level signals from Walmart, not live inventory at any one store (the affiliate API has no per-store stock lookup). The `suggested` pick already skips "Not available" candidates when a better one exists. If the user wants pickup, flag any `offer_type: ONLINE_ONLY` item before adding it — it won't be on a physical shelf. Products may carry `cart_link_warning`: Walmart's Add-to-Cart link silently drops items it can't sell online (STORE_ONLY offers, random-weight fresh meat/produce). The `suggested` pick already prefers warning-free candidates; if a warned item is the only match, tell the user up front it may not survive the cart link and offer a fixed-size ONLINE_AND_STORE alternative or a manual add in the Walmart app.
match_recipe_to_walmart
Remember that the user loves or hates a product or ingredient, so future matches get better without re-asking. sentiment: "love" or "hate". kind: "product" (a specific store item — pass ref=UPC/product_id and store="kroger"/"walmart") or "ingredient" (e.g. hates cilantro — ref defaults to the label). Capture these opportunistically: when the user swaps a suggested product ("not that brand"), rejects an ingredient, or praises something after cooking. One row per subject — restating updates it, so it's safe to record a changed mind. Requires pantry to be enabled.
record_product_feedback
Present the FINAL shopping list — the last step before add-to-cart. Call this once per cart, AFTER the triage conversation is done: pantry check relayed, staples skipped, swaps settled. Pass only what will actually be bought. Every item is re-checked against the store for current price and stock, so the total the user sees equals the cart they'll get. Nothing is added to the cart by this tool. On hosts that support it the result MAY render as an interactive final list with an add-to-cart button, but rendering can fail silently and the server cannot tell. Never tell the user a list or card is displayed. Relay the returned list compactly in text (product, size, price, quantity) unless the user confirms they can see the interactive list.
review_shopping_list
Search the Kroger catalog by keyword for a specific product — independent of any recipe. Use this for freeform lookups the recipe matcher can't do: a particular brand, a specific size (include it in the query, e.g. "olive oil 1 liter" or "olive oil 50.7 oz"), pantry staples, garnishes, or anything the user wants to add directly. Keep `query` to 8 words or fewer — Kroger rejects longer search terms, so anything past the 8th word is dropped before the search (the result then carries `query_truncated: true` and the `query_searched` actually used). Prefer a short product phrase plus size over a sentence. Write a size the way the catalog writes it — a pack count is "12 count" or "12 ct", never a word like "dozen": "eggs 12 count" returns five cartons where "large eggs dozen" returns nothing at all (live 2026-09-10). When a sized query comes back empty, drop the size and search the product alone before telling the user anything is unavailable. When the user wants a specific brand, pass `brand` (e.g. "Fage") with a generic query — that surfaces the brand's full size range instead of burying it under other products. Raise `limit` (up to 50) to see more sizes/pack options. If a specific product still doesn't show up but the user can see it on kroger.com, use kroger_get_product with the UPC or URL — never conclude the store doesn't carry it from keyword search alone. To find SALES, search the product category ("ribeye steak" — never words like "steak sale", which just keyword-match product names) and check each result's `on_sale` flag / compare `price_promo` to `price_regular`. Skip products whose `stock` is "Not available" — that store doesn't carry them right now. Returns products with description, brand, size, price, `on_sale`, `stock`, and `upc`; pass the chosen UPCs straight to kroger_add_to_cart (after the user confirms). Requires a connected Kroger account. Omit location_id to use the saved default store (auto-resolved from default_zip when needed), since prices, sizes, and availability vary by store.
kroger_search_products
Search the Walmart.com catalog by keyword, or look up one exact item. If the user shares a walmart.com product link (any URL containing `/ip/.../<itemId>`) or a bare numeric Walmart item id, pass it as `query` verbatim: the tool resolves that exact listing instead of keyword-searching, so the product_id you add is the one the user picked. Use for freeform lookups: a particular brand, size, pantry staples, or anything the user wants to add directly. Returns products with description, brand, size, price, product_id, and availability signals (`stock`, `offer_type`, `available_online`); pass chosen ids to walmart_add_to_cart after the user confirms. Prefer results WITHOUT `cart_link_warning` — the Add-to-Cart link silently drops store-only and random-weight items. No Walmart sign-in is required.
walmart_search_products
Find recipes by dish, ingredient, creator — or by URL. `query` may be a recipe page's address (https://...): the recipe is resolved directly, indexed first if we've never seen it. Otherwise it's a ranked full-text search over title, description, creator and ingredient lines, with fuzzy fallbacks. Check `match_kind`: `exact`/`url` hits are the answer; `ingredient` hits are fuzzy candidates found via ingredient names because nothing matched directly — confirm with the user before shopping one. When a URL yields nothing, `url_error` says why (the site blocked the fetch, the address 404s, the page has no recipe data, sign-in needed) — pass that reason on to the user rather than "nothing found".
search_recipes
Save a user preference with the connected account, so it persists across sessions and devices. Common keys: `dietary`, `default_location_id` (Kroger), `default_walmart_store_id`, `default_modality` (PICKUP/DELIVERY), `preferred_brands`, `default_zip` (ZIP code used to auto-resolve the nearest store for whichever of Kroger/Walmart doesn't have a saved store id yet — shared between both). Pass an empty value to clear a preference.
set_preference
FASTEST path from a dish idea to a reviewable cart: one call that finds the recipe AND proposes Kroger products for every ingredient at the user's store. Prefer this over separate search_recipes → get_recipe → match_recipe_to_kroger calls whenever the goal is a grocery cart. Pass a recipe URL when the user has one — most people arrive from a blog post — and it is looked up (indexed first, if new) instead of searched. Nothing is added to the cart. Returns the recipe (title + ingredients; call get_recipe for cooking steps), the matched products with alternatives, the user's folded-in preferences/pantry, and up to two other recipe candidates in case the top hit isn't what the user meant. Show the user the picks, then call the store's add-to-cart tool once with every confirmed item. Store choice is automatic: a signed-in account with a linked Kroger gets Kroger picks (`match`, then kroger_add_to_cart). An account with NO Kroger link — e.g. someone who signed in with the email magic link — gets Walmart picks instead (`walmart_match`, then walmart_add_to_cart; no store sign-in needed), so never answer "connect Kroger first" unless the user asks for Kroger by name. Pass location_id to force Kroger at that store. Omit it to use the saved default store.
shop_recipe
Update the user's pantry with one-tap effort — no quantities, ever. `items` is a list of {"name": "whole milk", "state": "have"|"out"|"remove", "staple": true|false (optional)}. Marking "have" restarts the item's freshness clock (shelf life is inferred from the name — milk decays in days, flour in months). Use "staple": true for things the user always keeps on hand. Use this whenever the user mentions their kitchen in passing ("we're out of eggs", "I picked up basil at the farmers market") — low-friction capture is what keeps the pantry alive. Requires pantry to be enabled.
update_pantry
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Peristyle Grocery Cart alternatives on ChatGPT?
As of 2026-09-13, Peristyle Grocery Cart competes with 3byggetilbud.dk, AllDiscGolf, Axiom, Bikefuchs, Boostermage, Breeze, BuyWise, Channel3 Shopping, CHECK24, Cimri, Data Market, Dupe, Eventbrite, Fragella: Discover Your Scent, Gathrd, Hyperassur, idealo, Klarna Shopping Search, Korea Concierge, KwikStore, MAKE#, Nash Agent, Ouest-France Shopping, PandaFind, PC Toplama Aracı, Penny, Petco, Polypo, Pricey- monitor+history+alerts, Product Link Expander, Rakhys, Sangria, SaveHealth, Seel, Share-A-Cart, Shop, Shoppable, Shopperoo, Spaartje, Spee24 Shopping, stierproducts, storabble, Swiftli, Tixel, Tonita, Wallector, Wallet Whistle, WebAZ Shopping, Zen Shopping, 전자랜드 in ChatGPT Shopping Assistants & Price Comparison, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.