salai-cli
Salai CLI Skill (Shell / Terminal)
Use the salai CLI to search Israeli grocery products, compare prices, manage carts, and (recommended) quote whole shopping lists in one call. Production Salai endpoints are the default — no URL configuration for normal use.
Longer agent guidance: docs/agent-spec-short.md in this repository; full docs/agent-spec.md may live in the SalAi monorepo.
Prerequisites
salaiCLI installed:npm i -g salaiornpx salai <command>- Auth (see below):
SALAI_API_KEYor--api-key,salai login(credentials file), or legacyMCP_API_KEYwhenSALAI_API_KEYis unset. If both env and file exist,SALAI_API_KEYoverrides the file — unset it (e.g.env -u SALAI_API_KEY) to use logged-in credentials. - Selected store is required for
search,autocomplete,cart, and forcompare/pricesscope — not forshopping-list/fulfill(quote mode is request-scoped; noSELECTED_STORE_REQUIRED)
CRITICAL: Always use --json
When calling salai as an agent, always append --json to every command (including salai whoami when you need machine-readable output). Parse structured JSON from the output.
Auth (device login)
| Command | What it does |
|---|---|
salai login |
Device sign-in in the browser; on success writes ~/.config/salai/credentials.json. |
salai logout |
Removes the credential file; --revoke also deactivates that API key on the server. |
salai whoami |
Prints account/key metadata (never the secret); use --json for scripts. |
salai login [--no-browser] [--name <label>]
salai logout [--revoke]
salai whoami [--json]
| Variable | Purpose |
|---|---|
SALAI_LOGIN_NO_BROWSER |
Set to 1 to skip opening the browser during salai login (same idea as --no-browser) |
Commands Reference
Shopping list (recommended — no selected store)
Resolves a shopping list, compares baskets across stores, returns ranked stores, per-item match types, promotions, and alternatives. Uses MCP tool fulfill_shopping_list (quote mode). CLI: salai shopping-list (alias salai fulfill). Higher token cost and stricter rate limits than search; handle TOKEN_LIMIT_REACHED and RATE_LIMIT_EXCEEDED.
# Inline list (comma-separated); Hebrew quantities supported in the text
salai shopping-list "חלב, לחם, ביצים" --json
salai shopping-list "פעמיים חלב, לחם" --json
# List file (newline-separated lines)
salai shopping-list --file ./list.txt --json
# Store universe: online_only (default) or all_active (explicit store IDs: salai call, not this subcommand)
salai shopping-list "חלב" --scope all_active --max-stores 5 --json
# Alternatives: same-brand substitutions only; or disable alternatives
salai shopping-list "חלב" --brand-strict --json
salai shopping-list "חלב" --no-alternatives --json
For scope.mode: explicit with a specific stores[] list, use the escape hatch — the shopping-list subcommand does not pass explicit store pairs:
salai call fulfill_shopping_list --args '{"rawList":"חלב","scope":{"mode":"explicit","stores":[{"retailerId":"...","storeId":"..."}]}}' --json
Stores (no store selection required)
salai retailers --json # List all retailers [{retailerId, name}]
salai stores --json # List all stores [{retailerId, storeId, retailerName, name}]
salai store --json # Show current selected store context
salai store set <retailerId> <storeId> # Set selected store (no --json needed)
Search (requires selected store)
salai search "<Hebrew query>" --json # Semantic search, returns numbered products
salai autocomplete "<Hebrew query>" --json # Fast text lookup
salai ac "<query>" --json # Alias for autocomplete
salai ac "<query>" --method semantic --json # Semantic autocomplete fallback
Search JSON output shape (structuredContent):
{
"viewType": "numbered_products",
"query": "חלב",
"numberedProducts": [
{ "index": 1, "itemCode": "7290000042015", "itemName": "חלב שקית 3% תנובה", "price": 6.35, "displayPrice": "₪6.35" }
]
}
Extract itemCode from results for cart and price commands.
Pricing (requires selected store for scope)
salai prices <itemCode> [<itemCode>...] --json # Prices for specific items
salai compare <itemCode:qty> [<itemCode:qty>...] --json # Compare across retailers
Compare format: salai compare 7290000042015:2 7290019489443:1 --json
Cart (requires selected store)
salai cart --json # Show current cart
salai cart add <itemCode> --json # Add item (qty defaults to 1)
salai cart add <itemCode> --qty 3 --json # Add with quantity
salai cart set-qty <itemCode> <quantity> --json # Set quantity (0 = remove)
salai cart remove <itemCode> --json # Remove item
salai cart compare --json # Compare cart across stores
salai cart delete <cartId> --json # Delete a cart
The cart add command auto-resolves the cart ID — no --cart-id.
Recommendations
salai recommend <itemCode> --json # Complementary product suggestions
salai rec <itemCode> --json # Alias
Low-level (escape hatch)
salai tools --json # List all MCP tools
salai call <toolName> --args '{"key":"value"}' --json # Call any tool by name
Workflow
Shopping list in one call (preferred when quoting)
salai shopping-list "<items>" --jsonorsalai shopping-list --file path --json- Parse ranked stores, line items,
tokenUsageif present; respect rate limits before retrying
Legacy granular cart workflow
- Check store:
salai store --json— if none, continue - Set store:
salai stores --json→ pick →salai store set <retailerId> <storeId> - Search:
salai search "חלב" --json→numberedProducts[].itemCode - Add to cart:
salai cart add <itemCode> --json - Compare:
salai cart compare --json
Price comparison without cart
salai search "חלב" --json→itemCodesalai compare <itemCode>:1 --json
Store and scope behavior
| Commands | Behavior |
|---|---|
shopping-list / fulfill |
No selected store; scope from flags / tool args (online_only, all_active, or explicit via salai call) |
login, logout, whoami |
No selected store; credentials / API only |
store, stores, retailers |
Work without a selected store |
search, autocomplete, cart * |
Require a selected store |
compare, prices |
Cross-store comparison (needs selected store for scope) |
recommend, tools |
Work without a selected store |
If no store is set, store-scoped commands return status: "blocked", errorCode: "SELECTED_STORE_REQUIRED". Use salai store set first — unless you are using shopping-list / fulfill, which does not use the selected-store context for quote mode.
Error handling
- No output / connection error — check auth (
SALAI_API_KEY,salai login, or credential file) and network SELECTED_STORE_REQUIRED—salai store set <retailerId> <storeId>(not applicable toshopping-list/fulfill)TOKEN_LIMIT_REACHED/RATE_LIMIT_EXCEEDED— especially on shopping list quotes; back off, reduce frequency, or upgrade plan; read responseretryAfterMsif presentAUTH_REQUIRED— missing or invalid key; runsalai loginor setSALAI_API_KEY/--api-keyINVALID_INPUT— empty list, bad scope, etc.- Empty search results — try
salai ac "<query>" --method semantic --json - Never log or expose the API key