Profile
Back to NewsBack
GitHub Trending 10 min
Reader Mode
lewpgs/migros-mcp: MCP server for Migros Switzerland product data - search products, nutrition info, store locations, and promotions

lewpgs/migros-mcp: MCP server for Migros Switzerland product data - search products, nutrition info, store locations, and promotions

13 hours ago

migros-mcp

Search Migros products and (optionally) manage your basket, addresses, and orders through Claude.

Important
This is not affiliated with Migros in any way.
It uses publicly accessible API endpoints. There is no official Migros API.
It can break at any time if Migros changes their endpoints.
Use at your own risk.

What you can do

Without an account (anonymous access):

  • "Search Migros for protein bars"
  • "What's the nutrition info for this Migros product?"
  • "Find Migros stores near Zurich"
  • "What promotions does Migros have right now?"
  • "Compare the protein content of these two products"
  • "Find me a recipe for risotto and add the ingredients to my basket" (combines anonymous recipe search with authenticated cart write)
With your Migros account (optional):
  • "What's currently in my Migros basket?"
  • "Add 2 liters of milk to my basket"
  • "Remove the bananas from my basket"
  • "Where will my order be delivered to?"
  • "Show me my last 5 Migros orders"
  • "Give me the link to finish my checkout"
  • "How much did I spend at Migros last month?"
  • "What was on my last in-store receipt?"
  • "Which Cumulus coupons do I have right now?"
  • "How many Cumulus points do I have?"
The basket and order tools require your Migros account credentials. They're optional. If you skip them at install, the anonymous tools still work.

Install

Claude Desktop (recommended)

  1. Download migros-mcp.mcpb
  2. Install it:
macOS: Double-click the file, or drag and drop it onto the Claude Desktop app icon

Windows: In Claude Desktop, go to File > Settings > Extensions > Advanced Settings > Install Extension and select the file

  1. Optional: enter your Migros email, password, and TOTP secret if you want the basket/order tools. Leave all three blank for anonymous access only. Credentials are stored in your OS keychain by Claude Desktop.
About the TOTP secret. This is NOT the rotating 6-digit code your authenticator app shows. It is the static base32 seed given to you (or scanned via QR code) when you originally set up the authenticator. It's a one-time value, typically ~32 characters of A-Z2-7 (for example: JBSWY3DPEHPK3PXP3PXP3PXP3PXP3PXP), and it doesn't change every 30 seconds.

How to find it:

- If you saved it during enrollment: copy it from your password manager. In 1Password / Bitwarden / Proton Pass, open the Migros entry, edit the OTP field, choose "View one-time password secret" (or similar). The string after secret= is what you want. - If you didn't save it: Migros only shows the seed during initial 2FA setup, on the same screen as the QR code, in a box labeled "Or enter the following key in the authenticator app:". Once enrollment completes, the seed is gone for good.

To recover it: in Migros account settings, remove your existing 2FA, then set it up again. The new setup screen will show the new seed text below the QR code. Copy it before completing enrollment, and re-add the new entry to your authenticator app.

Leave the field blank entirely if your Migros account doesn't have 2FA enabled.

Rather not store the seed? Leave the TOTP field blank. When Claude needs to log in, it asks you for the current 6-digit code from your authenticator app (or reads it from a password manager it has access to) and passes it to the authenticate tool. The code is used for that one login and is not stored.

That's it.


Advanced setup

These methods require Node.js 18+.

Claude Code

# Anonymous (search/browse only)
claude mcp add migros -- npx -y migros-mcp

With your account (basket + orders)

claude mcp add migros \ -e [email protected] \ -e MIGROS_PASSWORD='your-password' \ -e MIGROS_TOTP_SECRET=ABCDEFGHIJKLMNOP \ -- npx -y migros-mcp

Claude Desktop (manual) / Cursor

Add to your config:

  • Claude Desktop: claude_desktop_config.json
  • Cursor: .cursor/mcp.json (project) or ~/.cursor/mcp.json (global)
{
  "mcpServers": {
    "migros": {
      "command": "npx",
      "args": ["-y", "migros-mcp"],
      "env": {
        "MIGROS_EMAIL": "[email protected]",
        "MIGROS_PASSWORD": "your-password",
        "MIGROS_TOTP_SECRET": "ABCDEFGHIJKLMNOP"
      }
    }
  }
}

The env block is optional. Omit it to use anonymous tools only. Leave out MIGROS_TOTP_SECRET if you'd rather give Claude the current 6-digit code when it needs to log in (see authenticate below).

Test connection

npx migros-mcp                                                # anonymous
MIGROS_EMAIL=... MIGROS_PASSWORD=... MIGROS_TOTP_SECRET=... npx migros-mcp   # authenticated

Updating

The recommended install commands above use npx -y migros-mcp without pinning a version, so you auto-receive new releases. Recent npm versions check for the newest version each time npx starts, so an update lands the next time your MCP host starts the server. If it seems stuck on an old version, run npm cache clean --force and restart the host.

If you've installed via the drag-installed .mcpb instead, Claude Desktop pins you to that specific version. Download the latest .mcpb from Releases and re-install to update. Your credentials in the OS keychain are preserved across re-installs.

If you've explicitly pinned a version in your config (e.g. [email protected]), update by editing the version number or removing the pin entirely.

Available tools

Anonymous (no credentials needed)

