Skip to main content
Glama
igorsafonov-gif

Ametller Origen

README.md
# Ametller Origen — Claude Desktop shopping extension

Shop your [Ametller Origen](https://www.ametllerorigen.com/ca/online) online groceries by talking to Claude.
The extension drives **your own** authenticated Ametller Origen session: it browses the catalog, reads your
purchase history, and adds, changes, or removes items in your **real cart** so you and Claude fill it together.

**You stay in control of payment.** There is no checkout or payment tool, by design — Claude fills the cart and
you review and pay on the Ametller Origen site, where Strong Customer Authentication (SCA) happens. Sign in once
through a browser window (handling any 2FA); the session is stored locally on your machine and never leaves it.

It installs as a **Claude Desktop extension** (described by `manifest.json`) — load it **unpacked** via
developer mode (see [Install](#install); the packed `.mcpb` doesn't install reliably). It can also run as a
plain local MCP server.

> Independent project. Not affiliated with, endorsed by, or sponsored by Ametller Origen.

## How it works

The `/ca/online` store is a headless **Salesforce Commerce Cloud** (PWA Kit) storefront, so the extension talks
to the documented **SCAPI** shopper APIs, authenticated with a **SLAS** token.

- **Auth** — a headed browser login (`playwright-core` driving your installed Chrome) lets you sign in; the
  extension captures the registered SLAS token (access + refresh + customer id) straight from the
  `/oauth2/token` response and saves it to `~/.ametller/session.json`. Access tokens last ~30 min and are
  **refreshed silently** from the refresh token, so you only sign in about every ~90 days.
- **Catalog** — `shopper-search` (product search) and `shopper-products` (product detail).
- **Cart** — `shopper-baskets` (your real basket: add / set quantity / remove). Every mutation returns the
  updated basket, so there are no redundant round-trips.
- **Orders** — `shopper-customers` order history, used by reorder / "buy again".

Storefront config (public, read from the page): `siteId=ametller`, `org=f_ecom_blzv_prd`,
`shortCode=4jppt37a`, API base `https://4jppt37a.api.commercecloud.salesforce.com`.

## Tools

All tools are prefixed with `ametller_` so they never collide with another grocery extension's tools
(e.g. a Mercadona one) when both are installed in Claude Desktop at the same time.

| Tool | What it does |
|---|---|
| `ametller_get_shopping_guide` | The shopping playbook — read first. |
| `ametller_auth_status` | Whether the session is valid. |
| `ametller_login` | Open a browser to sign in (handles 2FA); saves the session. |
| `ametller_search_products` | Find products + ids (Catalan works best). |
| `ametller_get_product` | Details for one product. |
| `ametller_get_cart` | The current real cart. |
| `ametller_get_purchase_history` | Past orders (date, total, status, count). |
| `ametller_get_order_items` | Items in a past order (no changes). |
| `ametller_add_to_cart` / `ametller_set_quantity` / `ametller_remove_from_cart` | Mutate the real cart (reversible). |
| `ametller_reorder_order` | Add a whole past order to the cart ("buy again"). |

No `checkout` / `pay` tool — ever.

> Deferred: a "my regulars" suggestion and delivery-slot lookup. Ametller fulfils via Instaleap, so slots live
> in a separate system, not SCAPI — to be added after recon.

## Install

> **Install it unpacked (developer mode).** This is the recommended and reliable path — the packed `.mcpb`
> does not currently install cleanly in Claude Desktop, so use the unpacked folder below.

### As an unpacked Claude Desktop extension (recommended)

Load this folder directly. The build output (`dist/`) and runtime dependency (`node_modules/playwright-core`)
are git-ignored, so after cloning you must produce them first:

```bash
npm install        # installs playwright-core into node_modules/
npm run build      # writes dist/server.mjs (inlines the shopping guide)
```

The folder then contains everything an unpacked extension needs:

```
manifest.json
icon.png
dist/server.mjs
node_modules/playwright-core
```

In Claude Desktop: **Settings → Extensions → Advanced settings → "Install unpacked extension…"**, then select
this folder (the one containing `manifest.json`). It loads as the "Ametller Origen" extension; run the
`ametller_login` tool once, then try *"show me milk options"* (expect a photo-grid artifact) and *"add 2 to my cart"*.

Requirements: **Node ≥ 18** on your `PATH` and **Google Chrome** installed (the `ametller_login` tool opens it).
Rebuild (`npm run build`) after changing anything under `src/`, then reload the extension.

### As a local MCP server

If you don't want a Claude Desktop extension at all, run it as a plain MCP server:

```bash
npm install && npm run build
node dist/server.mjs
```

Point any MCP client at `node /path/to/dist/server.mjs` (set `AMETLLER_BROWSER_CHANNEL=chrome`).

### As a packed Claude Desktop extension (`.mcpb`)

> ⚠️ Not currently recommended — Claude Desktop does not install the packed bundle reliably. Use the unpacked
> path above instead. Kept here for completeness.

```bash
npm run pack       # builds dist/, then packs ametller-origen.mcpb via @anthropic-ai/mcpb
```

Then open the resulting `.mcpb` with Claude Desktop. (The bundle includes `dist/` and the production
`node_modules`, i.e. `playwright-core`.)

## Development

```bash
npm install
npm run spike      # guest read + basket round-trip against the live API (no login)
npm run login      # headed browser login -> ~/.ametller/session.json
npm run whoami     # verify the registered session (cart + orders)
npm run build      # esbuild bundle -> dist/server.mjs (inlines the shopping guide)
npm run test:mcp   # drive the built server over MCP, incl. a real cart round-trip
npm run icon       # regenerate the placeholder icon (icon.png)
npm run pack       # build -> ametller-unpacked/ + ametller-origen.mcpb + zip
```

Layout:

```
src/
  server.mjs          MCP server (the 12 tools)
  ametller/api.mjs    SCAPI client + compact mappers
  auth/slas.mjs       SLAS: guest PKCE token, refresh, JWT status
  auth/login.mjs      headed-browser token harvest
  auth/store.mjs      load the saved session
  shopping-guide.md   shopping playbook (bundled into the server)
scripts/              spike / login / whoami / test-mcp / make-icon / pack
```

## Privacy

The session token lives only in `~/.ametller/session.json` on your machine. The packaged bundle contains
only the server, icon, manifest, and `playwright-core` — no credentials. All API calls go directly from your
Mac to Salesforce Commerce.