# [0.3.1] - 2026-11-01

### Added

- **AI agents can read the store over MCP.** `/api/admin/mcp` serves the dashboard chat's tools to
  any MCP client that can send an integration token in `X-Api-Token`, Claude Code included. It's
  read-only, reads one channel per connection, and offers only the tools the token's permissions
  cover - sales, catalog, orders, stock, promotions, reviews and store setup. Each token can run 4
  calls at once and, with `RATE_LIMIT_ENABLED` on, `MCP_RATE_LIMIT_PER_MIN` a minute.
  `MCP_ENABLED=false` turns it off. Setup is in `docs/mcp.md`.

- **The storefront packages publish to npm.** `@skelet/storefront-core`, `-next`, `-astro` and
  `-react` go out with every release at its version, compiled to JavaScript with their types and
  licensed MIT, so a shop in a repo of its own can install them. A Skelet checkout keeps reading the
  source. The release workflow publishes through npm's trusted publishing, with no token stored -
  `docs/releasing.md` has the one-time setup.

### Fixed

- **The AI chat's product search reaches the whole catalog.** It used to scan only the first thousand
  products, so on a bigger store it answered "no products match" for things you sell. It now
  searches in the database, by name, SKU or URL, like the Products list does, newest first.
- **The AI chat's tools answer for the chat's channel.** A product's review counts and stock by
  location covered every channel, and review counts with the dashboard set to "All channels" did too.
- **A failed read in the AI chat says so.** "Could not load ..." came back to the model as an
  ordinary answer, and the cause was never logged. It's flagged as an error now, and logged.
- **The AI chat's overview tools say when a read failed.** Sales, web traffic, customer behaviour
  and experiments answered "no data" when the database or the Signals service couldn't be read, and
  the chat's opening snapshot left the section out the same way. They flag the failure now, and the
  snapshot says the section couldn't be read.
- **Money in the AI chat uses each currency's own decimals.** Every amount was printed with two, so
  yen came out a hundred times too small and dinars ten times too large. Promotion totals now name
  their currency too.
- **The AI chat's low-stock list covers the channel's own warehouses.** It filtered a store-wide page
  of 500 items down to the channel's, so a busy store could show "no low-stock items" for a channel
  that had some, and in flat inventory mode it never showed any. The insights card's count is the
  channel's now too.
- **The AI chat's window tops out at a year.** A larger window reached the sales queries unclamped.

### Security

- **The AI chat can only run the tools it was offered.** With customer data turned off in the AI
  settings, the chat hid the customer-record tools, but the model could still run one by asking for
  it by name. Now any tool it wasn't offered is refused.
- **Turning off customer data in the AI settings hides emails on orders too.** The order tools kept
  showing each customer's email after the switch was off. They don't now.
- **The AI chat quotes what shoppers and visitors wrote.** Customer names, review summaries, site
  searches, page addresses, referrers, rage-clicked element text, JS errors and custom event names
  reach the model in quotes, with line breaks escaped, so a crafted name or search can't pass itself
  off as part of the tool's answer.
- **The AI chat no longer confirms an id belongs to another channel.** Looking up an order or
  customer from another channel answered differently from one that doesn't exist; both read the same
  now.

[0.3.1]: https://github.com/skeletg/skelet/compare/v0.3.0...v0.3.1

---

From the Skelet changelog: https://skelet.dev/changelog/0.3.1/
