Skip to content
ShopifyPublic

About

The companion CLI to the Shop SKILL, the companion to the Shop skill, the personal shopping assistant that lets you Search, Buy, Track, Return, and Re-order products through the best product catalog in the world.

Resources

Code of conduct

Contributing

Security policy

Stars

21 stars

Watchers

1 watching

Forks

Repository files navigation

Shop CLI

Shop CLI lets agents search, compare, and buy across millions of Shopify stores through the Shop catalog — and track, return, or reorder past purchases — using the buyer's own Shop account, without ever handling raw card details.

The CLI covers the full shopping loop:

  • Catalog search across all Shop merchants — free text, similar-item (--like-id), or image search. Works signed out.
  • Sign in with Shop via the OAuth device flow, so the agent never sees a password.
  • Agentic checkout over UCP (create → update → complete), paying with Shop Pay or handing off a Finish-in-Shop link.
  • Orders — recent purchases, tracking, order details, returns, and reorders.

It has no native dependencies: the only runtime dependency is commander, so it installs cleanly in sandboxed agent environments where native builds fail.

Documentation:

Tip

If you're wiring this into an agent, start with the bundled skill in skill/SKILL.md — it's the playbook that drives the end-to-end shopping conversation and calls these commands under the hood. The hosted copy lives at https://shop.app/skill.md.

Installation

Requires Node.js >= 20.

pnpm add --global @shopify/shop-cli

Or with npm:

npm install --global @shopify/shop-cli

Upgrade with @latest; uninstall with pnpm rm -g @shopify/shop-cli (or npm rm -g @shopify/shop-cli).

Use with agents

The package bundles the Shop skill (skill/SKILL.md plus references) — the agent-facing instructions for the full flow: search etiquette, per-channel message formatting, sign-in choreography, and the checkout confirmation gate.

Output defaults to compact markdown; all commands accept --format md|json (auth and checkout always emit JSON). Keep --limit small on searches — large JSON pages burn tokens.

Quickstart

Check auth, sign in

shop auth status          # {"authenticated": false}
shop auth device-code     # prints a sign-in URL — show it to the user, then STOP
shop auth poll            # after the user approves, exchanges and stores tokens

Signing in is optional for search, required for checkout and orders.

Search

Always pass the buyer's country and currency; default --ships-to to the same country:

shop search "trail running shoes" --country US --currency USD --ships-to US --limit 8
shop search "tshirt" --country US --color White --size M
shop search --like-id gid://shopify/p/abc123 --ships-to US   # similar items
shop search --image ./photo.jpg --country US                 # visual search (jpeg/png/webp/avif/heic, ~3 MB max)

Prices are minor units (--max-price 15000 = $150.00).

Inspect a product

shop catalog get-product gid://shopify/p/abc123
shop catalog lookup gid://shopify/ProductVariant/50362300006715

get-product is where variant-level checkout_url links come from — never reconstruct one.

Checkout

shop checkout create --shop-domain example.myshopify.com \
  --variant-id gid://shopify/ProductVariant/123 --quantity 1 --country US --checkout-stdin

shop checkout complete --shop-domain example.myshopify.com \
  --checkout-id <id> --checkout-stdin --confirm --idempotency-key <key>

--confirm is a deliberate, separate step: verify item, variant, quantity, address, shipping, and total with the user first, and surface every messages[] warning verbatim (final sale, age restricted, Prop 65). Use a fresh idempotency key per distinct purchase intent. Only a returned status of completed means the purchase went through.

Orders

shop orders search --type recent
shop orders search --type tracking --query "shoes"
shop orders search --type reorder --query "coffee"

Advanced

Authentication

shop auth status       # check session (validates + auto-refreshes)
shop auth device-code  # phase 1: request device code, print verification URL
shop auth poll         # phase 2: poll token endpoint, store tokens
shop auth budget       # remaining delegated-spend budget, if configured
shop auth logout       # clear all stored credentials

The device flow is split into two commands so agents can return control to the user between turns: device-code stashes the pending device_code in the secret store; poll reads it back and exchanges it. Poll handles authorization_pending, slow_down, expired_token, and access_denied.

Tokens are stored under the service shop-agent (accounts access_token, refresh_token, device_id, country). Short-lived checkout JWTs and catalog tokens are minted on demand and kept in memory only.

The checkout lifecycle

A checkout moves through create → (update) → complete:

  • create returns a checkout with totals, fulfillment options, messages[], and — if the buyer has Shop Pay set up with a delegated budget — payment.instruments.
  • update patches only the fields you pass (email, address, method) using the checkout id from create.
  • complete echoes the instrument from the current create/update response verbatim (selected: true, credential.token = the instrument's own id). Never fabricate instrument ids.

If a checkout returns no payment instruments, don't retry: hand off the continue_url as a Finish-in-Shop link. If the merchant endpoint returns auth or permission errors, fall back to the variant checkout_url or product URL.

Payment budget (delegated spending)

Buyers can pre-authorize agent spending in Shop → Settings → Connections. shop auth budget reports the limit and remaining amount in minor units (5750 = $57.50). Empty = no budget configured; 0 = exhausted. The wallet token itself is never printed or persisted — the CLI only reports availability and remaining amount, and the user can revoke it at any time.

A budget exists but checkout returns no instruments? The merchant doesn't accept Shop Pay — hand off continue_url; don't re-prompt the user to set up a budget they already have.

Secret storage

Backend resolution order:

  1. SHOP_CLI_SECRET_BACKEND env override (keychain | secret-tool | file)
  2. macOS → Keychain (security CLI, always present on darwin)
  3. Linux with a working secret service → secret-tool
  4. Otherwise → JSON file at SHOP_CLI_SECRETS_PATH or ~/.shop-cli/secrets.json

The file store creates its directory 0700, writes atomically (temp file + rename), and keeps the file 0600. It holds the OAuth access/refresh tokens — treat it like an SSH key. On shared machines prefer a real keychain backend or --memory-store.

Automatic detection requires a working Secret Service, not just an installed secret-tool binary. A clean lookup miss still selects the keyring; connection errors or a probe exceeding five seconds select the file fallback. Explicit backend overrides remain authoritative. Backend selection is recalculated for each process, so consistently headless sessions can reuse the file store without an override. Changing the available service does not migrate credentials between backends; use a consistent SHOP_CLI_SECRET_BACKEND when intentionally selecting one.

SHOP_CLI_SECRET_BACKEND=file shop auth status   # force + acknowledge the file store
shop --memory-store auth status                 # nothing persisted (per-process)

Output formats

--format md (default) renders compact markdown; --format json returns full payloads. Auth and checkout commands always emit JSON; orders always emit markdown (the API returns a text summary, not JSON). Search's markdown omits per-variant checkout links to keep lists small — use catalog get-product for those.

Environment variables

Variable Effect
SHOP_CLI_SECRET_BACKEND Force a secret backend: keychain, secret-tool, or file
SHOP_CLI_SECRETS_PATH File-store location (default ~/.shop-cli/secrets.json)

Global flags: --country <ISO2> (context signal; persist with shop config set-country), --profile-url <url> (override the UCP agent profile), --memory-store, --format md|json.

Integrating into agents

Give your agent the bundled skill (skill/SKILL.md) or point it at https://shop.app/skill.md. The skill encodes the rules that matter for real money: sign-in choreography, the confirm-before-complete gate, verbatim warning disclosure, prompt-injection defenses, and per-channel formatting. Agents that can't install the CLI at all can follow the raw API reference in skill/references/direct-api.md — same endpoints, no install.

Personal-use limits

This CLI is designed for individual end users, for personal use. The Shopify servers it connects to have usage restrictions. Building commercial services, resale platforms, aggregators, or anything that provides third parties with programmatic access to Shopify's catalog, checkout, delegated payments, or aggregated user data is prohibited.

See https://help.shop.app/en/shop/shopping/personal-agents for accepted and prohibited use.

Development

pnpm install
pnpm typecheck
pnpm test
pnpm build           # tsc → dist/, marks dist/bin.js executable
pnpm shop -- --help

The secret store lives in src/storage.ts (PortableSecretStore) — backend resolution is documented under Secret storage.

Contributing

Bug reports and pull requests are welcome. Read CONTRIBUTING.md and CODE_OF_CONDUCT.md before getting started.

License

MIT. See LICENSE.md.

About

The companion CLI to the Shop SKILL, the companion to the Shop skill, the personal shopping assistant that lets you Search, Buy, Track, Return, and Re-order products through the best product catalog in the world.

Resources

Code of conduct

Contributing

Security policy

Stars

21 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages