agentsclimarketplace

Meal receipt

Skill scurry/meals-agent/.claude/skills/meal-receipt

Claude or other agent skills to help plan, make, and shop for meals

Install
npx -y skills add scurry/meals-agent --skill meal-receipt

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when processing grocery receipt images for the Meal OS system. Triggered by "/meal-receipt" or "process receipts" or "scan receipts".

SKILL.md

6.6 KB, ~1.8k tokens by cl100k_base, as published. Nobody here has run it

/meal-receipt — Receipt OCR & Price Tracker

Process grocery receipt images to build a price history ledger for cost estimates and loss leader detection.

Announce at start: "Processing grocery receipts..."

Step 1: Get Receipt Images

The user provides receipt images in one of two ways:

Option A: Folder Scan

Scan data/receipts/images/ for image files (.jpg, .jpeg, .png). Ignore files in the processed/ subfolder.

Group images into receipts by set ID — everything before the last -N in the filename:

  • mb-1.jpg, mb-2.jpg, mb-3.jpg → set "mb" (one receipt, 3 pages)
  • hannafords-1.jpg → set "hannafords" (one receipt, 1 page)
  • mb2-1.jpg, mb2-2.jpg → set "mb2" (second receipt, 2 pages)

The -N suffix determines page order within a set.

Option B: Chat

If the user provides image paths directly (e.g., /meal-receipt @mb-1.jpg @mb-2.jpg):

  • If multiple images, ask: "Are these all from the same receipt?"
  • If yes, treat as one set ordered by the filenames
  • If no, ask the user to clarify grouping

If no images are found or provided, say: "No receipt images found. Drop photos in data/receipts/images/ (e.g., mb-1.jpg, mb-2.jpg) or pass them directly: /meal-receipt @receipt.jpg"

Step 2: Load References

Read these files in parallel:

  • data/canonical-ingredients.yaml — for matching items to canonical IDs
  • data/receipts/aliases.yaml — for learned abbreviation mappings (if file exists)

If canonical-ingredients.yaml does not exist: Stop and tell the user: "data/canonical-ingredients.yaml is missing. Run /meal-setup first to initialize the project, then re-run /meal-receipt."

Step 3: OCR Receipt Images

For each receipt set, read the images in page order using the Read tool (Claude vision).

Extract from each receipt:

  • Store name — from the receipt header
  • Date — from the receipt header (fall back to file modification date if unreadable)
  • Line items — each with:
    • Item description (as printed)
    • Quantity (if weight-based, e.g., "2.13 lb")
    • Unit price (e.g., "$2.99/lb")
    • Total price

Lines to skip:

  • Tax lines, subtotals, totals, tender/payment, change
  • Savings summary lines, coupon lines, rewards/loyalty lines
  • Store header/footer info (address, phone, etc.)

Price normalization:

  • Weight-based: "2.13 lb @ $2.99/lb = $6.37" → extract per-unit price $2.99/lb
  • Multi-for: "2 @ 2/$5" → $2.50/each
  • Per-item: "$3.99" → $3.99/each

If store or date cannot be determined from the receipt, ask the user.

Step 4: Match Items to Canonical Ingredients

For each extracted line item, attempt to match to a canonical ingredient ID using this priority:

  1. Exact alias match — check data/receipts/aliases.yaml for the item description
  2. Fuzzy match against canonical-ingredients.yaml — compare to display names
  3. Common abbreviation patterns — apply known grocery shorthand:
    • CKN/CHKN = chicken, BRST = breast, THGH = thigh
    • EVOO = olive oil, EV OLV OIL = olive oil
    • GRK = greek, YOG = yogurt
    • ORG = organic (modifier, match base item)
    • FRSH = fresh (modifier, match base item)
    • GRND = ground
    • BKLS/BNLS = boneless, SKNLS = skinless
  4. No match — mark as ?

Step 5: Preview and Confirm

Show the full mapping before saving anything:

Receipt: [Store Name] — [YYYY-MM-DD] ([N] images)

  Matched items:
  1. [RECEIPT TEXT]    $[price]  →  [canonical_id] ($[unit_price]/[unit])
  2. [RECEIPT TEXT]    $[price]  →  [canonical_id] ($[unit_price]/[unit])
  ...

  Unmatched:
  N. [RECEIPT TEXT]    $[price]  →  ? ([suggestion or "non-food, skip"])
  ...

Confirm? (yes / fix [#] [canonical_id] / skip [#])

User corrections:

  • yes — save all matched items to the price ledger
  • fix 6 pasta — changes item 6's mapping to pasta; saves the abbreviation → canonical_id pair to data/receipts/aliases.yaml
  • skip 5 — marks item as non-food or irrelevant, excluded from ledger
  • Allow multiple corrections before final yes
  • After corrections, re-show the updated mapping for final confirmation

Step 6: Update Price Ledger

Write confirmed items to data/receipts/price-history.yaml.

Note: data/receipts/price-history.yaml is gitignored. See samples/receipts/price-history.yaml for a sanitized example.

Ledger format:

chicken_breast:
  - date: 2026-03-22
    store: Market Basket
    price: 2.99
    unit: /lb
    receipt: mb
  - date: 2026-03-15
    store: Hannaford's
    price: 4.49
    unit: /lb
    receipt: hannafords
olive_oil:
  - date: 2026-03-22
    store: Market Basket
    price: 9.99
    unit: /25 oz
    receipt: mb

Rules:

  • Append-only — never overwrite or remove previous entries
  • Organize by canonical ID (or human-readable name for non-canonical items)
  • Entries sorted by date descending within each ID
  • If the file doesn't exist yet, create it
  • If the file exists, read it first and append new entries

Step 7: Update Aliases

Write any new alias mappings (from user corrections or high-confidence matches) to data/receipts/aliases.yaml.

Aliases format:

# Learned receipt abbreviation → canonical ingredient ID
# Added automatically when user corrects a fuzzy match
'MB CKNBRST': chicken_breast
'PERDUE CKNBRST': chicken_breast
'MB GRAPE TOMATO': cherry_tomato
'EVOO 25OZ': olive_oil
'CHOBANI GREEK YOG': greek_yogurt

Rules:

  • Always single-quote alias keys — receipt text is unpredictable and may contain #, :, %, or other YAML-special characters
  • If the file doesn't exist yet, create it with a header comment
  • If the file exists, read it first and append new entries
  • Never overwrite existing aliases (if a conflict arises, keep the existing one and warn)
  • Only save aliases from user corrections (fix command) and high-confidence matches that the user confirmed

Step 8: Move Processed Images

After successful processing, move all images in the receipt set from data/receipts/images/ to data/receipts/images/processed/ to prevent re-processing while preserving originals.

Step 9: Confirm

Output a summary:

Receipt processed: [set ID] ([Store Name], [YYYY-MM-DD])

  Items matched: [N]
  Items skipped: [M] (non-food)
  New aliases learned: [K]
  Price ledger updated: data/receipts/price-history.yaml

  Notable prices vs. history:
  - [canonical_id]: $X.XX/unit (avg $Y.YY, ZZ% below/above average)
  - [canonical_id]: $X.XX/unit (first entry — no comparison yet)
  ...

If multiple receipt sets were processed, show a summary for each.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,970. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.