Skip to main content

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 addshop 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shop_cli-0.1.0.tar.gz (90.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shop_cli-0.1.0-py3-none-any.whl (67.7 kB view details)

Uploaded Python 3

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

Hashes for shop_cli-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b6c6b8edbfb240758f87581c1e2217c518e9e87bbb2c81fa6c5f25d11f9a55cd
MD5 2d1f389aff43b021191c5d3a2b2cbc3d
BLAKE2b-256 5aeae6596e9fbc67dc9b3df6bcc384890ad4f66f5bf05628b2c691032b5ca7a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for shop_cli-0.1.0.tar.gz:

Publisher: release.yml on antonyevans/shop-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for shop_cli-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e4368cd5cf970e4b7c7cdd280e2efdc43beac1a97d4c494b174f79f7442f8169
MD5 18500d23694c161219555c609ca1a685
BLAKE2b-256 3a7d06f19a0ff8f50a4c4662f4fe315bc850b6dd489e87a82a48117df2fcce75

See more details on using hashes here.

Provenance

The following attestation bundles were made for shop_cli-0.1.0-py3-none-any.whl:

Publisher: release.yml on antonyevans/shop-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page