🛒
One CLI that handles grocery shopping at any UK supermarket.
Your AI agent can now search products, manage baskets, book delivery, and checkout across Sainsbury's, Ocado, Tesco, and more.
Quick Start • Supported Stores • How It Works • Agent Integration • Smart Shopping • API Reference
If you're building AI agents for the agentic era, there's a gap: UK supermarkets offer zero APIs.
Sainsbury's, Ocado, Tesco, Asda, Morrisons — none of them provide developer APIs. No OAuth, no REST endpoints, no webhooks. If you want your agent to shop for groceries, there's no official way to do it.
But agents need to eat. Meal planning, auto-reordering, budget optimization — these are perfect agent workflows. The infrastructure just doesn't exist.
UK Grocery CLI closes that gap. Reverse-engineered integrations that give your agent a unified command-line interface to every major UK supermarket. Your agent calls groc search "milk" and it works whether you're shopping at Sainsbury's or Ocado.
Built for agent frameworks like OpenClaw, Pi, Claude Desktop MCP. Works with any agent that can shell out to a CLI. Your agent handles the intelligence (meal planning, budget optimization, dietary preferences). The CLI handles the grunt work (authentication, API calls, basket state).
- ✅ Sainsbury's - UK-wide delivery, full API coverage
- ✅ Ocado - London & South England, complete integration
- 🔜 Tesco - Coming soon (API reverse-engineering in progress)
- 🔜 Asda - Planned Q2 2026
- 🔜 Morrisons - Planned Q2 2026
# Clone the repository
git clone https://github.com/abracadabra50/uk-grocery-cli.git
cd uk-grocery-cli
# Install dependencies
npm install
# Install Playwright for authentication
npx playwright install chromium
# Optional: Link globally to use 'groc' command anywhere
npm link# Login to Sainsbury's (saves session to ~/.sainsburys/session.json)
npm run groc login --email YOUR_EMAIL --password YOUR_PASSWORD
# Or if installed globally:
groc --provider sainsburys login --email YOUR_EMAIL --password YOUR_PASSWORD
# Test it works
npm run groc search "milk"# Search for products
npm run groc search "organic milk"
# Add to basket
npm run groc add 357937 --qty 2
# View basket
npm run groc basket
# Book delivery and checkout
npm run groc slots
npm run groc book <slot-id>
npm run groc checkout# Agent calls via bash:
cd /path/to/uk-grocery-cli && npm run groc search "chicken breast" --json
cd /path/to/uk-grocery-cli && npm run groc add 357937 --qty 2
cd /path/to/uk-grocery-cli && npm run groc basket --jsonSee SKILL.md for complete agent integration guide.
The CLI provides a unified interface:
groc --provider <store> <command> [options]Switch providers with a flag. Commands stay the same.
groc --provider sainsburys search "milk" # Sainsbury's
groc --provider ocado search "milk" # Ocado
groc --provider tesco search "milk" # Tesco (coming soon)Under the hood:
Each provider implements a common interface:
interface GroceryProvider {
search(query: string): Promise<Product[]>;
getBasket(): Promise<Basket>;
addToBasket(id: string, qty: number): Promise<void>;
getSlots(): Promise<DeliverySlot[]>;
checkout(): Promise<Order>;
}The CLI routes commands to the right provider. Your agent doesn't care which store you're using.
Your agent can call the CLI directly:
// User: "Order milk from Sainsbury's"
// Agent executes:
await exec('groc --provider sainsburys search "milk" --json');
await exec('groc --provider sainsburys add 357937 --qty 2');
await exec('groc --provider sainsburys checkout');User: "Plan meals for this week, £60 budget, prefer organic"
Agent logic:
- Plans 7 meals based on preferences
- Extracts ingredient list
- For each ingredient:
- Searches product:
groc search "strawberries" - Decides organic vs conventional (see Smart Shopping)
- Adds to basket:
groc add <id> --qty <n>
- Searches product:
- Books delivery slot
- Checks out
The CLI handles: Product search, basket operations, checkout
Your agent handles: Meal planning, organic decisions, budget optimization
See AGENTS.md for complete integration guide.
The CLI provides product data. Your agent makes intelligent decisions.
// Agent logic (not CLI)
const dirtyDozen = ['strawberries', 'spinach', 'kale', 'apples'];
const cleanFifteen = ['avocados', 'sweetcorn', 'pineapple'];
if (dirtyDozen.includes(product)) {
// High pesticide residue - always buy organic
await search('organic strawberries');
} else if (cleanFifteen.includes(product)) {
// Low pesticide - save money with conventional
await search('strawberries');
}// Compare organic vs conventional pricing
const organic = await search('organic milk');
const conventional = await search('milk');
const premium = (organic.price - conventional.price) / conventional.price;
if (premium < 0.20 && budget.hasRoom()) {
return organic; // Less than 20% more - worth it
} else {
return conventional; // Save money
}// Agent can shop across stores
const sainsburys = await groc('--provider sainsburys search "milk"');
const ocado = await groc('--provider ocado search "milk"');
// Choose based on price, delivery area, or availabilitySee docs/SMART-SHOPPING.md for complete guide on organic decisions, seasonal produce, waste prevention, and meal optimization.
-p, --provider <name> Choose: sainsburys, ocado, tesco
groc providers List available providersgroc search <query> Search products
--json Output JSON for parsingExample output:
[
{
"id": "357937",
"name": "Sainsbury's Organic Semi-Skimmed Milk 2L",
"price": 1.65,
"unit": "2L",
"available": true
}
]groc basket View current basket
groc add <id> --qty <n> Add item to basket
groc remove <item-id> Remove item from basket
groc clear Empty basketgroc slots View available delivery slots
groc book <slot-id> Reserve delivery slot
groc checkout Place order
--dry-run Preview order without placinggroc login --email <email> --password <pass>
groc logout
groc status Check login statusUses your existing supermarket account and saved payment method.
How it works:
- Login once via browser automation (Playwright)
- Session cookies saved locally (
~/.sainsburys/session.json) - CLI uses cookies for API authentication
- Checkout uses your saved card from account settings
- No card details ever touch the CLI
Security:
- Session files git-ignored by default
- Cookies stored locally only
- No card data handled by CLI
- PCI compliant (payment stays in supermarket systems)
- Same security model as using the website
Setup payment method:
- Visit sainsburys.co.uk/myaccount (or your provider)
- Add payment method in account settings
- Set default card
- CLI will use it when checking out
interface GroceryProvider {
search(query: string): Promise<Product[]>;
getBasket(): Promise<Basket>;
addToBasket(id: string, qty: number): Promise<void>;
removeFromBasket(itemId: string): Promise<void>;
getSlots(): Promise<DeliverySlot[]>;
bookSlot(slotId: string): Promise<void>;
checkout(): Promise<Order>;
}Each provider implements this interface. Adding new supermarkets is plug-and-play.
Both Sainsbury's and Ocado use simple REST:
Sainsbury's:
GET /groceries-api/gol-services/product/v1/product?filter[keyword]=milk
POST /groceries-api/gol-services/basket/v2/basket/items
Ocado:
GET /api/search/v1/products?query=milk
POST /api/trolley/v1/items
See API-REFERENCE.md for complete endpoint documentation.
Agent plans meals → generates shopping list → searches products → orders → delivers
Agent tracks consumption → monitors inventory → reorders essentials when low
Agent tracks spending → suggests cheaper alternatives → keeps you on budget
Agent filters by halal/kosher/vegan/gluten-free → excludes restricted items
Agent prioritizes organic for Dirty Dozen → saves money on Clean Fifteen
See docs/SMART-SHOPPING.md for implementation examples.
uk-grocery-cli/
├── src/
│ ├── providers/
│ │ ├── types.ts # Common interface
│ │ ├── sainsburys.ts # Sainsbury's implementation
│ │ ├── ocado.ts # Ocado implementation
│ │ └── index.ts # Provider factory
│ ├── auth/
│ │ └── login.ts # Playwright authentication
│ └── cli.ts # Multi-provider CLI
├── docs/
│ ├── SMART-SHOPPING.md # Agent intelligence guide
│ └── API-REFERENCE.md # Complete API documentation
├── SKILL.md # OpenClaw skills format
├── AGENTS.md # Agent integration guide
└── README.md # This file
- 2FA Required: Sainsbury's requires SMS verification on every login
- Session Duration: Sessions expire after ~7 days (re-login needed)
- ✅ Working: Search, basket management, product data
⚠️ Experimental: Delivery slots (endpoint partially documented)⚠️ Experimental: Checkout flow (needs real-world testing)- 🔜 Coming: Order tracking, substitutions, favourites
Some endpoints are still being reverse-engineered. Contributions welcome.
git clone https://github.com/abracadabra50/uk-grocery-cli
cd uk-grocery-cli
npm install
npm run build
npm run groc -- --provider sainsburys search "milk"Contributions welcome!
Want to add:
- More supermarkets (Tesco, Asda, Morrisons)
- Missing API endpoints (slots, checkout improvements)
- Smart shopping algorithms
- Nutritional data integration
- Meal planning templates
Open an issue or PR.
- ✅ Multi-provider architecture
- ✅ Sainsbury's provider (full coverage)
- ✅ Ocado provider (full coverage)
- ✅ Smart shopping guide
- 🔜 Tesco provider
- 🔜 Delivery slot optimization
- 🔜 Price history tracking
- 🔜 Substitution handling
- 🔜 Asda & Morrisons providers
- 🔜 Nutritional data API
- 🔜 Recipe database integration
- 🔜 MCP server implementation for Claude Desktop
- 🔜 Model Context Protocol integration
- 🔜 Native Claude app support
MIT - Free to use, modify, distribute.
Personal Use Only
This tool is designed for personal grocery shopping automation and agent development. It is not intended for:
- Commercial scraping or data collection
- Reselling grocery data
- Automated bulk ordering for businesses
- Any use that violates supermarket terms of service
How It Works
The CLI uses your personal supermarket account credentials. You authenticate once (just like logging into the website), and the CLI uses your session to place orders on your behalf. This is functionally equivalent to using the website, just via command line instead of a browser.
Your Responsibility
By using this tool, you agree to:
- Use it only for your personal grocery shopping
- Comply with each supermarket's terms of service
- Not abuse rate limits or cause disruption
- Not use it for commercial purposes
No Affiliation
This project is not affiliated with, endorsed by, or sponsored by Sainsbury's, Ocado, Tesco, Asda, Morrisons, or any other supermarket chain. All trademarks are property of their respective owners.