# Changelog of Amazon MCP Server - Product Data for AI Agents (`mrbridge/amazon-mcp-server`) Actor

- **URL**: https://apify.com/mrbridge/amazon-mcp-server/changelog.md
- **Full Actor documentation**: https://apify.com/mrbridge/amazon-mcp-server.md

## Changelog

All notable changes to this Actor. Dates are the build date. Versions are Apify
build numbers, so they advance on every deploy and skip the ones that failed to
build.

### Unreleased

#### Added

- **Batch mode.** A conventional run now performs one read and finishes, instead of
  starting a server nobody calls and timing out. The Input form takes an operation,
  a marketplace and its one conditional field; the run writes a single business
  item to the dataset and exits SUCCEEDED. This is what makes the Actor usable as a
  saved Task or on a schedule.
- A `task-results` dataset view showing what a run fetched, alongside the existing
  `receipts` view used by Standby.

#### Changed

- The Input schema declares real fields. It previously advertised an empty form and
  said the Actor took no run input, which is no longer true.
- The dataset item written for a paid read now depends on the run mode: Standby
  keeps its technical receipt, a conventional run writes its result. A read bills
  by landing an item in the default dataset, so writing both would bill one call
  twice.
- Store title, description and SEO copy left `.actor/actor.json`. `apify push`
  never wrote them to the live Actor, so the manifest was a second source of truth
  that only ever disagreed with the first.

#### Notes

- Only the two read operations are offered in batch. The three action tools bill
  through `tool-action` and would additionally fire the synthetic dataset event.

#### Fixed

- The batch run record no longer carries a free-form message. One failure message
  is built around the caller's own category slug, so logging the outcome whole
  would have persisted that slug beyond the run.
- The output schema exposes one neutral dataset link instead of stating that the
  Actor produces no batch result. Two view-pinned outputs were tried first and were
  wrong: a view transforms every item rather than filtering, so each one rendered
  the other run's items as partial rows. The Console view selector does the job.
- The results view names the product fields at the row root, which is where unwind
  puts them, rather than under a `products.` prefix.
- The results view unwinds the products array, so a Task page shows one readable
  row per product. Display only: the run still writes one item and bills one read.
- Batch input is closed to unknown fields, in the parser and in the published
  schema. An argument nobody wired up is refused rather than dropped and billed.

### Unreleased (input form)

#### Changed

- The Input form shows only Operation and Marketplace. The Actor is an MCP server
  first, and a form opening on a search box implied a visitor had to configure a
  query before they could connect a client. The MCP endpoint now leads the page.
- `query`, `category`, `page` and `maxResults` are hidden rather than removed. They
  remain in the schema, in the parser and in every saved Example, and an API caller
  can still send them: only the form stopped showing them.
- Operation and Marketplace values carry human labels: Amazon Search, Amazon Best
  Sellers, and each storefront alongside its domain.

### Unreleased (taxonomy)

#### Fixed

- A best sellers category that does not resolve now returns `NOT_FOUND` instead of
  `PARSE_ERROR`. The extractor always told the two apart, grid rendered with no
  cards being an unknown category rather than a layout change, but the fetch ladder
  converted every extractor exception into `PARSE_ERROR` and that judgement never
  reached the caller. Two costs: a caller was told their well-formed slug had hit a
  layout change, and the alarm that means "go read the extractor" fired on every
  typo. Measured on `/gp/bestsellers/computers` and `/gp/bestsellers/toys`, which
  Amazon answers with 200, no redirect, the page frame rendered, and the word
  `undefined` where the department name belongs.

- On the vendor tier, that same verdict now stops the chain instead of failing over.
  A category that does not exist will not exist for the next vendor, and the second
  call buys the same answer at the same price.

- The propagated `NOT_FOUND` carries the ladder's facts: tier, outbound attempts,
  ladder duration, queue and token waits, and the vendors actually tried. Passing
  the extractor's error through untouched had dropped all of them, so `tool_call`
  could no longer show that nothing escalated.

Only `NOT_FOUND` is propagated. Every other extractor exception, taxonomy or native,
still reports `PARSE_ERROR`. The enrichment builds a new error rather than mutating
the original, and inherits none of its details: the best sellers extractor throws
with the caller's own slug in there, and telemetry outlives the run.

### 0.1.68 (2026-08-12)

#### Changed

- Clarified the response returned when `GET /mcp` is used. The server supports
  Streamable HTTP through `POST /mcp`, but does not expose a standalone GET event
  stream.