| Tool | Description | |---|---| | search_products | Search Migros products by name or keyword, including products sold only online (such as "Partner" products). Returns product IDs. | | get_product_details | Full product info: nutrition, ingredients, allergens, price, ratings. Online-only products also get their online price and a Partner flag. | | get_stock | Check product availability at a specific Migros store. Updated once daily. | | get_categories | List all Migros product categories. | | search_stores | Find Migros stores by location with addresses and opening hours. | | get_promotions | Search current Migros promotions and deals. | | search_recipes | Search Migusto (Migros' recipe site) by query and/or ingredients. German/French/Italian only. | | get_recipe_details | Full recipe by slug: ingredients, instructions, photos, nutrition. | | get_recipe_products | Migros product UIDs for a recipe, ready to pass straight to add_to_basket. |

Authenticated (require credentials)

| Tool | Description | |---|---| | authenticate | Log in with the current six-digit 2FA code. Only needed when no TOTP secret is set. Reuses a cached session when possible. | | get_profile | Logged-in customer's basic profile (name, email, language). | | get_addresses | Saved delivery and billing addresses. | | get_shopping_lists | The user's shopping lists by name, for people with more than one. Pass a list's id to the basket tools. | | get_basket | Items currently in the user's basket. | | add_to_basket | Add a product (sets target quantity, default 1). | | update_basket_quantity | Set an item's exact quantity (0 to remove). | | remove_from_basket | Remove an item entirely. | | get_orders | List your online orders, paginated, filterable by status. | | get_order_details | Full details of a single order by id. | | get_checkout_link | Returns the URL to open in your browser to complete checkout. | | get_cumulus_status | Cumulus loyalty card status: points balance, level, cardholder. | | get_in_store_receipts | List in-store receipts (Kassenbons) over a date range. | | get_receipt_details | URL to view a single in-store receipt's line items in the browser. | | get_cumulus_coupons | Active personalized Cumulus coupons. |

How it works

Anonymous tools

Use the migros-api-wrapper which calls the same endpoints the Migros website uses internally. A guest token is fetched at startup and cached.

Authenticated tools

Use OAuth 2.0 against login.migros.ch. The first call runs a credentialed login (email → password → TOTP) and caches the resulting cookies + access token. Every 30 minutes the token is refreshed silently using cached cookies, without submitting the login form again.

With MIGROS_TOTP_SECRET set, the MCP makes the 2FA code itself. Without it, the AI passes the current code to authenticate: it asks the user, or reads it from a password manager it has access to (for example a 1Password MCP or the 1Password CLI). The code is used for that one login and is never stored or logged.

The cache is persisted across MCP process restarts (Claude Desktop launches, Mac reboots, etc.) so we re-authenticate maybe twice a year instead of dozens of times a day. Migros' login endpoint is behind Cloudflare bot detection that throttles frequent logins, so persistence is what keeps the MCP from getting rate-limited.

The session lives at:

  • macOS: ~/Library/Application Support/migros-mcp/session.json
  • Linux: $XDG_CONFIG_HOME/migros-mcp/session.json
  • Windows: %APPDATA%/migros-mcp/session.json
If the cached session expires (typically a few weeks), the MCP automatically re-runs the credentialed login.

Without a stored TOTP secret, authenticated tools return fresh_code_required instead, and the AI calls authenticate with a new code. The MCP remembers that the account needs a code, so it doesn't send your password to Migros until it has one.

Order placement

For safety, this MCP does not place orders programmatically. The get_checkout_link tool returns a URL the user opens in their real browser to confirm address, delivery slot, and payment via Migros' own checkout flow. Real money requires a real human click.

Known limitations

  • 2FA support is TOTP-only. Accounts secured with a passkey (and no TOTP fallback) are not supported. If your Migros account uses passkey as the only second factor, add a TOTP authenticator app in Migros account settings, then provide the TOTP secret to this MCP, or pass the current code to authenticate.
  • No automatic order placement. See above: get_checkout_link hands off to your browser for the actual placement.
  • Cloudflare rate limits. The login host (login.migros.ch) sits behind Cloudflare bot detection. If the MCP triggers too many login attempts in quick succession (wrong password retries, repeated restarts without a cached session), the IP may be throttled. When this happens the MCP now sets a cooldown (respecting Retry-After headers or falling back to 30 s → 2 min → 10 min backoff) and stops hitting the login host until it clears. During cooldown, any still-valid cached JWT keeps working so your MCP tools may continue serving requests. Only re-authentication is paused. If the cached JWT is also expired while rate-limited the MCP will surface a clear error with the cooldown deadline rather than silently retrying and worsening the throttle.

Development

git clone https://github.com/lewpgs/migros-mcp.git
cd migros-mcp
npm install
npm run build
node dist/index.js

Debug with the MCP Inspector:

npx -y @modelcontextprotocol/inspector npx migros-mcp

Disclaimers

  • Unofficial: Not affiliated with, endorsed by, or connected to Migros in any way.
  • No official API: Uses endpoints that power the Migros website. They are not documented or supported. Migros can change them without notice.
  • Credentials: When you provide credentials, they're used only to authenticate against login.migros.ch. A 6-digit code passed to authenticate is used for that one login and is never stored or logged. Resulting session cookies and access tokens are stored locally in your OS user config directory. They are never sent anywhere except Migros' own servers.
  • No order placement: This server does not place orders programmatically. Orders are completed in the user's own browser via the URL returned by get_checkout_link.
  • Use at your own risk: No guarantees of functionality, availability, or compatibility.

License

MIT

Chat with me