by ivorpad
Unofficial, agent-friendly Mercadona shopping CLI (Go) — search products, read prices, build a cart and prepare checkout from the terminal. BYO credentials.
# Add to your Claude Code skills
git clone https://github.com/ivorpad/mercadona-cliGuides for using ai agents skills like mercadona-cli.
mercadona-cli is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by ivorpad. Unofficial, agent-friendly Mercadona shopping CLI (Go) — search products, read prices, build a cart and prepare checkout from the terminal. BYO credentials. It has 292 GitHub stars.
mercadona-cli's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/ivorpad/mercadona-cli" and add it to your Claude Code skills directory (see the Installation section above).
mercadona-cli is primarily written in Go. It is open-source under ivorpad on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh mercadona-cli against similar tools.
No comments yet. Be the first to share your thoughts!
Unlocks once the catalog security scan passes (runs nightly).
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
Unofficial, agent-friendly CLI for tienda.mercadona.es — search the catalog, read
prices, build a cart, and check out. Single static Go binary, no runtime
deps, structured --json output for programmatic/agent use.
Unofficial. Mercadona has no public API. Bring your own credentials; use at a sane request rate. This talks to the same HTTP endpoints the website does.
npm — downloads the prebuilt binary for your platform on install:
npm install -g @ivorpad/mercadona # puts `mercadona` on your PATH
npx @ivorpad/mercadona search queso # …or run without installing
curl (macOS / Linux):
curl -fsSL https://raw.githubusercontent.com/ivorpad/mercadona-cli/main/install.sh | sh
Override with MERCADONA_VERSION=v0.1.0 (pin a tag) or MERCADONA_INSTALL_DIR=/path
(install location; defaults to /usr/local/bin, else ~/.local/bin).
Manual — download a tarball for your OS/arch from the
releases page, extract, and put
mercadona on your PATH.
From source (Go 1.26+) — clone, then:
go build -o mercadona ./cmd/mercadona
(go install <module>@latest isn't wired up yet: the module path is
github.com/ivorjpc/mercadona, which doesn't match the repo URL.)
mercadona search queso # full-text product search
mercadona search --limit 5 --json mayonesa # structured output for agents
mercadona batch -f lista.txt # many terms in ONE request (≈100 items / call)
printf 'queso\ncarne\nmayonesa\n' | mercadona batch -f -
mercadona product 13406 # detail, price, nutrition (when available)
mercadona categories # category tree
mercadona categories --id 112 --json # one category's products (raw JSON)
Common flags: --wh mad1 (warehouse), --lang es, --json — and they can go anywhere after the (sub)command, not just up front.
Data goes to stdout, logs/errors to stderr, exit code 1 on error — friendly to scripts and agents.
mercadona set-postal 28022 # → resolves to warehouse mad1, saves it as the default
Product ids and prices are per-warehouse, and online checkout needs the cart's warehouse to
match your delivery address — so pin it to the warehouse that serves your postal code (no login
needed). Precedence: --wh flag > config.toml [defaults] > built-in mad1. import-har also
auto-detects and saves the warehouse from your session. (Within a city it varies: 28022 → mad1,
28013 → mad3.)
Example:
$ mercadona batch -f lista.txt
• queso → [51110] Queso rallado mozzarella pizza-Roma Hacendado — 1.60€ (8.000€/kg)
• carne → [34157] Carne de pimiento choricero Hacendado — 1.55€ (11.072€/kg)
• mayonesa → [13406] Mayonesa Hacendado — 1.20€ (2.400€/L)
import-har (preferred) / import-curl / login, whoami, cart, checkoutThe API authenticates with a Bearer token (a SimpleJWT). The first sign-in must happen in a
browser (password login needs a Google reCAPTCHA Enterprise token; Google-account users have no
password at all). After that, the refresh token renews the session headlessly, forever —
POST /api/auth/tokens/ {refresh_token} needs no captcha and rotates the token. Verified.
Two login methods, one outcome. However you sign in, the response carries the same durable
refresh_token, so the CLI automates identically:
| Method | Endpoint | Request body | Response |
|---|---|---|---|
| Email + password | POST /api/auth/tokens/ |
{username, password, recaptcha_token} |
{access_token, customer_id, refresh_token} |
| Google sign-in | POST /api/auth/social/google/ |
{id_token, postal_code} |
{access_token, customer_uuid, refresh_token} |
✅ Preferred login method — import-har. One browser login (email or Google), then
headless forever. Export a HAR after signing in and let the CLI pull the refresh token out for you:
# DevTools → Network → ⤓ "Export HAR…" (after you've logged in, by either method), then:
mercadona import-har --file tienda.mercadona.es.har
mercadona whoami # confirms it's authenticated
import-har seeds refresh_token into ~/.mercadona/config.toml (0600) and caches the current
access token + cookie. From then on every 401 token_not_valid triggers an automatic refresh +
retry — no browser, no captcha, unattended. (It reads only auth responses and Bearer/Cookie
headers; the password in the request body is never touched.)
Prefer to do it by hand? Write the token yourself — mercadona set-refresh <token> (or edit
~/.mercadona/config.toml):
[auth]
refresh_token = "<your refresh token>" # the durable, headless-renewable credential
[defaults]
warehouse = "mad1" # or: `mercadona set-postal 28022` resolves + writes this for you
postal_code = "28022"
MERCADONA_TOKEN/MERCADONA_COOKIE/MERCADONA_CUSTOMER (and MERCADONA_USER/MERCADONA_PASS) env vars also work for one-off runs.
Quick one-off (no refresh): mercadona import-curl --file s.txt from a DevTools "Copy as
cURL" of any …/api/customers/… request extracts the Bearer token + cookie + customer id. It has
no refresh token, so it can't auto-renew — re-import when the access token expires.
mercadona login --user … --password …exists but will fail without arecaptcha_token(browser-only), and does nothing for Google accounts; prefer the HAR/refresh-token flow above.
The customer id is read automatically from the token's customer_uuid claim, so
you never pass it (the literal me alias is rejected with 403). Token/cookie/
customer can also come from MERCADONA_TOKEN / MERCADONA_COOKIE /
MERCADONA_CUSTOMER. Secrets are read from env/files, never taken as flags.
mercadona import-har --file tienda.mercadona.es.har # auth (preferred; or import-curl)
mercadona whoami # → "ok — customer id=…" (confirms auth)
mercadona cart get --json # inspect current cart (names, qty × unit_price, total)
mercadona cart add 51110 2 --max 80 # add 2× a product (capped at 80 €)
printf '51110 2\n13406 1\n' | mercadona cart set-many -f - --max 80 # many '<id> <qty>' in ONE write (0 removes)
mercadona cart clear # empty the cart in one write
mercadona checkout create --json # open a checkout → id + default address
mercadona checkout addresses # list saved delivery addresses
mercadona checkout slots --address <id> # delivery slots (they hang off the address, not the checkout)
mercadona checkout get --checkout <id> # show a checkout: total, address, slot
mercadona checkout set-delivery --checkout <id> --address <id> --slot <id>
mercadona checkout submit --checkout <id> --max 80 --yes # IRREVERSIBLE — places the order
cart add adds to the existing quantity; cart set sets the absolute quantity (0 removes). For a
whole basket, cart set-many -f - applies many <id> <qty> lines in a single write — and prices
it first, so --max refuses before writing — while cart clear empties it. All accept --max.
The access token (a SimpleJWT) lasts ~6 weeks; when whoami starts returning
401 token_not_valid, re-import a fresh Copy as cURL (or use login).
When an agent drives the CLI, cap how much it can ever spend. Any cart/checkout over the cap is
refused with a non-zero exit and an error: line — so the agent stops instead of running up a huge
order. Pass it as a flag (which can go anywhere on the line):
mercadona cart add 10379 99 --max 50 # → error: BUDGET EXCEEDED … refusing (exit 1)
mercadona checkout submit --checkout <id> --max 80 --yes # submits only if total ≤ 80 €
Or set it once so every command is capped — MERCADONA_MAX_EUR=100 (env), or in config:
# ~/.mercadona/config.toml
[limits]
max_eur = 100 # refuse any cart/checkout whose total exceeds 100 €
Precedence is flag > env > config; 0/unset = no limit. Enforced on cart add/set/set-many,
checkout create, checkout set-delivery, and — critically — checkout submit, which fails
closed: with a cap set, if it can't read the order total it refuses rather than spend blind.
(With no cap, submit prints a warning.)
The interesting part isn't "an AI does your shopping." It's that one person can now do things that used to need a developer or an analyst: track your own inflation, rank a category by €/kg, catch genuine price drops, build an allergen-safe basket. Every output below is live CLI — and since reads need no login, most are copy-paste.
You think in names; the cart API thinks in ids. batch bridges them in one request — the top
hit per term, with its price:
$ printf 'arroz redondo hacendado\ngambón grande congelado\nmejillón mediterráneo\ntomate triturado hacendado\naceite oliva virgen extra hacendado\n' | mercadona batch -f -
• arroz redondo hacendado → [5044] Arroz redondo Hacendado — 1.20€ (1.200€/kg)
• gambón grande congelado → [60393] Gambón grande congelado — 6.00€ (12.000€/kg)
• mejillón mediterráneo → [85499] Mejillón mediterráneo — 5.80€ (5.800€/kg)
• tomate triturado hacendado → [16044] Tomate triturado Hacendado — 0.55€ (1.375€/kg)
• aceite oliva virgen extra hacendado → [4740] Aceite de oliva virgen extra Hacendado — 4.95€ (4.950€/L)
Put your picks in a basket file — it takes inline # comments, so it reads like the list you
started with, not a wall of ids (paella.txt):
# paella base — 3 personas
5044 1 # Arroz redondo Hacendado
60393 1