# io.github.lukabudik/alza-mcp (npm · alza-mcp)

Unofficial MCP server for Alza.cz: catalog search plus token-guarded account and checkout.

- Trust score: 79/100 (medium)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- npm · `alza-mcp`: 79/100 (this document), [markdown](https://verifymcp.io/servers/lukabudik-alza-mcp/alza-mcp.md), [page](https://verifymcp.io/servers/lukabudik-alza-mcp/alza-mcp)

## Channel facts

- Registry: `npm`
- Package: `alza-mcp`
- Version: `0.5.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 75/100
  - No malware found by supply-chain analysis.
  - CVE check failed: a known high-severity CVE affects zod 3.25.76, a direct dependency. A fixed version is available.
  - Declares code that runs automatically (postinstall) and that we could not recognise. It may be perfectly ordinary, but we have not established what it does.
  - 32 of 117 dependencies flagged as unhealthy (1 deprecated).
- **Provenance & Transparency**: 74/100
  - Repository check failed: the declared repository URL redirects; it must resolve directly.
  - Cryptographically verified build provenance (signed, bound to lukabudik/alza-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 28 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 77/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 6228 tokens (~346/item across 18 items; 18 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 70/100
  - Stability observed for 21 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 18 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 19 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the io.github.lukabudik/alza-mcp server?

io.github.lukabudik/alza-mcp runs locally as an npm package, launched with npx -y alza-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add lukabudik-alza-mcp -- npx -y alza-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "lukabudik-alza-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "alza-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "lukabudik-alza-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "alza-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add lukabudik-alza-mcp -- npx -y alza-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "lukabudik-alza-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "alza-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add lukabudik-alza-mcp --command npx --arg -y --arg alza-mcp
```

### Hermes

```yaml
mcp_servers:
  lukabudik-alza-mcp:
    command: "npx"
    args: ["-y", "alza-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "lukabudik-alza-mcp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "alza-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add lukabudik-alza-mcp -t stdio -c npx -a -y alza-mcp
```

### Other

```json
{
  "mcpServers": {
    "lukabudik-alza-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "alza-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-04 (score 79, +1)

No change was recorded against any check on this day. Stability & Change Management went from 63 to 67. That category is still filling its 30-day observation window: 19 days of observed history at the previous scan, 20 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-02 (score 78, +1)

No change was recorded against any check on this day. Stability & Change Management went from 57 to 60. That category is still filling its 30-day observation window: 17 days of observed history at the previous scan, 18 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-31 (score 77, +1)

- [functional improvement] Security disclosure: unverified → pass

### 2026-10-30 (score 76, 0)

- [functional regression] Security disclosure: pass → unverified

### 2026-10-29 (score 76, +1)

No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-27 (score 75, +1)

No change was recorded against any check on this day. Stability & Change Management went from 37 to 40. That category is still filling its 30-day observation window: 11 days of observed history at the previous scan, 12 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-25 (score 74, +1)

No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-24 (score 73, −5)

- [security regression] CVE-2023-54404 affects this package: high
- [security regression] Known CVEs: pass → fail

## MCP tools (18)

### `search_products` (~1279 tokens)

Search Alza products

Search the Alza.cz catalog by keyword. Use this for product discovery — finding what's available, comparing options, or starting research. Returns a list with product code, name, price, stock (from the card's purchase CTA), and rating. To get full details for one product, follow up with `get_product`. Price filters (`min_price`/`max_price`, rejected when inverted) and sorts are applied client-side to the top ~72 ranked candidates, so a narrow window can return fewer items than exist; `pageSize` is the real number of cards per Alza page (~24, not your `limit`) and `hasMore` says whether further pages exist. Sorting: Alza's search page ignores server-side sort, so price-asc / price-desc / rating scan up to ~72 top-ranked candidates (3 pages) and sort them client-side — `candidatesScanned` reports how many were scanned; for an absolute price floor also pass `max_price`. `in_stock: true` keeps only products with a live purchase CTA. Brand/attribute filtering: call `list_category_filters({category_id})` for real ids, then pass `producer_ids` and/or `filters` with `category_id`. This switches to Alza's own filtered category page, so `query` is ignored and results match what the website shows; a filter Alza doesn't honour returns an error rather than unfiltered results. Slider facets (screen size, refresh rate, brightness, weight, …) filter by `{param_id, min?, max?}` range; the applied ranges come back in `appliedRanges`. `min_screen_inches`/`max_screen_inches` use the category's real diagonal slider when `category_id` is given, and a product-name size heuristic otherwise. For attributes Alza has no facet for, compare shortlisted candidates with `get_product`'s `params`. Read-only.

Input parameters:

- `category_id` (integer): Restrict the search to a specific category id. Use list_categories to discover ids.
- `filters` (array): Attribute filter selections from `list_category_filters` (`filterable: true` groups only; never guess ids). Requires `category_id`. Combines with `producer_ids`. Two forms: `{param_id, value_id}` for…
- `in_stock` (boolean): If true, keep only products purchasable right now (card shows a 'Do košíku'/'Vybrat variantu' (alza.sk: 'Do košíka'/'Vybrať variant') purchase CTA; cards with a 'Hlídat'/'Strážiť' watch button are ex…
- `limit` (integer): Maximum number of results to return. Default 20, max 50.
- `max_price` (number): Maximum price in the locale's currency. Products whose price could not be read are excluded. Must not be below `min_price`. Applied client-side to the scanned candidates (up to ~72 top-ranked results…
- `max_screen_inches` (number): Maximum screen diagonal in inches. See `min_screen_inches` for when this is a server-side filter vs a name-based fallback.
- `min_price` (number): Minimum price in the locale's currency. Products whose price could not be read are excluded. Must not exceed `max_price`. Applied client-side to the scanned candidates (up to ~72 top-ranked results o…
- `min_screen_inches` (number): Minimum screen diagonal in inches, for display products (monitors, TVs, laptops). With `category_id` (and a category that has a diagonal slider) this is Alza's own server-side diagonal filter (live-v…
- `page` (integer): 1-indexed result page (1-50) (follows Alza's rendered pagination). Only pages Alza actually renders are reachable — a page beyond the rendered set returns no results rather than repeating page 1. Pag…
- `producer_ids` (array): Filter by ONE brand id (an array of at most one — Alza has no multi-brand category URL; to compare brands call once per brand) — get real ids from `list_category_filters`'s `brands`. Requires `catego…
- `query` (string, required): Search keywords. Required. Example: 'iPhone 15 Pro', 'PlayStation 5', 'gaming mouse Logitech'.
- `sort` (string): Sort order, default 'relevance'. Alza's search page ignores server-side sort parameters, so price (asc/desc) and rating sorts gather candidates from up to 3 result pages (~72 items — the top of Alza'…

Output parameters:

- `appliedRanges` (array)
- `candidatesScanned` (number)
- `hasMore` (boolean)
- `nextPage` (number)
- `page` (number)
- `pageSize` (number): Cards per rendered Alza result page (the real page capacity), not the requested limit.
- `products` (array)
- `query` (string)
- `total` (number)

### `get_product` (~266 tokens)

Get product details

Fetch details for a single product by its Alza code (the `code` from `search_products`, e.g. 'WEXOA002B0' — not the numeric id): name, price (with the original price when discounted), availability, rating, brand, category, primary image, URL, and the spec table when the product page carries one (up to 30 rows, merged from both the DOM spec table and the JSON-LD `additionalProperty` list some page templates use instead — fixed 2026-09-27 after a product with only the latter returned no params at all). Use after `search_products` to compare shortlisted candidates in depth, and to get the canonical URL to show the user. For reviews use `get_product_reviews`; for the complete spec sheet (parameterGroups) use `mobile_read` with operation=`router_product` and product_id = the numeric `d########` id from the product URL. Sourced from the product page's JSON-LD schema, so values are accurate and stable. Read-only.

Input parameters:

- `code` (string, required): Alza product code, e.g. 'WEXOA002B0'. This is the canonical identifier returned by `search_products` (the `code` field). Not the numeric id.

Output parameters:

- `product` (object): Scraped product detail (JSON-LD sourced; stable fields listed, rest passthrough).

### `compare_products` (~323 tokens)

Compare products side by side

Fetch 2–6 products by their Alza codes (the `code` from `search_products`) and return one aligned comparison table: a column per product, rows for price, availability, rating and brand, then every spec row present in any of them (exact spec-name matching; a product missing a row shows —). Use instead of calling `get_product` repeatedly when the user asks which of several candidates is better. A code that fails to load is reported in its own column (`ok: false`, `error`) while the others still compare. Pages load at most two at a time, so 6 products take roughly 15–30 s on a cold cache. Optional `summarize: true` adds a short verdict generated by your client's LLM via MCP sampling, grounded only in the table (skipped, not an error, when sampling is unsupported). Read-only.

Input parameters:

- `codes` (array, required): 2–6 Alza product codes to compare side by side, e.g. ['WEXOA002B0', 'JA190b1']. These are the `code` values from `search_products` (not numeric ids). Duplicates (same code, any letter case) are colla…
- `summarize` (boolean): Opt-in: also ask your own client LLM (MCP sampling) for a short verdict grounded only in the table. Ignored with `summary.status: "unavailable"` when the client does not support sampling — the table…

Output parameters:

- `duplicatesIgnored` (array)
- `products` (array)
- `rows` (array)
- `summary` (object)

### `get_product_reviews` (~250 tokens)

Get product reviews

Fetch reviews for a single product by its Alza code: the aggregate rating and review count plus up to `limit` individual reviews (author as Alza displays it, date, rating, body, pros/cons) from Alza's reviews API, newest first. `reviewCount` is the product page's aggregate; the reviews list can contain more items than it, apparently because the API also returns reviews from other storefronts (Slovak-language reviews have been seen; the API has no market field to confirm it) — the response text says so when that happens. Use after `get_product` when the user wants real-world feedback before deciding. If the reviews API is unavailable you receive the aggregate only (empty `reviews` array) — in that case rely on the rating/count. Do not use for the aggregate rating alone when you already have it from `search_products`/`get_product`. Read-only.

Input parameters:

- `code` (string, required): Alza product code, e.g. 'WEXOA002B0'. Same as the `code` from `search_products`.
- `limit` (integer): Maximum number of individual reviews to include. Default 10, max 50.

Output parameters:

- `code` (string)
- `ratingAverage` (number)
- `reviewCount` (number)
- `reviews` (array)

### `recommend_alternatives` (~331 tokens)

Recommend alternative products

Find alternatives to one product ("something like this but cheaper / better / same brand"). Candidate pool = Alza's own alternatives list for the product (mobile API, keyed by the numeric commodity id taken from the product URL); if that list is empty, or nothing in it survives the mode filter, falls back to a same-category `search_products` (`poolSource` says which was used). Heuristics: `cheaper` = strictly lower price, cheapest first; `same-brand` = brand match (source brand vs. the candidate's name), then rating desc, price asc; `better-specs` = rating >= source rating (unrated dropped), then rating desc, price asc — it ranks by customer rating, it does not compare spec tables, so shortlist then compare with `get_product` `params`. The source product is always excluded. Read-only.

