New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

grocery-delivery-mcp

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grocery-delivery-mcp

MCP server + CLI for mein-aldi.de (ALDI Süd grocery delivery): product search, price & availability, categories. Public API, cached and rate-limited. Unofficial, unaffiliated.

latest
Source
npmnpm
Version
0.2.0
Version published
Weekly downloads
34
-71.9%
Maintainers
1
Weekly downloads
 
Created
Source

grocery-delivery-mcp

grocery-delivery-mcp

npm MCP Registry License

Ask your AI assistant "is oat milk in stock for delivery?" — and get a real answer, with today's price.

This is an MCP server, CLI, and library for mein-aldi.de, ALDI Süd's grocery delivery platform. It lets a language model (or you, from a terminal) search the catalog, check price and availability, and browse categories.

Under the hood the catalog talks to the public api.mein-aldi.de JSON API — no login, no account, no scraping tricks. Search, price, and availability are all publicly readable. Every request is rate-limited, retried, and circuit-broken to stay polite to an undocumented API, and responses are cached (in memory and on disk) so repeat questions are instant. There's also an opt-in cart prefill for your own account — the one part that logs in.

Unofficial and unaffiliated with ALDI. It uses an undocumented API that may change or break without notice. Prices and availability are guidance, not a real-time inventory guarantee. See COMPLIANCE.md for exactly how it accesses the API responsibly — robots.txt, terms, and rate-limit posture.

Add it to your LLM

No install, no API key, no configuration. Point any MCP client at the package and start asking.

Claude Code — one command:

claude mcp add grocery-delivery -- npx -y grocery-delivery-mcp

Claude Desktop, Cursor, or any other MCP client — add this to your MCP config (e.g. claude_desktop_config.json):

{
  "mcpServers": {
    "grocery-delivery": {
      "command": "npx",
      "args": ["-y", "grocery-delivery-mcp"]
    }
  }
}

Restart the client and ask: "Is oat milk in stock for delivery on ALDI, and what does it cost?" That's it. 🎉

Or find it in the registry. It's published in the official MCP Registry as io.github.RayNCooper/grocery-delivery-mcp, so registry-aware clients can discover and install it by name.

Prefer the terminal or want to embed it in your own code? See the Quickstart.

Contents

What you can do with it

Connected to an MCP client like Claude Desktop, your assistant can answer questions like:

  • "Is bio milk available for delivery right now, and what does it cost?"
  • "Find me the five cheapest options for pasta."
  • "What's on sale at ALDI right now?"
  • "How much fat and sugar are in these chips, and what are the allergens?"
  • "What product categories are available?"

Straight from a terminal, the same thing:

grocery-delivery search "milch" --limit 5      # search the catalog
grocery-delivery check "bio bananen"           # is the top match in stock?
grocery-delivery offers --sort price_asc       # current deals, cheapest first
grocery-delivery product 434365                # full detail: nutrition, allergens
grocery-delivery categories --depth 2          # browse the category tree

Or from your own code, as a library — see Ways to use it.

Quickstart

Wiring it into an LLM is the one-liner above. This is the terminal / CLI path. For the read-only catalog (steps 1–3) you only need Node ≥ 22 — nothing to clone, build, or configure; the store is baked in (see Limitations). Cart prefill (step 4) is the one exception: it's authenticated and runs from a clone.

1. Install

npm install -g grocery-delivery-mcp

That puts the grocery-delivery command (and the grocery-delivery-mcp server binary) on your PATH.

2. Check it works

grocery-delivery doctor
# Checking https://api.mein-aldi.de (service point ADG045_1) ...
# ✓ categories: 32 roots
# ✓ search "milch": 25 hits
# ✓ The mein-aldi.de API is live and serving data — you're good to go.

doctor is a connectivity check — it exits non-zero if the API returns nothing, so scripts can gate on it.

3. Use it

grocery-delivery search "kaffee" --limit 5
grocery-delivery check "bio bananen"
grocery-delivery offers --sort price_asc --limit 10   # cheapest current deals
grocery-delivery product 434365                       # nutrition, ingredients, …
grocery-delivery categories --depth 2

4. Fill your own cart

