pp-instacart
Original:🇺🇸 English
Translated
Printing Press CLI for Instacart. Natural-language Instacart CLI that talks directly to the web GraphQL API. Add items to your cart, search products, and manage carts across retailers without browser automation. Also caches your purchase history locally so 'add' resolves items you have bought before instead of guessing from live search. Trigger phrases: 'install instacart', 'use instacart', 'run instacart', 'add X to my Safeway cart', 'what did I buy last time', 'order the usual', 'add my regulars to Costco', 'backfill my instacart history', 'sync my instacart orders', 'download my order history', 'save my instacart history locally'.
4installs
Added on
NPX Install
npx skill4agent add mvanhorn/printing-press-library pp-instacartTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Instacart - Printing Press CLI
Prerequisites: Install the CLI
This skill drives the binary. You must verify the CLI is installed before invoking any command from this skill. If it is missing, install it first:
instacart-pp-cli- Install via the Printing Press installer:
bash
npx -y @mvanhorn/printing-press install instacart --cli-only - Verify:
instacart-pp-cli --version - Ensure (or
$GOPATH/bin) is on$HOME/go/bin.$PATH
If the install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.23+):
npxbash
go install github.com/mvanhorn/printing-press-library/library/commerce/instacart/cmd/instacart-pp-cli@latestIf reports "command not found" after install, the install step did not put the binary on . Do not proceed with skill commands until verification succeeds.
--version$PATHWhen to Use This CLI
Reach for this when a user wants:
- Add a product to an Instacart cart by natural language ("add lemon sorbet to QFC")
- Add something they have bought before ("add my usual milk to Safeway")
- Show, search, or compare their active carts across retailers
- List or search their own Instacart order history
- Run an Instacart flow from a script, cron job, or agent loop
Do not reach for this if the user wants to actually check out. This CLI adds items to your cart; you still complete checkout in the Instacart app or web UI.
Unique Capabilities
History-first add
addaddConfidence rules:
- FTS5 match in your local purchased_items at that retailer
- Purchased within the last 365 days
- Was in stock on the last purchase
Falls through to today's live-search behavior when any condition fails. Pass to force live search.
--no-historyEvery successful (history-resolved or live-resolved) writes back to so the signal gets warmer without a full re-sync.
addpurchased_itemsOne-command history backfill
Typing "backfill my instacart orders" (or similar, see Argument Parsing) kicks off a Chrome-MCP-driven flow that walks the user's logged-in Instacart tab, extracts their order history into JSONL, and imports it into the local DB. After backfill, resolves from real purchase history instead of live-search guesses.
addPrimary path: Chrome MCP. Fallback: paste three JS files into DevTools by hand.
Full walkthrough below under "Backfill Flow". Reference docs with more detail:
- — Chrome MCP flow
docs/backfill-walkthrough.md - — manual DevTools flow
docs/backfill-devtools-fallback.md
history listhistory searchhistory statsInstacart does not expose a clean order-history GraphQL op, so the legacy command cannot work. See for why.
history syncdocs/solutions/best-practices/instacart-orders-no-clean-graphql-op.mdNatural-language add
addResolves a product from free-text via Instacart's own three-call GraphQL chain (ShopCollectionScoped -> Autosuggestions -> Items) and fires . No browser automation.
UpdateCartItemsMutationWhen Instacart rejects a candidate with (autosuggest occasionally surfaces a product that is not addable at your active cart's shop), automatically retries up to 3 ranked candidates before giving up. In output a successful retry sets and includes an array listing the rejected item ids. When history-first resolution hits the same error, falls through to live search and reports .
notFoundBasketProductadd--jsonretry_count > 0attemptsaddresolved_via: "history->live"Multi-retailer carts
cartscarts listCommand Reference
Authentication:
- - extract session cookies from Chrome
instacart auth login - - show current session state
instacart auth status - - clear saved cookies
instacart auth logout - - paste cookie JSON manually (fallback for newer macOS Chrome)
instacart auth paste - - load cookies from a browser-use export JSON
instacart auth import-file <path>
Cart operations:
- - add a product by natural language
instacart add <retailer> <query...> - - skip the history-first resolver
instacart add <retailer> <query...> --no-history - - add by exact Instacart item id
instacart add --item-id <id> <retailer> - - show current cart contents at a retailer
instacart cart show <retailer> - - remove an item from a cart
instacart cart remove <item-id> <retailer> - - list every active cart across retailers
instacart carts list
Discovery:
- - search products at a retailer
instacart search <query> --store <retailer> - - list retailers available at your address
instacart retailers list - - cache one retailer locally
instacart retailers show <slug>
Purchase history:
- - load a JSONL order dump into the local DB (the working path)
instacart history import <path> - - read from stdin, JSON output for agent pipelines
instacart history import - --json - - preview counts without writing
instacart history import <path> --dry-run - - top purchased items by count + recency
instacart history list - - filter + paginate
instacart history list --store <retailer> --limit 20 - - FTS search your purchase history
instacart history search <query> - - scoped FTS search
instacart history search <query> --store <retailer> - - counts + per-retailer state
instacart history stats
Maintenance:
- - health check: config, store, ops, history, session, live ping
instacart doctor - - refresh the GraphQL operation hash cache
instacart capture - - merge fresh hashes from the community registry
instacart capture --remote - - show the operation-hash cache state
instacart ops list
Recipes
First-time setup
bash
instacart auth login # extract cookies from Chrome
instacart doctor # verify auth + live ping
instacart capture # seed built-in op hashesThen backfill history (optional but recommended; unlocks history-first ):
addTell the agent: "backfill my instacart orders"
The skill drives the rest. See the "Backfill Flow" section below.
Add something you buy all the time
bash
instacart add safeway "oat milk" # resolves via local history if you have bought it beforeLook for in the output. If you see , the FTS match did not pass the confidence check; check to see what is actually in your history.
via historyvia liveinstacart history search "oat milk" --store safewayForce a fresh live search
bash
instacart add safeway "oat milk" --no-history --dry-run --json--dry-run --jsonresolved_viaDaily top-up from recent history
bash
instacart history list --store safeway --limit 20 --json | jq -r '.[].name' \
| while read item; do instacart add safeway "$item" --yes --json; doneAuth Setup
Requires a logged-in Instacart session in Chrome. The CLI extracts cookies via kooky (no credential handling on our side). If Chrome is locked or you are on a system kooky cannot read:
bash
instacart auth paste # paste the full cookie JSON manually
instacart auth import-file <path>Session lives at (0600).
~/.config/instacart/session.jsonAgent Mode
The CLI is agent-native by default. Pass on any command for machine-readable output. previews without firing the mutation and surfaces which resolver (, , or ) would have fired.
--json--dry-runaddhistoryliveitem-idadd- : one of
resolved_via,history,live(history pick was rejected, live retry succeeded), orhistory->live.item-id - : how many candidates were rejected before the winner.
retry_countwhen the first pick landed.0 - : present only when
attempts, array ofretry_count > 0for each rejected candidate.{item_id, name, error_type} - On exhaustion (exit 5): JSON envelope with ,
error,retailer,query, and aattemptsnaming the concrete next step (hintthensearch, or retry withadd --item-id).--no-history
Filtering output
--selectbash
instacart-pp-cli <command> --agent --select id,name
instacart-pp-cli <command> --agent --select items.id,items.owner.nameUse this to narrow huge payloads to the fields you actually need — critical for deeply nested API responses.
Response envelope
Data-layer commands wrap output in . Parse for data and to know whether it's or local. The summary is printed to stderr only when stdout is a TTY; piped/agent consumers see pure JSON on stdout.
{"meta": {...}, "results": <data>}.results.meta.sourceliveN results (live)Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 2 | Usage error |
| 3 | Auth missing or rejected |
| 4 | Resource not found |
| 5 | API error / conflict |
| 7 | Rate limited or transient network |
Argument Parsing
Given a free-form natural-language request:
- Empty, , or
help-> run--helpinstacart --help - Starts with -> CLI install; ends with
install-> MCP installmcp - Matches a backfill intent -> run the Backfill Flow below. Trigger phrases include: "backfill my orders", "backfill my history", "sync my instacart history", "sync my instacart orders", "download my order history", "save my instacart history locally", "pull in my past orders", "import my recent orders".
- Anything else -> map to the best subcommand and run with when invoked from an agent
--json
Backfill Flow
Drive this when the user hits a backfill intent. Read via WebFetch for the full procedure; summary below.
docs/backfill-walkthrough.mdSetup check:
- Confirm is on PATH. If not, install:
instacart-pp-cli.go install github.com/mvanhorn/printing-press-library/library/commerce/instacart/cmd/instacart-pp-cli@latest - Probe . If the tool is unavailable, route to the DevTools fallback: fetch
mcp__claude-in-chrome__tabs_context_mcpand walk the user through it. Stop.docs/backfill-devtools-fallback.md - Run . If orders > 0, this is a top-up run; the resume state will skip already-dumped orders automatically.
instacart-pp-cli history stats --agent
Chrome MCP loop:
- WebFetch the three JS files (cache each in the current session):
https://raw.githubusercontent.com/mvanhorn/printing-press-library/main/library/commerce/instacart/docs/dumper.jshttps://raw.githubusercontent.com/mvanhorn/printing-press-library/main/library/commerce/instacart/docs/extract-one.jshttps://raw.githubusercontent.com/mvanhorn/printing-press-library/main/library/commerce/instacart/docs/export-jsonl.js
- Open or reuse a tab at . If the dumper returns
https://www.instacart.com/store/account/orders, ask the user to pick a profile in the tab, then re-run.profile_picker: true - Inject via
dumper.js. Read backmcp__claude-in-chrome__javascript_toolandtotal_ids.pending_extract - For each order ID in the pending set, navigate to then inject
/store/orders/<id>. Report progress to the user every 10 orders.extract-one.js - When pending reaches 0, inject . It downloads
export-jsonl.jsto the user's default Downloads folder.instacart-orders.jsonl - Run in a Bash tool. Show the summary JSON to the user.
instacart-pp-cli history import ~/Downloads/instacart-orders.jsonl --agent - Verify: . Offer a follow-up sanity check:
instacart-pp-cli history stats --agentand flaginstacart-pp-cli add <retailer> "<something they've bought>" --dry-run --jsonwhen it appears.resolved_via: "history"
Error surfaces worth translating for the user:
- Extractor on every order -> Instacart rotated their web bundle. Report the observed cache keys and point at the rotation-recovery section of the walkthrough doc.
cache_key_missing - Dumper reports fewer IDs than the user expected -> probably on a multi-profile account; ensure the selected profile is the one with purchase history.
- shows 0 orders imported -> the JSONL is empty (only skip records). Re-run the extractor loop with fresh tabs.
history import
Direct Use
- Check installed:
which instacart-pp-cli - Check auth:
instacart doctor - Capture GraphQL hashes:
instacart capture - (Optional but recommended) Backfill history — run the Backfill Flow above. Unlocks history-first resolution.
add - Run your command with if invoked from an agent
--json