Supermarket

v1.1.0

Search grocery products, find store locations, add items to cart, and view profile across all Kroger-family stores — Kroger, Ralphs, Fred Meyer, Harris Teete...

0· 503·2 current·2 all-time
byRyan William Niemes@niemesrw

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for niemesrw/supermarket.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "Supermarket" (niemesrw/supermarket) from ClawHub.
Skill page: https://clawhub.ai/niemesrw/supermarket
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Canonical install target

openclaw skills install niemesrw/supermarket

ClawHub CLI

Package manager switcher

npx clawhub@latest install supermarket
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
The name/description (product search, locations, cart, profile) match the included code: a CLI and Firebase Cloud Functions that implement client_token and user_token flows, product/location endpoints, and cart/profile calls. No unrelated services or credentials are requested in the skill metadata.
Instruction Scope
SKILL.md instructs the agent to use a hosted OAuth proxy endpoints (authorize, tokenClient, tokenUser, tokenRefresh) and to generate session IDs and present a login link for the browser-based OAuth flow. These instructions stay within the stated purpose. The SKILL.md explicitly says the proxy holds client_id/client_secret and that tokens are deleted after retrieval; that behavior is implemented in the provided proxy source. A prompt-injection pattern (base64-block) was detected in SKILL.md — review that section in full to confirm it isn't trying to encode hidden instructions or data (scanner found a base64 block, which often is benign but worth eyeballing).
Install Mechanism
There is no install spec (instruction-only skill for runtime); source code is bundled but nothing in the skill will automatically download or execute external binaries. The presence of Firebase function source and a Go CLI is consistent with the documented self-hosting option; no high-risk install URLs or archive extraction are present.
Credentials
The skill declares no required environment variables for agent runtime. The bundled proxy code expects server-side secrets (KROGER_CLIENT_ID and KROGER_CLIENT_SECRET) for the hosted Cloud Functions — this is appropriate for an OAuth proxy, but it means you must trust the operator of us-central1-krocli.cloudfunctions.net. The CLI optionally uses OPENCLAW_BOT_TOKEN / OPENCLAW_CHAT_ID (Telegram) or stores Telegram/credentials locally under ~/.config/krocli; that is proportional to the advertised telegram 'send login link' feature.
Persistence & Privilege
Skill is not force-included (always: false) and uses normal agent invocation. The CLI code writes user credentials/telegram config to ~/.config/krocli and the proxy writes temporary session documents to Firestore — these are reasonable for the feature set. The tokenUser function deletes the Firestore session after returning tokens, and sessions have a 5-minute TTL as described.
Scan Findings in Context
[base64-block] unexpected: A base64-block pattern was detected inside SKILL.md. The rest of the bundle appears coherent and open-source; the base64 signal may be a benign artifact (e.g., an example or truncated payload) but you should inspect SKILL.md's full content for any encoded instructions or hidden data before trusting the hosted proxy.
Assessment
This skill is internally consistent: the code implements the described Kroger client and a hosted OAuth proxy whose server-side secrets are kept off the agent. The main risk is trusting the hosted proxy at us-central1-krocli.cloudfunctions.net because it holds the Kroger client_id/secret and handles exchanging/refreshing user tokens. If you don't fully trust that remote service, either: (1) self-host the provided Firebase Cloud Functions (source is bundled) and deploy them to your own project so you control the secrets, or (2) use your own Kroger developer credentials via the CLI's local mode (instructions in README). Also review the SKILL.md fully (scanner flagged a base64 block) and double-check that the login link behavior suits you. Note that the CLI may store credentials and optional Telegram tokens under ~/.config/krocli — don't provide Telegram or other tokens unless you trust the destination.

Like a lobster shell, security has layers — review code before you run it.

fred-meyervk977ec360tpxnrgnv9k3x21agn81q6eqfrysvk977ec360tpxnrgnv9k3x21agn81q6eqgroceryvk977ec360tpxnrgnv9k3x21agn81q6eqharris-teetervk977ec360tpxnrgnv9k3x21agn81q6eqking-soopersvk977ec360tpxnrgnv9k3x21agn81q6eqkrogervk977ec360tpxnrgnv9k3x21agn81q6eqlatestvk977ec360tpxnrgnv9k3x21agn81q6eqralphsvk977ec360tpxnrgnv9k3x21agn81q6eq
503downloads
0stars
2versions
Updated 1mo ago
v1.1.0
MIT-0

