Agent-native commerce CLI
Project description
shop
Status: alpha (v0.1.0). Core search, mandate, cart, and order flows work. PyPI and binary releases coming soon. Expect breaking changes until v1.0. Feedback welcome — open an issue.
Agent-native commerce CLI. All commands return JSON. Humans configure once; agents invoke autonomously.
git clone https://github.com/antonyevans/shop-cli
pip install -e shop-cli/
shop search products "coffee filters" --max-price 20
What it is
shop is a CLI built for AI agents as the primary user. It handles product discovery, mandate-enforced purchasing, and order tracking — with JSON output on every command and semantic exit codes agents can branch on.
Agents never see card credentials. Spending policy lives in signed mandate files, not in agent prompts.
Install
git clone https://github.com/antonyevans/shop-cli
pip install -e shop-cli/
Requires Python 3.9+. A pip install shop-cli PyPI release is planned once the API stabilizes.
Quick start
1. Add a payment method
Choose the payment network that matches your merchants:
Stripe (works with UCP and ACP merchants):
shop payment add --label "My Visa" --stripe-key sk_live_...
# → opens browser URL for PCI-compliant card entry
shop payment confirm --session-id cs_xxx --stripe-key sk_live_...
Shop Pay (works with Shopify UCP merchants):
shop payment add-shop-pay \
--token SHOP_PAY_TOKEN \
--email buyer@example.com \
--first-name Jane --last-name Smith \
--address1 "123 Main St" --city "Portland" --province OR --zip 97201
PayPal Fastlane (works with PayPal Fastlane merchants):
shop payment add-paypal-fastlane \
--token FASTLANE_TOKEN \
--email buyer@example.com
2. Connect a merchant
Shopify Global Catalog — search across ~1M+ Shopify stores:
shop merchant connect-shopify \
--client-id YOUR_CLIENT_ID \
--client-secret YOUR_CLIENT_SECRET
Shopify UCP checkout — agent checkout via Shop Pay at a specific Shopify store:
shop merchant add-shopify-checkout \
--store-domain my-store.myshopify.com
# uses credentials from connect-shopify above
UCP merchant — any merchant publishing /.well-known/ucp:
shop merchant add https://store.example.com
ACP merchant — Stripe Agentic Commerce Protocol endpoint:
shop merchant add-acp https://store.example.com [--acp-key KEY]
PayPal Fastlane merchant:
shop merchant add-paypal \
--name "Acme Store" \
--client-id PP_CLIENT_ID \
--client-secret PP_CLIENT_SECRET
3. Create a mandate
Mandates define what an agent is allowed to buy. They're Ed25519-signed YAML files stored in ~/.shop/mandates/.
shop mandate create \
--budget-total 500 \
--per-order-max 50 \
--period monthly \
--category-allow "office supplies,coffee"
4. Search and buy
# Search
shop search products "coffee filters" --max-price 20 --in-stock-only
# Add to cart
shop cart add --sku shopify:abc123 --quantity 2
# Place order
shop order create --from-cart --idempotency-key $(uuidgen) --yes
Payment methods
shop supports five payment credential types. Each is stored as an opaque token in ~/.shop/payment.yaml — agents never see card numbers.
| Type | Command | Works with |
|---|---|---|
stripe |
shop payment add → shop payment confirm |
ucp, acp adapters |
shop_pay |
shop payment add-shop-pay |
shopify_ucp adapter |
paypal_fastlane |
shop payment add-paypal-fastlane |
paypal_fastlane adapter |
credit_card |
shop payment add-card |
shopify_storefront (dev/test only) |
Stripe flow: shop payment add creates a Stripe Checkout Session and returns a browser URL. The user enters card details in Stripe's hosted page (PCI scope stays with Stripe). shop payment confirm polls until complete, then stores only opaque Stripe IDs.
shop payment list # view stored methods (last4/brand/expiry only)
shop payment remove --id pm_xxx
Merchant adapters
| Adapter | Protocol | Payment | Use for |
|---|---|---|---|
ucp |
UCP v1 REST | Stripe | UCP-compliant merchants |
acp |
ACP REST | Stripe | ACP-spec merchants (Stripe/OpenAI standard) |
shopify_catalog |
Shopify Catalog API | (search only) | Shopify product discovery |
shopify_storefront |
Shopify Storefront API | credit card | Per-store Shopify checkout |
shopify_ucp |
Shopify UCP/MCP JSON-RPC | Shop Pay | Shopify stores (agent checkout) |
paypal_fastlane |
PayPal Orders API v2 | PayPal Fastlane | PayPal-enabled merchants |
mock |
Deterministic fixtures | — | Dev / offline testing |
Command reference
All commands exit 0 on success and return a JSON object on stdout. Errors also return JSON with error_code, detail, and exit_code.
shop search products
Search across all registered merchants in parallel.
shop search products QUERY [--max-price FLOAT] [--min-rating FLOAT] [--in-stock-only] [--explain]
{
"results": [
{
"sku": "shopify:abc123",
"title": "Arabica Coffee Filters 100-pack",
"price": 12.99,
"availability": "InStock",
"confidence": 0.87
}
],
"total": 1,
"meta": { "total_queried": 1, "failed_merchants": [] }
}
--explain adds a per-result confidence_explanation breakdown.
shop merchant commands
| Command | Description |
|---|---|
shop merchant add URL |
Discover and register UCP merchant via /.well-known/ucp |
shop merchant add-acp URL [--acp-key KEY] |
Register ACP merchant via /.well-known/acp |
shop merchant add-paypal --name N --client-id ID --client-secret S |
Register PayPal Fastlane merchant |
shop merchant add-shopify-store --store-domain D --storefront-token T |
Register Shopify Storefront merchant |
shop merchant add-shopify-checkout --store-domain D |
Register Shopify for agent UCP checkout |
shop merchant connect-shopify --client-id ID --client-secret S |
Connect Shopify Global Catalog |
shop payment commands
| Command | Description |
|---|---|
shop payment add --label L --stripe-key SK |
Start Stripe card setup (returns browser URL) |
shop payment confirm --session-id ID --stripe-key SK |
Complete Stripe setup, store credentials |
shop payment add-shop-pay --token T --email E |
Store Shop Pay token |
shop payment add-paypal-fastlane --token T --email E |
Store PayPal Fastlane token |
shop payment add-card --number N ... |
Store raw card (DEV/TEST ONLY) |
shop payment list |
List stored methods (no sensitive data) |
shop payment remove --id ID |
Remove a payment method |
shop mandate create
shop mandate create \
--budget-total FLOAT \
--per-order-max FLOAT \
--period monthly|weekly|one-time \
[--category-allow "cat1,cat2"] \
[--category-deny "cat1,cat2"] \
[--merchant-allow "slug1,slug2"] \
[--merchant-deny "slug1,slug2"] \
[--expires-at ISO8601]
shop mandate list / verify / usage
shop mandate list # all mandates with budget utilization
shop mandate verify --mandate-id ID # check Ed25519 signature
shop mandate usage --mandate-id ID # live budget + pending orders
shop cart add / view / clear
shop cart add --sku MERCHANT:SKU [--quantity 1] [--dry-run]
shop cart view [--session-id ID]
shop cart clear --yes [--session-id ID]
--dry-run validates mandate compliance and confidence scoring without writing to the database.
shop order create / status
shop order create \
--from-cart \
--idempotency-key UUID \
--yes \
[--mandate-id ID]
shop order status --order-id ID
Every order requires --idempotency-key — safe to retry on network failure.
shop history
shop history [--last 20] [--merchant slug]
Transaction audit log from local SQLite. Never leaves the machine.
shop schema commands
shop schema commands
Returns the full machine-readable CLI contract — all commands, flags, types, and exit codes. Agents use this for runtime capability discovery without reading docs.
Exit codes
Agents branch on exit codes rather than parsing error text.
| Code | Meaning | Agent action |
|---|---|---|
0 |
Success | Proceed |
1 |
Bad arguments | Fix the call |
2 |
Auth error | Re-authenticate |
3 |
Mandate violation | Stop or request approval |
4 |
Unavailable / not supported | Try another merchant |
5 |
Low confidence | Surface to human |
6 |
Network / DB error | Retry (safe) |
Confidence scoring
Every search result includes a confidence score (0.0–1.0) computed from six signals:
| Signal | Weight | Description |
|---|---|---|
fields_completeness |
30% | 7 required fields; each missing costs −10% |
seller_rating |
20% | ≥4.5 → full score; <3.5 → zero |
review_count |
20% | ≥50 → full; 10–49 → 70%; 1–9 → 40% |
return_policy |
15% | return window + condition + refund timeline |
certifications |
10% | any cert present → full score |
price_stability |
5% | 30-day max/min ratio ≤1.10 → stable |
Default threshold is 0.80 — results below threshold cause exit 5. Configure in ~/.shop/config.yaml:
confidence_threshold: 0.80
default_mandate: mandate-id-here
max_workers: 10
Configuration
| Path | Purpose |
|---|---|
~/.shop/config.yaml |
Global settings (threshold, max_workers, default mandate) |
~/.shop/merchants.yaml |
Registered merchants and adapter credentials |
~/.shop/payment.yaml |
Payment credentials (chmod 600) |
~/.shop/mandates/ |
Ed25519-signed mandate files |
~/.shop/shop.db |
SQLite order history and cart state |
~/.shop/keys/ |
Ed25519 mandate key, P-256 UCP signing key |
Override the config directory with SHOP_HOME=/path/to/dir — useful in read-only home environments or for testing.
For agents
Idiomatic agent workflow
# 1. Discover what's available
shop schema commands | jq '.commands[].noun' | sort -u
# 2. Create a mandate (once, at session start)
MANDATE=$(shop mandate create --budget-total 200 --per-order-max 40 --period monthly | jq -r '.mandate_id')
# 3. Search with confidence filter
shop search products "USB-C hub" --max-price 40 --in-stock-only
# 4. Validate before committing
shop cart add --sku shopify:xyz --dry-run
# 5. Place order with idempotency key
shop order create --from-cart --mandate-id $MANDATE \
--idempotency-key $(uuidgen) --yes
Handling exit codes
import subprocess, json
result = subprocess.run(["shop", "search", "products", "coffee"], capture_output=True)
data = json.loads(result.stdout)
match result.returncode:
case 0: process(data["results"])
case 3: request_approval(data["detail"]) # mandate violation
case 5: surface_to_human(data["results"]) # low confidence
case 6: retry() # network error, safe to retry
Python versions
Tested on Python 3.9, 3.10, 3.11, 3.12.
License
MIT
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 shop_cli-0.1.0.tar.gz.
File metadata
- Download URL: shop_cli-0.1.0.tar.gz
- Upload date:
- Size: 90.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6c6b8edbfb240758f87581c1e2217c518e9e87bbb2c81fa6c5f25d11f9a55cd
|
|
| MD5 |
2d1f389aff43b021191c5d3a2b2cbc3d
|
|
| BLAKE2b-256 |
5aeae6596e9fbc67dc9b3df6bcc384890ad4f66f5bf05628b2c691032b5ca7a9
|
Provenance
The following attestation bundles were made for shop_cli-0.1.0.tar.gz:
Publisher:
release.yml on antonyevans/shop-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shop_cli-0.1.0.tar.gz -
Subject digest:
b6c6b8edbfb240758f87581c1e2217c518e9e87bbb2c81fa6c5f25d11f9a55cd - Sigstore transparency entry: 1421504032
- Sigstore integration time:
-
Permalink:
antonyevans/shop-cli@c950d0f8e4b7ecca9d1376398361775e84ba2f3a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/antonyevans
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c950d0f8e4b7ecca9d1376398361775e84ba2f3a -
Trigger Event:
push
-
Statement type:
File details
Details for the file shop_cli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: shop_cli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 67.7 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 |
e4368cd5cf970e4b7c7cdd280e2efdc43beac1a97d4c494b174f79f7442f8169
|
|
| MD5 |
18500d23694c161219555c609ca1a685
|
|
| BLAKE2b-256 |
3a7d06f19a0ff8f50a4c4662f4fe315bc850b6dd489e87a82a48117df2fcce75
|
Provenance
The following attestation bundles were made for shop_cli-0.1.0-py3-none-any.whl:
Publisher:
release.yml on antonyevans/shop-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shop_cli-0.1.0-py3-none-any.whl -
Subject digest:
e4368cd5cf970e4b7c7cdd280e2efdc43beac1a97d4c494b174f79f7442f8169 - Sigstore transparency entry: 1421504205
- Sigstore integration time:
-
Permalink:
antonyevans/shop-cli@c950d0f8e4b7ecca9d1376398361775e84ba2f3a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/antonyevans
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c950d0f8e4b7ecca9d1376398361775e84ba2f3a -
Trigger Event:
push
-
Statement type: