Amazon Fresh from your terminal.
A fast, local-first execution layer for people, scripts, and shopping agents.
fresh searches Amazon Fresh, manages your cart, chooses fulfillment, previews the real delivered total, and places or cancels orders—without turning your Amazon password into an environment variable.
It speaks JSON by default, looks great with --pretty, and ships its own AI-agent skill inside the binary.
fresh search --limit 5 "eggs"
fresh cart add B0EXAMPLE --expected-price 4.99 --source-url 'https://…'
fresh schedule list
fresh checkout preview --max-total 75 --tip 0Warning
fresh is experimental and uses undocumented Amazon interfaces that may change without notice. It is not affiliated with or endorsed by Amazon. Use it only with accounts and orders you are authorized to manage.
| What you get | |
|---|---|
| Agent-native | Stable JSON on stdout, errors on stderr, and an embedded skill via fresh skill |
| Human when you want it | Polished output with --pretty; guided flows with --interactive |
| Passwordless to the CLI | Amazon device authorization—your password and MFA response never enter fresh |
| Hard purchase rails | Price guards, spending ceilings, expiring checkout tokens, and exact confirmation phrases |
| Small by design | One Go binary, direct HTTP for normal operation, no always-on browser |
Requires Go 1.26.5+.
go install github.com/woke/fresh-cli/cmd/fresh@latest
fresh auth loginIf fresh is not found after installation, add Go's binary directory to your
PATH:
export PATH="$(go env GOPATH)/bin:$PATH"To install from a checkout instead, run go install ./cmd/fresh from the
repository root.
Prebuilt archives and SHA-256 checksums are available on the releases page.
Amazon displays a device code and approval page. Once approved, fresh verifies the resulting session before saving it.
Now shop:
# Find the thing
fresh --pretty search --limit 10 "chicken breast"
# Add the exact listing at the price you observed
fresh cart add <asin> \
--expected-price <price> \
--source-url '<url-from-search>'
# Pick delivery and review every dollar
fresh --interactive schedule
fresh --pretty checkout preview --max-total 100 --tip 5JSON is always the automation contract:
fresh search --limit 20 "tomatoes" | jq
fresh cart list | jq
fresh orders list | jqThe default is one JSON value on stdout. No decoration, no hidden prompts.
fresh cart list
fresh checkout preview --max-total 80Put --pretty before any command for styled terminal output:
fresh --pretty search "mushrooms"
fresh --pretty cart list
fresh --pretty orders listUse Charm-powered prompts for the decisions that benefit from a human eye:
fresh --interactive # choose a workflow
fresh --interactive address
fresh --interactive schedule
fresh --interactive substitutions
fresh --interactive checkoutInteractive checkout still requires the exact phrase PLACE ORDER. It only activates in a real terminal. Set NO_COLOR=1 to disable ANSI color.
Adding an item binds the action to the exact ASIN, observed price, and Fresh result URL. If the live price changes, fresh rejects the add instead of quietly charging the new amount.
Checkout is deliberately two-step:
checkout previewrefreshes checkout, masks sensitive details, checks your spending ceiling, and creates a five-minute local token.checkout placerequires that token, the same ceiling, and the exact phrasePLACE ORDER.
The token is bound to the cart, address, delivery window, payment method, tip, displayed total, and maximum total. Change any of them and it stops working. Cancellation has its own CANCEL ORDER gate.
fresh never retries an ambiguous placement or cancellation response. Check fresh orders list before deciding what happened.
The canonical shopping skill lives inside the binary—no extra download, version mismatch, or mystery prompt:
fresh skill > SKILL.mdThe skill leaves taste, budgeting, nutrition, and product judgment to the agent. The CLI owns mechanics: authentication, price checks, cart mutations, checkout state, and confirmation gates.
Show every command
fresh --pretty <command>
fresh --interactive [address|schedule|substitutions|checkout]
fresh auth login
fresh auth refresh
fresh auth status
fresh auth logout
fresh search [--limit N] <query>
fresh cart list
fresh cart add <asin> --expected-price <amount> --source-url <search-result-url>
fresh cart quantity <asin-or-item-id> <quantity>
fresh cart remove <asin-or-item-id>
fresh address list
fresh address use <index-or-id>
fresh substitutions list
fresh substitutions set <index-or-asin> <similar|none>
fresh schedule list
fresh schedule select <index>
fresh checkout preview --max-total <amount> [--tip <amount>]
fresh checkout place --token <token> --confirm 'PLACE ORDER' --max-total <amount>
fresh orders list
fresh orders cancel <index-or-order-id> --confirm 'CANCEL ORDER'
fresh skill
fresh doctor
fresh version
On macOS, private state lives in:
~/Library/Application Support/fresh-cli/
├── session.json # amazon.com web cookies
└── device-auth.json # renewable device credential
Files are written atomically with owner-only permissions. Treat this directory like a logged-in browser profile. fresh auth logout removes the local session.
The CLI does not print cookies, CSRF tokens, full addresses, payment details, checkout action URLs, or authenticated HTML.
go test ./...
go test -race ./...
go vet ./...
go run honnef.co/go/tools/cmd/staticcheck@latest ./...Live transport checks are opt-in:
go run ./cmd/fresh doctor
FRESH_LIVE_CLOAK=1 go test ./internal/amazon -run LiveCaptured HARs, sessions, and local binaries are ignored and must never be committed.
Give your grocery agent hands—not your password.