Supermarket Skill

Search grocery products, find stores, add to cart, and view your profile across all Kroger-family stores (Kroger, Ralphs, Fred Meyer, Harris Teeter, King Soopers, Fry's, QFC, Mariano's, Pick 'n Save, and more) — all through the Kroger API via a hosted OAuth proxy. No API keys or developer accounts needed.

How This Works (Transparency)

This skill uses a hosted OAuth proxy at us-central1-krocli.cloudfunctions.net to handle Kroger API authentication. Here's what it does and doesn't do:

What the proxy handles:

  • Stores the Kroger client_id/client_secret (as Firebase secrets — never exposed to the agent)
  • Exchanges authorization codes for tokens during login
  • Refreshes expired user tokens

Privacy guarantees (verifiable in source):

  • User tokens are deleted from Firestore immediately after being returned to the agent (tokenUser.ts:44)
  • Login sessions expire after 5 minutes (callback.ts:10)
  • Firestore rules deny all direct client access — only server-side Cloud Functions can read/write
  • No tokens are logged — only errors use console.error
  • The proxy never sees your Kroger username or password (that goes directly to Kroger's OAuth page)

Full source code: The proxy is open source at firebase/functions/src/ in the krocli repository. You can audit every function: authorize.ts, callback.ts, tokenClient.ts, tokenUser.ts, tokenRefresh.ts.

If you don't trust the hosted proxy, see "Self-Hosting" at the bottom of this document.

Architecture

All API calls go through the hosted proxy which handles OAuth credentials. The agent never needs a client_id or client_secret.

Two token types:

  • Client token — for public data (products, locations). Obtained automatically.
  • User token — for personal data (cart, profile). Requires one-time browser login.

Getting a Client Token

Before searching products or locations, obtain a client token:

curl -s -X POST https://us-central1-krocli.cloudfunctions.net/tokenClient

Response:

{"access_token": "eyJ...", "expires_in": 1800, "token_type": "bearer"}

Cache the access_token for subsequent requests. It expires in 30 minutes.

Searching Products

curl -s -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Accept: application/json" \
  "https://api.kroger.com/v1/products?filter.term=milk&filter.limit=10"

Query parameters:

ParameterRequiredDescription
filter.termYesSearch term (e.g. "milk", "organic eggs")
filter.locationIdNoStore ID for local pricing/availability
filter.limitNoMax results (default 10, max 50)

Response fields to show the user:

  • data[].productId — UPC code
  • data[].description — Product name
  • data[].brand — Brand name
  • data[].items[].price.regular — Price (when locationId provided)
  • data[].items[].price.promo — Sale price (when available)
  • data[].items[].size — Package size

Finding Store Locations

curl -s -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Accept: application/json" \
  "https://api.kroger.com/v1/locations?filter.zipCode.near=45202&filter.limit=5"

Query parameters:

ParameterRequiredDescription
filter.zipCode.nearYesZIP code to search near
filter.radiusInMilesNoSearch radius (default 10)
filter.limitNoMax results (default 10)

Response fields to show the user:

  • data[].locationId — Store ID (use for product pricing)
  • data[].name — Store name
  • data[].address.addressLine1, city, state, zipCode
  • data[].phone — Phone number
  • data[].hours — Operating hours

User Authentication (for Cart & Profile)

When the user wants to add items to their cart or view their profile, they need to authenticate with Kroger. This is a one-time browser flow.

Step 1: Generate a session ID and send the login link

Generate a random hex session ID (16-32 characters) and present the login URL to the user as a clickable link:

https://us-central1-krocli.cloudfunctions.net/authorize?session_id=SESSION_ID

Tell the user: "Click this link to log in to your Kroger account. Once you see 'Login successful', come back here and let me know."

Step 2: Poll for tokens

After the user says they've logged in, poll for their tokens:

curl -s "https://us-central1-krocli.cloudfunctions.net/tokenUser?session_id=SESSION_ID"
  • If {"status": "pending"} with HTTP 202: user hasn't finished yet. Wait and retry.
  • If HTTP 200: tokens are returned. Cache access_token and refresh_token.
{
  "access_token": "eyJ...",
  "refresh_token": "abc...",
  "expires_in": 1800,
  "token_type": "bearer"
}

Step 3: Use the user token

The user token is needed for cart and profile endpoints.

Adding to Cart

Requires user token from authentication above.

curl -s -X PUT \
  -H "Authorization: Bearer USER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  "https://api.kroger.com/v1/cart/add" \
  -d '{"items": [{"upc": "0011110838049", "quantity": 1}]}'

Request body:

{
  "items": [
    {"upc": "PRODUCT_ID", "quantity": 1}
  ]
}

HTTP 204 means success (no response body).

Viewing Profile

Requires user token.

curl -s -H "Authorization: Bearer USER_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  "https://api.kroger.com/v1/identity/profile"

Refreshing an Expired User Token

If a user token returns 401, refresh it:

curl -s -X POST \
  -H "Content-Type: application/json" \
  "https://us-central1-krocli.cloudfunctions.net/tokenRefresh" \
  -d '{"refresh_token": "REFRESH_TOKEN"}'

Response includes new access_token and refresh_token. Cache both.

Token Management Summary

TokenHow to getExpiresRefresh
ClientPOST /tokenClient30 minJust request a new one
UserBrowser login flow30 minPOST /tokenRefresh with refresh_token

Error Handling

HTTP StatusMeaningAction
401Token expiredRefresh or re-obtain token
403ForbiddenToken lacks required scope
429Rate limitedWait and retry
400Bad requestCheck parameters

Typical Workflows

"Search for milk near me"

  1. Get client token via POST /tokenClient
  2. Ask user for ZIP code (or use a previously known one)
  3. Find nearest store via locations API
  4. Search products with filter.locationId for local pricing

"Add bananas to my Kroger cart"

  1. Check if user token is cached; if not, start login flow
  2. Search for "bananas" to get the UPC
  3. Confirm product with user
  4. PUT /cart/add with the UPC

"What Kroger stores are near 90210?"

  1. Get client token
  2. Search locations with filter.zipCode.near=90210
  3. Format results with name, address, hours

Token Persistence

After a successful user login, save the refresh token and preferred ZIP code to your long-term memory so the user doesn't have to log in again next session.

After login, remember:

  • kroger_refresh_token: the refresh_token from the login flow
  • kroger_zip_code: the user's preferred ZIP code (if provided)
  • kroger_store_id: the user's preferred store locationId (if identified)

At the start of a session, check your memory for a saved kroger_refresh_token. If found:

  1. Call POST /tokenRefresh with the saved refresh_token
  2. If it succeeds, use the new access_token — no login needed
  3. If it fails (e.g. token revoked), clear the saved token and start a fresh login flow

Important: Only save the refresh_token, never the access_token (it expires in 30 minutes and is useless to persist).

Self-Hosting the Proxy

If you prefer not to use the hosted proxy, you can run your own. The full source is in the krocli repo under firebase/.

Option 1: Deploy your own Firebase proxy

  1. Create a Kroger developer app at developer.kroger.com
    • Scopes: product.compact, cart.basic:write, profile.compact
    • Redirect URI: https://YOUR-PROJECT.cloudfunctions.net/callback
  2. Clone the repo and set up Firebase:
    git clone https://github.com/BLANXLAIT/krocli.git
    cd krocli/firebase
    firebase init
    firebase functions:secrets:set KROGER_CLIENT_ID
    firebase functions:secrets:set KROGER_CLIENT_SECRET
    
  3. Update CALLBACK_URL in callback.ts and authorize.ts to point to your project
  4. Deploy:
    firebase deploy --only functions,firestore:rules
    
  5. Replace all us-central1-krocli.cloudfunctions.net URLs in this skill with your own project URL

Option 2: Use the krocli CLI directly (no proxy at all)

If you have Go installed, you can skip the proxy entirely:

go install github.com/blanxlait/krocli/cmd/krocli@latest
krocli auth credentials set /path/to/your/kroger-creds.json
krocli products search --term "milk"
krocli auth login   # browser OAuth, tokens stored in OS keyring
krocli cart add --upc 0011110838049

In this mode, all API calls go directly to api.kroger.com using your own credentials. No proxy involved. Tokens are stored locally in your OS keyring.

Comments

Loading comments...