Your assistant can also prefill your own mein-aldi.de cart — via two tools: connect_aldi_account (opens ALDI's login in a browser, once) and prefill_cart (adds items). You still check out, pay, and pick a slot yourself; it never places an order.

Run the server from a clone (the cart tools aren't in the published npm build yet), plus a browser engine for the login:

git clone https://github.com/RayNCooper/grocery-delivery-mcp.git
cd grocery-delivery-mcp && pnpm install && pnpm build
npx playwright install chromium          # the browser used for the ALDI login

Point your MCP client at it — no session file, no extra config:

{
  "mcpServers": {
    "grocery-delivery": {
      "command": "pnpm",
      "args": ["-C", "/abs/path/to/grocery-delivery-mcp", "start"]
    }
  }
}

Then just chat: "Add 2× oat milk, bananas, and coffee to my ALDI cart." The first time, the assistant offers to connect — a browser window opens on the ALDI login, you sign in once, and it's remembered (and refreshed automatically after). Your cart fills; open mein-aldi.de to finish. Details + compliance scope: docs/CART-PREFILL.md.

See Ways to use it for the full command list, the HTTP transport, and the library API.

Ways to use it

One shared core, consumed three ways.

Local MCP server (stdio)

For Claude Desktop, Cursor, and other desktop MCP clients. Add it to your LLM shows the npx config, which needs no install and is the recommended setup. If you've installed the package globally, you can run the server directly instead:

grocery-delivery-mcp        # the MCP server (stdio) — same as: grocery-delivery serve

One-click install: a prebuilt MCPB bundle (.mcpb) installs into Claude Desktop with a double-click — no configuration — built from manifest.json and attached to releases.

Remote MCP server (Streamable HTTP)

For networked or hosted use.

grocery-delivery serve --http
# → HTTP server listening on http://127.0.0.1:3000/mcp

Point a Streamable-HTTP MCP client at http://127.0.0.1:3000/mcp. There's also a GET /health endpoint, and sessions are keyed by the Mcp-Session-Id header.

Self-host with Docker: docker compose up (see docker-compose.yml and Dockerfile) runs your own single-tenant instance on your own IP. It's deliberately not a shared multi-user service; COMPLIANCE.md explains why.

A note on security: the server binds to 127.0.0.1 by default and enforces DNS-rebinding protection (allowedHosts). It has no built-in auth — if you expose it beyond localhost (ALDI_HTTP_HOST=0.0.0.0), put it behind a reverse proxy that adds auth and TLS.

CLI & library

Install globally (npm install -g grocery-delivery-mcp) for the grocery-delivery command, or run any command ad-hoc with npx -p grocery-delivery-mcp grocery-delivery <cmd>. Every command supports --json for machine-readable output and --force-refresh to bypass the cache.

grocery-delivery search "milch" --limit 5
grocery-delivery search "joghurt" --diet Vegan --sort price_asc   # filter + sort
grocery-delivery search "wasser" --limit 10 --offset 10          # page 2
grocery-delivery stock 229396 000000000000228798      # availability + price by SKU
grocery-delivery check "bio bananen"                  # is the top match available?
grocery-delivery product 434365                       # full detail: nutrition, allergens
grocery-delivery offers --sort price_asc --limit 10   # current deals, cheapest first
grocery-delivery categories --depth 2
grocery-delivery browse 19000000 --limit 20 --brand MILSANI      # filter a category
grocery-delivery status                               # cache / breaker / rate-limit
grocery-delivery doctor                               # health check (API reachable?)
grocery-delivery <cmd> --json                         # machine-readable output

search and browse accept --sort (relevance|price_asc|price_desc|name_asc|name_desc), server-side --offset paging, and the facet filters --label (Bio|Neu|Aktion), --diet, --brand, and --country. Text and --json output both include the available facets (brands, diet types, labels, with counts) so you can see how to refine.

Use the same core from your own code — npm install grocery-delivery-mcp, then:

import { createService, loadConfig } from "grocery-delivery-mcp";

const service = createService(loadConfig(process.env));
const result = await service.search({ query: "milch", limit: 5 });
console.log(result.products, result.cacheState);

Tools & resources

The MCP server exposes these tools:

ToolWhat it does
search_productsFree-text search → products + facets; label/diet/brand/country filters, sort, paging
get_productsExact lookup by SKU(s) — "check stock" for known items
get_product_detailsFull detail by SKU: nutrition, ingredients, allergens, storage, origin
check_availabilityOne-shot "is X available right now?" (search → top match → live check)
list_offersCurrent promotional products ("Aktion") — the "what's on sale" list
list_categoriesBrowse the category tree (with numeric keys)
browse_categoryList products in a category — same filters, sort, and paging as search
get_delivery_slotsDelivery time-slots — experimental (see Limitations)
get_service_statusDiagnostics: cache, breaker, rate-limit — plus store metadata from /v1/stores
connect_aldi_accountConnect your ALDI account (opt-in) — opens ALDI's login in a browser so you sign in once; remembers the session for cart prefill — see Fill your own cart
prefill_cartPrefill your own cart (authenticated, opt-in) — add products by name/SKU; you still check out. Prompts to connect first if needed

And these resources: aldi://categories (the full tree), aldi://product/{sku} (price & availability), aldi://product-details/{sku} (full detail), and aldi://offers (current deals).

Every returned product carries the usual price and availability plus depositDisplay (Pfand), sizeDisplay (pack size), labels (badges like Bio / Aktion), and deepLink (the mein-aldi.de product page). Every result carries a cacheState (fresh / stale / miss / bypass / degraded) and a fetchedAt timestamp, so a model always knows how fresh a price is. Pass force_refresh: true (or --force-refresh) when you need an authoritative, up-to-the-second read.

Configuration

Everything is set through environment variables, and every default is sensible — out of the box, there's nothing you need to set. The full list with defaults lives in .env.example. The ones you're most likely to touch:

EnvDefaultMeaning
ALDI_SERVICE_TYPEdeliverydelivery (verified), pickup, instore
ALDI_CACHE_DIROS cache dirWhere the on-disk cache lives
ALDI_CACHE_DISABLEDfalseTurn the cache off
ALDI_TTL_PRODUCTS_MS300000Price/availability freshness (5 min)
ALDI_TTL_SEARCH_MS600000Search freshness (10 min)
ALDI_TTL_CATEGORY_MS86400000Category tree freshness (24 h)
ALDI_RATE_MIN_INTERVAL_MS250Min spacing between requests (~4 rps)
ALDI_HTTP_HOST / ALDI_HTTP_PORT127.0.0.1 / 3000HTTP transport bind
ALDI_LOG_LEVELinfosilent/error/warn/info/debug (stderr)

How it stays polite and fast

It treats an undocumented, unowned API with care, and caches aggressively so it rarely has to ask twice:

  • Rate limiting — a minimum interval plus jitter between request starts, with capped concurrency.
  • Retries — exponential backoff (equal jitter) on 429/5xx/network/timeout, honoring Retry-After; fails fast on other 4xx.
  • Single-flight — identical concurrent requests share one underlying fetch.
  • Circuit breaker — after repeated failures it backs off, and tools degrade to best-effort/empty results (degraded: true) instead of erroring.
  • Cache — memory + disk, per-resource TTLs, and stale-while-revalidate (serve stale instantly, refresh in the background). Delivery slots are never served stale.

Limitations

  • Delivery slots (get_delivery_slots) aren't implemented yet — no public endpoint is confirmed. The tool returns supported: false with a reason. See scripts/slots-probe.mjs and Development.
  • Account features are limited to cart prefill (opt-in). The catalog side is read-only and never logs in. A separate, opt-in flow prefills your own cart — you authenticate once, and it never checks out, pays, or places an order (see Fill your own cart). Checkout, payment, and order history stay out of scope. COMPLIANCE.md covers the access posture.
  • One store, baked in. mein-aldi.de delivery is a single-store pilot: the API serves exactly one live merchant (ADG045_1), identical for every address (the postal code is ignored, and no other store resolves). So there's nothing to select — the service point is hardcoded and there's no ALDI_SERVICE_POINT setting. If ALDI expands delivery to multiple stores, this becomes configurable again.

Development

Working on the project itself? Build from source — this needs pnpm:

git clone https://github.com/RayNCooper/grocery-delivery-mcp.git
cd grocery-delivery-mcp
pnpm install
pnpm build               # compiles TypeScript → dist/

Then the usual loop:

pnpm dev                 # tsx watch src/stdio.ts
pnpm dev:http            # tsx watch src/http.ts
pnpm typecheck
pnpm test                # unit tests (no network)
pnpm test:integration    # live API, gated by ALDI_INTEGRATION=1, serial + rate-limited
pnpm lint
pnpm format

# Phase 2: discover the delivery-slots endpoint (read-only probe)
node scripts/slots-probe.mjs

Integration tests hit the real API and are gated behind ALDI_INTEGRATION=1 — keep them out of hot CI loops to avoid hammering ALDI. Architecture notes live in docs/ARCHITECTURE.md, and contributions are welcome — see CONTRIBUTING.md.

Releasing

Releases are driven by the VERSION file. Bump it, and merging to main triggers .github/workflows/publish.yml, which stamps that version into package.json and server.json, publishes the package to npm, and publishes the entry to the MCP Registry via mcp-publisher. Both artifacts always match VERSION, so they can't drift.

# from the /ship flow, or by hand:
echo "0.2.0" > VERSION   # (also bump package.json / CHANGELOG)
git commit -am "release: v0.2.0" && git push   # merge to main → publish

The job is idempotent — if the version is already on npm it skips cleanly, so re-runs stay green. No secrets are required: npm uses trusted publishing (OIDC) and the MCP Registry uses GitHub OIDC — both ride the workflow's id-token: write permission, and npm provenance is generated automatically. The one prerequisite is that the npm trusted publisher is configured on npmjs.com to point at this repo and the publish.yml workflow.

License

GPL-3.0-or-later. See LICENSE.

Keywords

mcp

FAQs

Package last updated on 10 Jul 2026

Related posts