### 0.1.67 (2026-08-12)

#### Fixed

- A managed vendor that loses its own network budget is now cancelled, not merely
  outrun. The budget was a `Promise.race` against a timer, which bounded the wait
  and left the request on the wire until the ladder's global abort fired up to
  twenty seconds later, still billed by the vendor and still holding its rate-limit
  slot. Each attempt now carries its own `AbortController`, combined with the
  ladder's, and the socket dies at its own 7 s deadline.
- The budget stops applying once response headers arrive. A vendor answering at
  6.9 s and streaming a large product page used to be at risk of cancellation at
  the exact moment it started paying off; the body is now read to the end.

### 0.1.66 (2026-08-12)

#### Changed

- The status qualifier that prefixed the title, both descriptions, the README
  heading, the OpenAPI title and the MCP resource is gone from every surface, by
  owner decision. The non-affiliation sentence and the trademark attribution stay
  and now carry that posture on their own.

### 0.1.65 (2026-08-12)

#### Changed

- Same removal across the Store metadata and the published build. Shipped ahead of
  0.1.66, which finished the job in the package manifest and the internal docs.

### 0.1.64 (2026-08-11)

#### Changed

- `asin` accepts up to 2048 characters instead of 512. It doubles as a full product
  URL and Amazon's tracking tail grows without warning, so a legitimate URL was
  refusable for a reason the caller could not see. 2048 is what browsers and
  proxies already treat as safe.
- The README describes the interactive OpenAPI view without naming a Console tab,
  so a platform rename cannot make the documentation wrong.

#### Fixed

- The manifest ships `buildTag: "canary"`. `apify push` uploads the manifest and it
  overwrites the remote value, so a manifest saying `latest` promoted straight to
  production on a bare push. Every build now lands on canary and production moves
  only by an explicit tag move.

### 0.1.61 (2026-08-11)

#### Added

- Full output schemas. `tools/list` now describes every field of every result,
  including the objects inside `products`, `reviews` and `offers`, which were
  previously published as opaque objects. A client can plan against the schema
  instead of calling the tool to find out what comes back.
- `## Quick Start` at the top of this README and on the Actor's Input tab, with the
  real endpoint and the two ways to authenticate.
- OpenAPI description of the HTTP surface, rendered on the Standby tab: endpoints,
  request examples, both security schemes, and the 401, 403, 406 and 500 responses.
- `coverage` in the `amazon://marketplaces` resource, stating per tool which
  storefronts it serves.

#### Changed

- Tool descriptions are shorter. Field lists moved to the output schemas, where a
  model can read them structurally.
- Every business object is now defined once and feeds both the internal validator
  and the published schema, so the two cannot drift.

### 0.1.57 (2026-08-11)

#### Fixed

- **Input hardening.** `amazon_bestsellers` accepted a category containing path
  separators, which let a caller steer the request to another Amazon path. The
  category is now a single slug of letters, digits and hyphens, and the handler
  encodes it as well. Refused calls cost nothing: no fetch, no charge.
- Tool arguments are validated against a closed schema. An unknown property is
  refused with `-32602` instead of being dropped in silence, which previously meant
  a caller could be billed for a call whose argument was never read.
- Length limits on `query` (256), `category` (100), `marketplace` (8) and `asin`
  (512), published in `tools/list`.
- `error.message` is capped at 400 characters.
- A transport failure now returns its `eventId` in `error.data`, so the identifier
  in the server log is one the caller can actually quote.

### 0.1.49 (2026-08-10)

#### Added

- Managed-vendor fallback after both direct fetch tiers fail on a block or a rate
  limit, with a per-vendor circuit breaker. Billing still happens only after a
  fully validated result.

#### Changed

- Fetch budget restructured to 40 s for the ladder and 5 s after it, split between
  the direct phase and the vendor phase, so a slow vendor cannot eat the time the
  parser needs.

### 0.1.34 (2026-08-09)

#### Changed

- `amazon_search` withdrawn on FR. Five spaced searches on amazon.fr all came back
  as challenges, on both fetch tiers, while the product and best-seller pages
  answered normally through the same proxy country. The call now returns
  `UNSUPPORTED_MARKETPLACE` before any request is made, so it costs nothing.

### 0.1.30 (2026-08-08)

#### Fixed

- Container kills under load. The V8 old-space limit sat above the container
  limit, so the kernel reclaimed the process before V8 escalated its collections.
