Unofficial Model Context Protocol (MCP) server for PC Express / Loblaws grocery shopping
Control your grocery cart with AI! This MCP server enables LLMs (like Claude) to search past orders, find products, and manage your shopping cart across all Loblaws-owned grocery banners.
- Unofficial: This project is NOT affiliated with, endorsed by, or supported by Loblaws Companies Limited, PC Express, or any related entities
- Use at Your Own Risk: This uses an undocumented API that may change without notice
- No Warranty: See LICENSE for details
- Educational Purpose: This project demonstrates API reverse engineering and MCP server development
Works with all PC Express enabled stores:
- Zehrs - Ontario-based grocery chain
- Loblaws - Main flagship banner
- No Frills - Discount grocery banner
- Real Canadian Superstore - Western Canada supermarket
- Your Independent Grocer - Franchise stores
- T&T Supermarket - Asian specialty supermarket
- search_past_orders - Find items from your order history
- get_order_items - Get detailed product list from specific orders
- search_products - Search the product catalog
- add_to_cart - Add products to your shopping cart
- remove_from_cart - Remove items from cart
- view_cart - See current cart contents
- β Home Assistant - Voice-controlled grocery shopping
- β Claude Desktop - Chat with your grocery list
- β Custom Clients - Any MCP-compatible application
π€ "Add ice cream to my grocery cart"
π€ "What did I order last week?"
π€ "Search for organic bananas"
π€ "What's in my cart?"
- Python 3.10 or higher
- Active account with a PC Express enabled banner
- pip or pip3
-
Clone the repository
git clone https://github.com/YOUR_USERNAME/pcexpress-mcp-server.git cd pcexpress-mcp-server -
Install dependencies
pip install -r requirements.txt
-
Configure credentials
cp .env.example .env # Edit .env with your credentials (see Configuration section) -
Test the connection
python test_api.py
-
Run the server
python pcexpress_mcp_server.py
Since there's no public API, you need to extract credentials from your browser session:
- Visit your banner's website (e.g., www.zehrs.ca)
- Log in to your account
- Open DevTools (F12) β Network tab
- β Check "Preserve log"
- Clear network log
- Navigate to your cart and past orders
- Right-click in Network tab β "Save all as HAR with content"
- Run the credential extractor:
python extract_credentials.py path/to/file.har
This automatically creates your .env file!
See SETUP.md for detailed manual extraction instructions.
# OAuth Bearer Token (expires after a few hours)
PCEXPRESS_BEARER_TOKEN=your_bearer_token_here
# Your customer/user ID
PCEXPRESS_CUSTOMER_ID=your_customer_id_here
# Your active cart ID
PCEXPRESS_CART_ID=your_cart_id_here
# Store ID (4-digit code)
PCEXPRESS_STORE_ID=your_store_id_here
# Banner: zehrs, loblaws, nofrills, superstore, independent, tandt
PCEXPRESS_BANNER=zehrs# configuration.yaml
mcp:
servers:
- name: pcexpress
command: python3
args:
- /path/to/pcexpress_mcp_server.py
env:
PCEXPRESS_BEARER_TOKEN: "your_token"
PCEXPRESS_CUSTOMER_ID: "your_id"
PCEXPRESS_CART_ID: "your_cart"
PCEXPRESS_STORE_ID: "your_store"
PCEXPRESS_BANNER: "zehrs"Edit your Claude Desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%/Claude/claude_desktop_config.json
{
"mcpServers": {
"pcexpress": {
"command": "python3",
"args": ["/path/to/pcexpress_mcp_server.py"],
"env": {
"PCEXPRESS_BEARER_TOKEN": "your_token",
"PCEXPRESS_CUSTOMER_ID": "your_id",
"PCEXPRESS_CART_ID": "your_cart",
"PCEXPRESS_STORE_ID": "your_store",
"PCEXPRESS_BANNER": "zehrs"
}
}
}
}Restart Claude Desktop and start chatting about groceries!
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
server_params = StdioServerParameters(
command="python3",
args=["pcexpress_mcp_server.py"],
env={
"PCEXPRESS_BEARER_TOKEN": "your_token",
# ... other env vars
}
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# List available tools
tools = await session.list_tools()
# Call a tool
result = await session.call_tool("search_products", {
"query": "ice cream"
})- QUICKSTART.md - 5-minute setup guide
- SETUP.md - Detailed configuration instructions
- BANNERS.md - Multi-banner usage guide
- ARCHITECTURE.md - Technical architecture details
- CONTRIBUTING.md - How to contribute
Problem: Bearer tokens expire after a few hours
Impact: Server stops working when token expires
Workaround: Re-extract credentials from browser session
Status: β Not solved - Long-term authentication not yet implemented
See #1 - Implement automatic token refresh
Problem: Type-ahead search only returns category suggestions, not actual products
Impact: Can't directly get product codes for adding to cart
Workaround: Use past orders to find product codes
Status: π Investigating alternative endpoints
Problem: Cart ID may change on logout/login
Impact: Server needs cart ID updated
Workaround: Re-extract credentials
Status:
Problem: Using reverse-engineered, undocumented API
Impact: May break if Loblaws changes their API
Workaround: Monitor for changes, update accordingly
Status:
Problem: Product availability varies by store location
Impact: Search results depend on selected store
Workaround: Ensure correct PCEXPRESS_STORE_ID is set
Status: β Expected behavior
Cause: Token expired or invalid
Fix: Re-extract credentials from browser
Cause: Cart/Customer ID changed or wrong banner
Fix: Verify PCEXPRESS_BANNER matches token source, re-extract IDs
Cause: Store doesn't carry product or wrong store ID
Fix: Verify PCEXPRESS_STORE_ID is correct
Cause: Missing dependencies or invalid credentials
Fix:
pip install -r requirements.txt
python extract_credentials.py your_file.harSee full troubleshooting guide in SETUP.md
- Automatic token refresh (#1)
- Full product search (not just type-ahead) (#2)
- Cart ID change detection (#3)
- Better error messages (#4)
- Shopping list management
- PC Optimum points integration
- Checkout/order placement
- Product details (images, nutrition, etc.)
- Price tracking
- Multiple banner support in single instance
- Recipe suggestions based on cart
- Price comparison across banners
See Issues for full list.
Contributions are welcome! See CONTRIBUTING.md for guidelines.
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Test thoroughly (
python test_api.py) - Commit (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the GNU Affero General Public License v3.0 - see the LICENSE file for details.
- Thanks to the MCP protocol team at Anthropic
- Inspired by the need for better grocery shopping automation
- Built with reverse-engineering and determination
This project is provided for educational and personal use only.
- Not affiliated with Loblaws Companies Limited
- Uses undocumented API - use at your own risk
- May violate Terms of Service - check before using
- No warranty or guarantee of functionality
- Author not responsible for any consequences of use
By using this software, you agree to take full responsibility for your usage.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made with β€οΈ for better grocery shopping
If this project saved you time, consider starring β the repo!