Input parameters:

- `code` (string, required): Alza product code of the product to find alternatives for, e.g. 'RI054b5'. Same as the `code` from `search_products`.
- `limit` (integer): Maximum number of alternatives to return. Default 5, max 20.
- `mode` (string): Ranking mode. 'cheaper': strictly lower price than the source, cheapest first. 'same-brand': same brand as the source, best rating first then lower price. 'better-specs': rated at least as high as th…

Output parameters:

- `alternatives` (array)
- `candidatesConsidered` (number)
- `mode` (string)
- `poolSource` (string)
- `source` (object): Scraped product detail (JSON-LD sourced; stable fields listed, rest passthrough).

### `find_pickup_points` (~439 tokens)

Find AlzaBox lockers and Alza showrooms

Find AlzaBox parcel lockers and AlzaShop showrooms near a Czech/Slovak postal code: name, address, GPS, distance and opening hours, sorted nearest first. The postal code is geocoded with the public OpenStreetMap Nominatim service (nominatim.openstreetmap.org): the normalised code and the country are sent to that third party, not to Alza. Use when the user asks where the nearest AlzaBox or Alza store is, or where they could pick up an order. No cart or login needed. Lockers come from Alza's public locker map and are cached; each has a `parcelShopId`. Locker hours vary (many are nonstop, mall lockers follow mall hours) and are looked up for the first 10 lockers returned. Important: a standalone locker list can't tell whether a given product fits. Alza excludes large items (observed: 34"+ monitors) from the whole AlzaBox network and routes them to a few oversized-item pickup points. To check a specific product, add it to the cart and read `delivery_options` (or `web_pickup_places`, which is cart-scoped). Read-only. Example: `find_pickup_points({postal_code: '500 02', types: ['alzabox'], limit: 5})`

Input parameters:

- `limit` (integer): Maximum number of pickup points to return. Default 10.
- `postal_code` (string, required): Czech or Slovak 5-digit postal code. Examples: '110 00', '11000', '602 00'. One optional space is tolerated; blank or malformed values are rejected.
- `radius_km` (number): Search radius in kilometres. Default 15 km.
- `types` (array): Restrict to specific pickup-point types. 'alzabox' = self-service AlzaBox parcel lockers (live list from Alza's public locker map, no cart needed). 'branch' = brick-and-mortar AlzaShop showrooms with…

Output parameters:

- `points` (array)
- `warnings` (array)

### `list_category_filters` (~358 tokens)

List a category's filters

List the brands and attribute filters (facets) Alza defines for a category, with real ids and product counts. The attribute set differs per category (laptops have CPU/RAM facets, monitors have panel/resolution facets, …). Pass `brands[].valueId` to `search_products` as `producer_ids` (brand filtering works in every category), and `filterable: true` groups' `param_id`/`value_id` pairs as `filters`. Checkbox values are only honoured when Alza has an SEO landing page for that exact value (HDMI ports, for example); many others, notably panel type and resolution on monitors, are redirected to the unfiltered category (live 2026-10-07), and `filterable: true` does not predict which. When one isn't honoured, `search_products` returns an error rather than unfiltered results; drop that filter and compare candidates with `get_product`'s `params` instead. Slider groups (`filterMode: "range"` — screen size, refresh rate, brightness, weight, port counts, …) filter by `{param_id, min?, max?}` in `search_products`'s `filters`, with min/max in the facet's own units as given by `values[].value` (e.g. millimetres for a monitor diagonal, inches for a TV diagonal; live-verified 2026-10-06). `filterable: false` groups are informational only. Call this before using `producer_ids`/`filters` — never guess ids. Read-only.

Input parameters:

- `category_id` (integer, required): Category id to read attribute filters for (from `list_categories` or `search_products`'s results).

Output parameters:

- `brands` (array)
- `category_id` (number)
- `groups` (array)

### `list_categories` (~84 tokens)

List Alza categories

Browse the Alza category tree one level at a time. Useful for narrowing a product search — find the right category id, then pass it to `search_products` as `category_id`. Without arguments, returns top-level categories.

Input parameters:

- `parent_id` (integer): Parent category id. Omit to list top-level categories. Pass an id from a previous result to drill down.

Output parameters:

- `categories` (array)

### `get_deals` (~294 tokens)

Find discounted Alza products

Find currently discounted products on Alza.cz, with current price, original price, savings and a discount % COMPUTED from the observed prices (never from marketing badges). Alza has no 'sale' facet or product-grid sale page, so this scans category listing pages (up to 3 pages ≈ 72 cards for a given `category_id`; page 1 of five popular categories when omitted) for cards showing a crossed-out original price or an 'Ušetříte' savings amount — it covers a bounded sample, not Alza's whole sale inventory (`candidatesScanned` says how many cards were checked). Czech store only (alza.cz price-box wording); errors on other locales. Prices are the shelf price, not code/AlzaPlus+ coupon prices. Read-only.

Input parameters:

- `category_id` (integer): Leaf category id to scan for discounts (from `list_categories`/`search_products`; top-level hub categories such as 'Počítače a notebooky' have no product grid and return nothing). Omit to scan the fi…
- `limit` (integer): Maximum deals to return, best discount first. Default 20, max 50.
- `min_discount_percent` (number): Keep only products whose computed discount is at least this many percent. Default 0 (any discount).

Output parameters:

- `candidatesScanned` (number)
- `categoryIds` (array)
- `deals` (array)
- `total` (number)

### `autocomplete` (~132 tokens)

Alza search suggestions

Cheap search-box suggestions (plain HTTP, no page render): suggested query phrases plus matching categories, brands and products with ids/codes. Use it to refine a messy Czech query before a full `search_products` — pass a category `id` as `category_id`, or a product code to `get_product`.

Input parameters:

- `limit` (integer): Max entries per section (suggested phrases, categories, products, brands, articles). Default 5, max 10.
- `query` (string, required): Partial or full search text, e.g. "čistič kol" or "iphone". Czech diacritics are fine.

Output parameters:

- `articles` (array)
- `brands` (array)
- `categories` (array)
- `products` (array)
- `query` (string)
- `suggestions` (array)

### `auth_discovery` (~84 tokens)

Read Alza OAuth discovery

Read the live OpenID Connect discovery document that the Alza mobile app uses (issuer, authorization endpoint, token endpoint). Use only when debugging the OAuth flow or verifying which identity endpoints Alza exposes before calling `auth_start`. Do not use for everyday shopping — it returns a configuration document, not account data, and changes nothing. Read-only; no credentials are ever sent.

Output parameters:

- `authorization_endpoint` (string)
- `code_challenge_methods_supported` (array)
- `grant_types_supported` (array)
- `issuer` (string)
- `jwks_uri` (string)
- `token_endpoint` (string)

### `auth_start` (~276 tokens)

Start Alza mobile API OAuth

Start an OAuth 2.0 PKCE sign-in for the Alza mobile API: returns an authorization URL plus a state value. Use when `account_status` reports no loaded token, or when account tools start failing with authentication errors. Flow: open the returned authorization URL in a browser, sign in to Alza, the app redirects to `alza://identity?code=...&state=...` — then call `auth_exchange` with that redirect URL (or its code and this state). Desktop browsers cannot open the `alza://` scheme, so the page appears to stall and after ~40 s shows "Při přihlášení došlo k chybě." — that message is a client-side timer, not a failed sign-in. Tell the user to open DevTools before signing in (Network tab with "Preserve log" on) and copy the `alza://identity?code=...` URL from the redirect's `Location` header, or from the Console error about failing to launch `alza://`. The code is short-lived, so exchange it promptly. This call only creates a local PKCE session: the user's credentials never enter the MCP and nothing changes on Alza's side. Do not call it repeatedly for one sign-in — each call supersedes the previous state.

Output parameters:

- `authorizationUrl` (string)
- `state` (string)

### `auth_exchange` (~226 tokens)

Exchange Alza OAuth code

Complete the OAuth 2.0 PKCE sign-in: exchange the authorization code for mobile API tokens and load them into this server. Use immediately after the user finishes the `auth_start` flow in the browser. Pass the whole `alza://identity?code=...&state=...` redirect URL as `code` (state is then read from it), or the bare `code` plus `state` — never a password and never a refresh token here. Fails if the state does not match a pending `auth_start` session (start over from `auth_start` in that case). Side effect: replaces the token set currently loaded in this process; afterwards account tools such as `cart`, `profile`, and `order` are authenticated.

Input parameters:

- `code` (string, required): Authorization code from the `alza://identity` redirect (the `code` query parameter), or the full redirect URL.
- `state` (string): State value returned by `auth_start`; must match the pending PKCE session exactly. Optional when `code` is the full redirect URL.

Output parameters:

- `data`
- `err` (number|string|null)
- `msg` (string|null)

### `prepare_mutation` (~540 tokens)

Prepare an Alza mutation

Start a two-step mutation by returning a one-time confirmation token bound to exactly one action. This call itself sends nothing to Alza. Use it before the high-impact typed mutations — `register` (action `register`), `address_upsert` (`address_create` or `address_edit`), `address_delete` (`address_delete`), `pay_after_order` (`after_order_payment`), `web_place_order` (`web_place_order`), `web_pay_after_order` (`web_after_order_payment`), `cancel_order` (`cancel_order`), `review_submit` (`review_submit`), `subscription_activate` (`subscription_activate`), `subscription_update_installment` (`subscription_update_installment`), `upload_attachment` (`attachment_upload`), `watchdog_set` (`watchdog_set`), `watchdog_delete` (`watchdog_delete`) — and before any low-risk `mutate_list` action (`create`, `rename`, `delete`, `add`, `remove`, `move`, `set_country`, `set_isic`, `add_gift`, `add_order_service`, `send_feedback`, `submit_discussion`, `rate_discussion`, `coupon_add`, `coupon_remove`, `basket_update`, `basket_unlock`, `gdpr_export`). Pass `payload`: exactly the arguments you will send to that tool, all except `confirmation_token` (for `mutate_list`, the object you will pass as its `payload`). The token is bound to the action and to that payload — a call with different arguments is refused and spends the token. Pass the returned token as `confirmation_token` on the matching call; the token is single-use — the first call that presents it spends it, even if that call fails, so prepare a new one to retry — and it expires 5 minutes after it is issued (`expiresAt`). Each action has its own pending token: preparing the same action again replaces its earlier token, tokens prepared for other actions stay valid. Do not use for read-only tools, and not for `add_to_cart` (which is a low-risk cart write that needs no token).

Input parameters:

- `action` (string, required): Which mutation you are about to perform; the token will only be accepted by that action's tool.
- `payload` (object, required): The exact arguments of the mutation call, without `confirmation_token` — e.g. cancel_order: {order_id, part_id, hash, reason}; mutate_list coupon_add: {coupon: "CODE"}. Show these to the user when as…

Output parameters:

- `action` (string)
- `confirmationToken` (string)
- `expiresAt` (string)
- `payloadBound` (boolean)

### `account_status` (~122 tokens)

Check mobile API auth status

Report whether a mobile API access token is loaded in this server process, and when it expires (`expiresAt`, `expired`) if that is known. An expired token is refreshed automatically before the next account call when a refresh token is loaded. Use as a first check before account-scoped tools (`cart`, `profile`, `order`, `add_to_cart`), or to diagnose "not authenticated" failures. If no token is loaded, run `auth_start`, have the user complete the browser sign-in, then `auth_exchange`. Read-only; no network call.

Output parameters:

- `apiBaseUrl` (string)
- `authenticated` (boolean)
- `expired` (boolean)
- `expiresAt` (string)
- `visitorId` (string)

### `list_toolsets` (~106 tokens)

List available toolsets

List every toolset this server groups its tools into: id, title, description, member tool names, and whether it's currently enabled. Only `catalog` and `auth` are enabled by default to keep the visible tool list small — use `set_toolset` to turn on the group a task actually needs (e.g. `basket_and_checkout` before placing an order). Call this first if you're unsure which toolset covers what you need. Read-only, no network call.

Output parameters:

- `toolsets` (array)

### `set_toolset` (~120 tokens)

Enable or disable a toolset

Enable or disable every tool in one toolset (or `all` for every toolset) at once, so only the tools relevant to the current task are visible. Call `list_toolsets` first to see the available ids. Changing this fires the standard MCP tools-list-changed notification. No Alza-side effect — this only changes which tools this MCP server currently exposes to you.

Input parameters:

- `enabled` (boolean, required): true to enable, false to disable.
- `id` (string, required): Toolset id from `list_toolsets`, or "all".

Output parameters:

- `enabled` (boolean)
- `id` (string)
- `tools_affected` (array)

### `report_issue` (~411 tokens)

Draft a GitHub issue about alza-mcp

Draft a bug report or feature request for the alza-mcp project (github.com/lukabudik/alza-mcp). Use it when a tool fails unexpectedly, returns data that is clearly wrong, Alza changed something and a tool broke, or the user needs something no tool can do. Not for the user's own mistakes (invalid arguments, a product that doesn't exist) or for problems with an Alza order — those go to Alza support. This tool files nothing: it returns a redacted Markdown draft with version and environment details and this session's recent tool errors, a `gh` command to search for duplicates, a `gh issue create` command, and a prefilled new-issue link. Then: show the user the title and body and ask before filing, since it is posted publicly from their GitHub account. If they agree and you can run shell commands with an authenticated GitHub CLI, run `gh_search_command` first and, if nothing matches, `gh_create_command`; otherwise give them `new_issue_url`.

Input parameters:

- `category` (string, required): bug = alza-mcp misbehaves; alza_change = Alza changed a page/endpoint and a tool broke; feature_request = something the tools can't do yet; docs = wrong or missing documentation.
- `expected` (string): What you expected instead.
- `include_recent_errors` (boolean): Attach this session's last 5 tool errors (redacted). Default true.
- `steps` (array): Steps to reproduce: tool calls with their arguments, in order.
- `title` (string, required): One-line summary, e.g. "get_product returns no specs for PSU pages".
- `tool` (string): The alza-mcp tool involved, e.g. "search_products".
- `what_happened` (string, required): What went wrong, including the exact error text. No personal data: credentials, emails, phone numbers and account ids are redacted automatically, but leave out names and addresses.

Output parameters:

- `body` (string): Markdown issue body, already redacted.
- `gh_create_command` (string): Files the issue with the GitHub CLI from the user's account (body passed via heredoc).
- `gh_search_command` (string): Run first to look for an existing issue about the same problem.
- `labels` (array)
- `new_issue_url` (string): Prefilled GitHub new-issue page, for agents without a shell or `gh`.
- `recent_errors_included` (integer)
- `redactions` (integer): How many credential / personal-data matches were replaced.
- `repo` (string)
- `title` (string)
- `url_body_truncated` (boolean)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Vulnerabilities, Dependencies. The full working is on the page: https://verifymcp.io/servers/lukabudik-alza-mcp/alza-mcp#diagnostics

## Score history

- 2026-11-05: 79
- 2026-11-04: 79
- 2026-11-03: 78
- 2026-11-02: 78
- 2026-11-01: 77
- 2026-10-31: 77
- 2026-10-30: 76
- 2026-10-29: 76
- 2026-10-28: 75
- 2026-10-27: 75
- 2026-10-26: 74
- 2026-10-25: 74
- 2026-10-24: 73
- 2026-10-23: 78
- 2026-10-22: 77
- 2026-10-21: 74
- 2026-10-20: 74
- 2026-10-19: 74
- 2026-10-18: 74
- 2026-10-17: 74
- 2026-10-16: 74
- 2026-10-15: 74
- 2026-10-14: 42
- 2026-10-13: 42
- 2026-10-12: 42
- 2026-10-11: 42

## Common questions

### What is the io.github.lukabudik/alza-mcp server?

io.github.lukabudik/alza-mcp is listed in the public MCP registry as io.github.lukabudik/alza-mcp. Unofficial MCP server for Alza.cz: catalog search plus token-guarded account and checkout. This page covers its npm package (alza-mcp).

### Is the io.github.lukabudik/alza-mcp server safe to use?

io.github.lukabudik/alza-mcp scores 79 out of 100 on VerifyMCP. We recorded 1 known advisory against it as of 5 November 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the io.github.lukabudik/alza-mcp server expose?

io.github.lukabudik/alza-mcp exposes 18 tools: search_products, get_product, compare_products, get_product_reviews, recommend_alternatives, and 13 more. Their descriptions and schemas cost roughly 5,641 tokens of context every time the server is loaded.

### Is the io.github.lukabudik/alza-mcp server still maintained?

io.github.lukabudik/alza-mcp is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the io.github.lukabudik/alza-mcp server under?

io.github.lukabudik/alza-mcp declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

### What did VerifyMCP test on the io.github.lukabudik/alza-mcp server?

VerifyMCP ran 16 checks on io.github.lukabudik/alza-mcp, covering Malware scan, Known CVEs, Install scripts, Dependency health and 12 more. Endpoint Security and Transport & Reachability do not apply to an npm package, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.

## Links

- npm package: https://www.npmjs.com/package/alza-mcp
- Socket report: https://socket.dev/npm/package/alza-mcp
- Changelog RSS feed: https://verifymcp.io/servers/lukabudik-alza-mcp/alza-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/lukabudik-alza-mcp/alza-mcp/changelog.json
- Trust report (JSON): https://verifymcp.io/servers/lukabudik-alza-mcp/alza-mcp.json
- HTML version of this page: https://verifymcp.io/servers/lukabudik-alza-mcp/alza-mcp
