The OpenCart CLI you wish came in the box — query, edit, and operate your OpenCart store from the terminal. AI-powered queries, live order watching, interactive shell.
Project description
opencart-cli
The OpenCart CLI you wish came in the box. Query, edit, and operate your store from the terminal. AI-powered queries, interactive shell, live order watching, dry-run safety on every mutation.
$ pip install opencart-cli
$ opencart init
$ opencart ask "which products are low on stock?"
That's it. You're operating an OpenCart store from the terminal.
What you get
— sparklines, pretty tables, money formatting, all out of the box. Pipe it through jq and it switches to JSON automatically.
Want to see it yourself in your own terminal? Run
opencart demo sales(orproducts,orders,doctor,all) — works without setting up a profile, uses canned data through the real rendering pipeline.
✨ Features
- 🤖
opencart ask "..."— ask in plain English, get SQL generated with full schema context, see the SQL, confirm, run it. Powered by Claude or OpenAI. - 🐚
opencart shell— interactive REPL with persistent connection. ~30× faster for multi-command workflows. - 📡
opencart watch orders— live tail of new orders with terminal-bell notifications. - 🏥
opencart doctor— diagnoses SSH/DDEV/MySQL/PHP/OpenCart in one command. Tells you exactly what's wrong. - 🛡️ Safety-first defaults — dry-run on every mutation,
--read-onlymode, auto-readonly on profiles namedprod*, audit log of every change. - 🔌 3 connection backends — remote SSH, local DDEV, local PHP/Docker. Same commands, same UX.
- 🌎 Multi-profile — manage many stores from one CLI.
opencart --profile staging products list. - 🔐 Secrets in OS keychain — DB passwords stored in macOS Keychain / Linux Secret Service / Windows Credential Manager. Never in plaintext config.
- 📊 Beautiful output — Unicode sparklines, ANSI tables, money formatting. Auto-falls-back to JSON when piped.
- 🐚 Shell completions — bash, zsh, fish, PowerShell. Generated by typer.
- 📦 Works with OpenCart 2.x, 3.x, 4.x — schema differences auto-detected.
🚀 Quick start
Install
Recommended — using pipx (puts opencart on your PATH globally in an isolated environment):
brew install pipx && pipx ensurepath
pipx install opencart-cli # core CLI
pipx install 'opencart-cli[ai]' # plus `opencart ask` (Claude/OpenAI)
Or plain pip (works but you'll need to manage your own venv or pip install --user):
pip install opencart-cli
If
opencartis "command not found" after a plainpip install, the script likely landed somewhere not on your PATH.pipxsolves this universally.
Configure (interactive)
opencart init
The wizard asks for connection type (SSH / DDEV / local), credentials, OpenCart paths, and tests the connection before saving. Config lands at ~/.config/opencart-cli/config.yaml, DB password in the OS keychain.
Use
opencart products list --low-stock-under 5
opencart orders list --days 7 --min-total 100
opencart sales summary --days 30
opencart customers list --search "jane@"
opencart ask "what's our best-selling category this month?"
🧠 opencart ask — the headline feature
You don't always remember the exact column names. AI does.
$ opencart ask "show me products under £10 with less than 5 in stock"
Reading schema...
Asking Claude (Anthropic)...
Explanation: Find active products priced below £10 with low stock.
Generated SQL:
SELECT p.product_id, p.model, pd.name, p.price, p.quantity
FROM oc_product p
LEFT JOIN oc_product_description pd ON pd.product_id = p.product_id
WHERE p.price < 10 AND p.quantity < 5 AND p.status = 1
LIMIT 50
Run this query? [Y/n]: y
┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┓
┃ product_id ┃ model ┃ name ┃ price ┃ quantity ┃
┣━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━┫
┃ 42 ┃ MOUSE-WL-01 ┃ Wireless Mouse Pro ┃ £9.99 ┃ 3 ┃
┃ 87 ┃ CABLE-USBC-1M ┃ USB-C Cable 1m ┃ £8.50 ┃ 2 ┃
┗━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━┻━━━━━━━━━━┛
Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your environment. The CLI picks whichever it finds. AI only ever generates SELECT statements — mutations are blocked.
🔌 Connection backends
SSH (remote VPS / shared hosting)
profiles:
prod:
connection:
type: ssh
host: 12.34.56.78
user: youruser
key: ~/.ssh/id_ed25519
db: {user: yourdb, name: yourshop}
opencart: {root: /home/youruser/public_html, version: 3.x}
DDEV (local development)
profiles:
local:
connection:
type: ddev
project_path: ~/Sites/my-opencart
db: {user: db, name: db}
opencart: {root: /var/www/html}
Local (Docker Compose, MAMP, native PHP)
profiles:
docker:
connection:
type: local
php_bin: "docker compose exec web php"
cwd: ~/Sites/my-shop
db: {user: oc, name: opencart, host: 127.0.0.1, port: 3306}
opencart: {root: /var/www/html}
Run opencart doctor to verify any profile end-to-end.
🛡️ Safety model
Every mutation command runs through the same safety pipeline:
- Read-only mode wins. Profiles named
prod*are auto-read-only. Explicitread_only: truemakes any profile read-only.--read-onlyflag forces it per-invocation. - Dry-run by default for big changes.
--dry-runpreviews the plan, applies nothing. - Confirmation prompts. Every mutation prompts unless
--yesis passed. - Audit log. Every change is logged to
~/.config/opencart-cli/audit.jsonlwith before/after diff, timestamp, user, host. View withopencart audit show. - Parameterised SQL. Nothing user-supplied is concatenated into SQL — uses
mysqli_prepareend-to-end. - Raw
opencart sqlblocks mutations and DDL. OnlySELECT/SHOW/DESCRIBE/EXPLAINallowed there.
$ opencart -y products update 183 --price 99.99
Plan: Update product 183
price: 65.99 → 99.99
✗ Profile 'prod' is read-only — refusing to execute mutation.
🤝 opencart-cli vs opencart-mcp
Same engine, two cockpits. Pick the one that matches how you work — or use both.
opencart-mcp |
opencart-cli (this repo) |
|
|---|---|---|
| Who uses it | Claude (or another AI) | You, with the keyboard |
| Invoked via | Natural language in Claude Code / Cursor | Terminal commands |
| Output | JSON for the AI to read | Tables / JSON / YAML / CSV |
| AI involvement | Required | Optional (opencart ask only) |
| Connection cost | New SSH per call | Persistent SSH — ~30× faster |
| Best for | Conversational ops while chatting | Scripts, cron, REPL, headless servers |
The CLI is everything the MCP is, plus a terminal-first interface, persistent connections, AI inside the terminal (no Claude Code needed), shell completions, pipes for jq, watch mode, and an interactive REPL.
📦 Configuration
Config file (paths + connection details only — never secrets):
- macOS:
~/Library/Application Support/opencart-cli/config.yaml - Linux:
~/.config/opencart-cli/config.yaml - Windows:
%APPDATA%\opencart-cli\config.yaml
Override with OPENCART_CLI_CONFIG=/some/path.yaml.
Secrets (DB passwords): OS keychain by default. Override via env var OPENCART_<PROFILE>_DB_PASS (e.g. OPENCART_PROD_DB_PASS). CI-friendly — no keychain needed.
SSH keys: referenced by path, never embedded.
🎛 Output formats
opencart products list # auto: table if TTY, JSON if piped
opencart -f json products list # explicit JSON
opencart -f yaml settings list # explicit YAML
opencart -f csv orders list --days 7 # explicit CSV
opencart products list | jq '.[] | select(.price | tonumber > 50)'
🩺 opencart doctor
When things don't work, run this first.
$ opencart doctor
Diagnosing profile: prod
Connection: ssh
✓ Connection: built SSHConnection
✓ Shell exec: responsive
✓ PHP: 7.4.33
✓ MySQL: 8.0.45
✓ OpenCart tables: found (oc_product exists)
✓ OpenCart version: 3.x
✓ All checks passed.
If anything fails, the message tells you what to fix.
🛠 Command reference
opencart init Interactive setup wizard
opencart demo <sales|products|orders|doctor|all> Try the CLI without a profile
opencart doctor Diagnostic checks
opencart ask "..." AI natural-language query
opencart shell Interactive REPL
opencart watch orders Live tail new orders
opencart sql "SELECT ..." Raw SQL (SELECT/SHOW/DESCRIBE only)
opencart version Print version
opencart products list List products (filters: --search, --status, --low-stock-under)
opencart products get <id> Full product detail
opencart products update <id> Update product fields (dry-run default)
opencart orders list Recent orders (filters: --days, --status, --min-total)
opencart orders get <id> Order header + line items + history
opencart customers list List/search customers
opencart settings list List OpenCart settings (filters: --group, --key)
opencart settings set <group> <key> <value> Update a setting
opencart stock low Low stock report (filter: --threshold)
opencart sales summary Sales totals + sparkline + top sellers
opencart sales daily Daily breakdown
opencart profile list List profiles
opencart profile use <name> Set default profile
opencart profile show [name] Show full profile config
opencart profile remove <name> Remove a profile
opencart --install-completion Shell completion (bash/zsh/fish/PowerShell)
Global flags (place before the subcommand):
-p, --profile <name> Use a specific profile
-f, --format <fmt> Output format: auto/table/json/yaml/csv
-y, --yes Skip confirmation prompts
--dry-run Show what would change, do nothing
--read-only Force read-only mode this invocation
-V, --version Print version
🤝 Contributing
PRs welcome — see CONTRIBUTING.md. Issues for bug reports and feature requests. The codebase is small, well-typed, and ruff-clean.
📜 License
MIT — do whatever you like.
⭐ If this saved you 10 minutes of admin-panel clicking, please star the repo.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file opencart_cli-1.0.0.tar.gz.
File metadata
- Download URL: opencart_cli-1.0.0.tar.gz
- Upload date:
- Size: 39.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6f7b50bbed3f354e2df426e856f71eed5eeba2a2184ec769db4748b910fb760
|
|
| MD5 |
533dbe0cc0c581b9e7b51b75b38e1063
|
|
| BLAKE2b-256 |
6930e73ea63803ba16c6de4de880ca97f5da46dc902929adea7cb101f98c32f4
|
Provenance
The following attestation bundles were made for opencart_cli-1.0.0.tar.gz:
Publisher:
release.yml on chrisbray85/opencart-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
opencart_cli-1.0.0.tar.gz -
Subject digest:
d6f7b50bbed3f354e2df426e856f71eed5eeba2a2184ec769db4748b910fb760 - Sigstore transparency entry: 1506048430
- Sigstore integration time:
-
Permalink:
chrisbray85/opencart-cli@340213b09847625b85906769461be653cb654b1a -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/chrisbray85
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@340213b09847625b85906769461be653cb654b1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file opencart_cli-1.0.0-py3-none-any.whl.
File metadata
- Download URL: opencart_cli-1.0.0-py3-none-any.whl
- Upload date:
- Size: 51.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd87ee920e766d1e14a82b509785492a1e4fdc43169692179d20375635c04eb3
|
|
| MD5 |
b7e06a17b6c2e90f55821fc972e4a71f
|
|
| BLAKE2b-256 |
66353eff1df67a6acd33a0b89221bb218684d292ed9b6e8e678784ca7fa3dbca
|
Provenance
The following attestation bundles were made for opencart_cli-1.0.0-py3-none-any.whl:
Publisher:
release.yml on chrisbray85/opencart-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
opencart_cli-1.0.0-py3-none-any.whl -
Subject digest:
fd87ee920e766d1e14a82b509785492a1e4fdc43169692179d20375635c04eb3 - Sigstore transparency entry: 1506048531
- Sigstore integration time:
-
Permalink:
chrisbray85/opencart-cli@340213b09847625b85906769461be653cb654b1a -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/chrisbray85
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@340213b09847625b85906769461be653cb654b1a -
Trigger Event:
push
-
Statement type: