Skip to main content
Glama
README.md
# pyaterochka-mcp

[![CI](https://github.com/shishliannikov/pyaterochka-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/shishliannikov/pyaterochka-mcp/actions/workflows/ci.yml)
[![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

Неофициальный локальный MCP-сервер для поиска товаров, сборки корзины и
защищённого оформления доставки из «Пятёрочки».

> Проект не связан с X5 Group или «Пятёрочкой». Публичного API оформления
> заказов нет. Приватные интерфейсы могут измениться, быть заблокированы или
> запрещены пользовательским соглашением. Используйте только со своим аккаунтом.

## Что умеет MCP

| Инструмент | Побочный эффект | Назначение |
| --- | --- | --- |
| `pyaterochka_status` | нет | Проверяет локальную настройку, сессию, магазин и готовность checkout |
| `set_store` | локальный конфиг | Выбирает магазин по SAP-коду |
| `find_nearest_store` | только при `select=true` | Находит магазин по уже выбранным пользователем координатам |
| `list_categories` | нет | Показывает категории выбранного магазина |
| `search_products` | нет | Ищет доступные товары и актуальные цены |
| `list_category_products` | нет | Показывает товары категории |
| `get_product` | нет | Читает карточку, наличие, состав и атрибуты товара |
| `view_cart` | нет | Читает общую live-корзину аккаунта |
| `add_to_cart` | меняет корзину | Добавляет товар; денег не списывает |
| `update_cart_item` | меняет корзину | Задаёт точное количество; `0` удаляет позицию |
| `clear_cart` | меняет корзину | Очищает корзину |
| `list_delivery_intervals` | нет | Читает доступные виды и интервалы доставки |
| `select_delivery_interval` | меняет корзину | Выбирает express/auto или точный интервал |
| `list_payment_methods` | нет | Показывает только маскированные способы оплаты |
| `select_payment_method` | меняет checkout | Выбирает способ и при необходимости запоминает linked ID |
| `clear_preferred_payment_method` | локальный конфиг | Забывает локальное предпочтение, не удаляя карту |
| `set_order_details` | меняет корзину | Записывает квартиру, подъезд, этаж и комментарии |
| `checkout_preview` | пересчитывает корзину | Делает `revise`, показывает точный итог; заказ не создаёт |
| `confirm_order` | **может списать деньги** | После отдельного подтверждения один раз отправляет реальный заказ |
| `active_orders` | нет | Читает активные заказы |
| `order_history` | нет | Читает историю с редактированием личных полей |
| `get_order_status` | нет | Читает текущий статус одного заказа |
| `list_cancel_reasons` | нет | Получает актуальные причины отмены |
| `cancel_order` | **отменяет заказ** | Отменяет только явно указанный пользователем заказ |

Все изменения корзины аннулируют предыдущий checkout preview. Единственный
инструмент, создающий реальный заказ, — `confirm_order`; по умолчанию он
выключен в конфиге.

## Текущее состояние

Версия `0.6.0a3` содержит 24 MCP-инструмента:

- MCP-инструменты каталога, поиска, карточки товара и выбора магазина;
- импорт заголовков и cookies из локального HAR без вывода секретов в терминал;
- локальный Chrome transport для запросов через открытую вкладку `5ka.ru`;
- автоматический локальный capture через отдельное окно Chrome без ручного HAR;
- текущий протокол корзины `5ka.ru`: корзина как заказ со статусом `CART`;
- создание/чтение корзины, добавление, точное изменение количества и очистку;
- выбор доставки «как можно скорее» или точного доступного интервала;
- сохранение квартиры, подъезда, этажа и комментариев к заказу;
- чтение и выбор способов оплаты с маскированием карты;
- безопасное запоминание ID уже привязанного способа оплаты;
- обязательный пересчёт доступности и минимальной суммы перед оформлением;
- однократную отправку заказа через linked card, новую карту, СБП или SberPay;
- чтение активного заказа, истории и точного статуса;
- список причин отмены и отмену только по явному запросу;
- возможность переопределить версию любого endpoint-а через локальный конфиг;
- двухшаговый checkout с TTL, одноразовым токеном, суммой в копейках и
  fingerprint корзины;
- максимальный лимит заказа;
- запрет реального submit по умолчанию;
- отсутствие автоматического повтора submit при любом неоднозначном ответе;
- сверку корзины после неоднозначной ошибки мутации без повторной записи;
- маскирование адреса, контактов, карты и комментариев в ответах статуса;
- общий строгий редактирующий фильтр для MCP-ответов и HAR-отчётов;
- санитизацию и ограничение длины недоверенного текста от API;
- лимит количества одного товара от `0` до `100` и отказ для `NaN`/`Infinity`;
- потоковый лимит тела ответа до разбора JSON;
- запрет редиректов, доменно-привязанные cookies и проверку каждого URL;
- валидацию всех идентификаторов, подставляемых в URL;
- MCP-схемы с границами аргументов и аннотациями побочных эффектов;
- только локальный `stdio` transport.

Маршруты сверены с актуальным публичным JavaScript-клиентом `5ka.ru`:

- `GET /api/orders/v3/orders/?in_action=true` — поиск черновика `CART`;
- `/api/orders/v4|v8/orders/...` — создание корзины;
- `/api/orders/v5|v8/orders/...` — изменение корзины;
- `GET /api/orders/v6|v10/orders/{id}/` — чтение корзины;
- `/api/orders/v1|v3/orders/{id}/intervals` — интервалы доставки;
- `PATCH /api/orders/v7|v12/orders/{id}/` — доставка и детали заказа;
- `POST /api/orders/v1|v2/orders/{id}/revise` — финальный пересчёт;
- `/api/orders/v1/payment-methods` — способы оплаты;
- `/api/orders/v1/orders/{id}/pay-by-*` — однократная отправка/оплата;
- `/api/ordering/public/v1/orders/...` — активный заказ и отмена.

API версионируется и включается feature-флагами, поэтому все стандартные
маршруты остаются переопределяемыми.

Прямой HTTP-клиент с импортированными заголовками может получить `403`.
Поэтому рекомендуемый режим выполняет запросы непосредственно внутри уже
авторизованной пользовательской вкладки Chrome. MCP не переключает вкладку,
разрешает запросы только по HTTPS к `5ka.ru` и его поддоменам и не следует
редиректам. HTTP-режим применяет ту же доменную проверку; его cookies
привязаны к `5ka.ru`.

Проект ничего не кэширует: каталог, цены, наличие, корзина и заказ каждый раз
читаются из upstream для выбранного `store_id`. Это снижает риск показать
устаревшую цену, но не превращает приватный API в стабильный контракт.

Реальный submit не включён в стандартную конфигурацию. При уже привязанной
карте MCP может отправить заказ одним защищённым вызовом. Для новой карты, СБП
или SberPay «Пятёрочка» возвращает официальный платёжный переход: подтверждение
в форме или банковском приложении остаётся обязательным. 3-D Secure и
антифрод-проверки банка также нельзя гарантированно автоматизировать.

Подробная архитектура, маршруты, safety guard и проверенный end-to-end
сценарий описаны в [`docs/PAYMENTS.md`](docs/PAYMENTS.md).
Результаты внешних аудитов и статус финальных исправлений находятся в
[`docs/SECURITY_AUDIT_FOLLOWUP_RESOLUTION_2026-07-28.md`](docs/SECURITY_AUDIT_FOLLOWUP_RESOLUTION_2026-07-28.md).
Правила сообщения об уязвимостях описаны в [`SECURITY.md`](SECURITY.md).

## Установка

```bash
cd pyaterochka-mcp
python3 -m venv .venv
.venv/bin/pip install -e '.[dev,capture]'
```

## Подключение к MCP-клиенту

Codex:

```bash
codex mcp add pyaterochka -- /absolute/path/to/pyaterochka-mcp/.venv/bin/pyaterochka-mcp
codex mcp list
```

Для клиента с JSON-конфигурацией MCP:

```json
{
  "mcpServers": {
    "pyaterochka": {
      "command": "/absolute/path/to/pyaterochka-mcp/.venv/bin/pyaterochka-mcp"
    }
  }
}
```

После подключения перезапустите MCP-клиент или откройте новую задачу и первым
вызовите `pyaterochka_status`.

## Автоматический безопасный capture

Запустите:

```bash
.venv/bin/pyaterochka-capture
```

Команда открывает отдельное окно Google Chrome с закрытым локальным профилем.
В этом окне:

1. Войдите через X5ID. Если аккаунта ещё нет, выберите регистрацию, укажите
   свой номер телефона и самостоятельно введите SMS-код.
2. Выберите адрес доставки.
3. Добавьте один товар.
4. Откройте корзину и удалите товар.
5. Не переходите к оплате.
6. Закройте окно Chrome.

Сессионные заголовки, cookies, магазин и координаты сохраняются напрямую в
owner-only конфиг. Они не печатаются в терминал и не передаются в чат.
MCP не просит номер телефона или SMS-код и не регистрирует аккаунт от имени
пользователя: согласия и одноразовый код остаются в официальном окне X5ID.

Если сессия ещё не настроена, `pyaterochka_status` возвращает пошаговый
`authentication_onboarding` с предложением войти или зарегистрироваться.
Различить «нет аккаунта» и «аккаунт есть, но сессия ещё не захвачена» до
официальной авторизации MCP не может.

## Альтернатива: импорт HAR

1. Откройте `https://5ka.ru` в Chrome и войдите через X5ID.
2. Выберите адрес доставки и нужный магазин.
3. Откройте DevTools → Network, включите `Preserve log` и очистите список.
4. Выполните только безопасный сценарий:
   - найдите «молоко»;
   - откройте карточку товара;
   - добавьте один товар;
   - откройте корзину и экран итоговой суммы;
   - удалите добавленный товар.
5. Не нажимайте кнопку оплаты.
6. В Network выберите `Save all as HAR with content`.
7. Импортируйте HAR локально:

```bash
.venv/bin/pyaterochka-import-har ~/Downloads/5ka-session.har --transport chrome
```

Для Chrome transport:

1. Оставьте в обычном Google Chrome открытую вкладку `https://5ka.ru/`.
2. В меню Chrome включите `View → Developer → Allow JavaScript from Apple Events`.
3. При первом запуске разрешите вашему MCP-клиенту или терминалу управлять
   Google Chrome, если macOS покажет системный запрос.

Запросы выполняются в фоне именно в этой вкладке, используя её действующую
сессию. MCP не читает историю браузера и не отправляет запросы на другие домены.

Секреты сохраняются в:

```text
~/.config/pyaterochka-mcp/config.json
```

Файл создаётся с правами `0600`. В терминал значения cookies и токенов не
печатаются. Рядом создаётся `capture-report.json` — редактированный отчёт о
распознанных маршрутах. Импортёр понимает и старую пару API `v5/v6`, и текущую
`v8/v10`. Для ответов сохраняется только структура полей и типов, без значений.
HAR содержит секреты: после проверки импорта удалите его вручную безопасным
способом.

## Проверка

```bash
.venv/bin/pytest
.venv/bin/pyaterochka-capture --help
.venv/bin/pyaterochka-probe "молоко"
.venv/bin/pyaterochka-mcp
```

`pyaterochka-probe` выполняет только чтение: проверяет категории и поиск, не
меняя корзину. В выводе нет cookies, токенов и сырых ответов upstream.
В режиме `chrome` обычный Chrome должен быть открыт на `5ka.ru`.

При запуске MCP первым вызовите:

```text
pyaterochka_status
```

Затем:

```text
search_products("молоко")
get_product("<id>")
add_to_cart("<id>", 1)
view_cart()
```

Полный checkout выполняется строго по этапам:

```text
list_delivery_intervals()
select_delivery_interval("INTERVAL", "<uuid>")   # необязательно для auto/express
set_order_details(flat="12", entrance="1", floor="4")
list_payment_methods()
select_payment_method(<id>)
checkout_preview()
```

`checkout_preview` ничего не покупает, но это не read-only-вызов: он может
выбрать сохранённый способ оплаты, пересчитать loyalty и выполнить `revise`
общей корзины. Он возвращает точную итоговую сумму, недостающую сумму до
минимума, выбранную доставку, маскированный способ оплаты и
`missing_requirements`. Только если `ready_for_submit=true`, сумму нужно
показать пользователю и получить отдельное явное подтверждение. Готовый
preview также возвращает короткоживущий `confirmation_token`.

После подтверждения exact total:

```text
confirm_order(<точная сумма>, "<confirmation_token из этого preview>")
```

Для уже привязанной карты успешный ответ может сразу содержать созданный заказ.
Для новой карты/СБП/SberPay ответ содержит `requires_external_payment=true` и
официальный `payment_url`. После попытки используйте:

```text
active_orders()
order_history()
get_order_status("<order_id>")
```

При сетевой ошибке `confirm_order` не повторяйте: сначала проверьте активный
заказ и историю.

Полный жизненный цикл — от первой авторизации до отмены и восстановления после
ошибок — описан в
[`docs/ARCHITECTURE_AND_FLOWS.md`](docs/ARCHITECTURE_AND_FLOWS.md).

## Сохранённая карта

MCP сам не принимает и не хранит номер карты, срок действия или CVV. Первый
платёж новой картой проходит на официальной платёжной странице «Пятёрочки».
Если после этого API показывает карту как привязанную, её можно выбрать один
раз с локальным предпочтением:

```text
list_payment_methods()
select_payment_method(<id привязанной карты>, remember_for_future_orders=true)
```

В конфиг записывается только непрозрачный `payment_method_id`. При следующих
`checkout_preview` MCP автоматически выбирает этот метод до финального
пересчёта, поэтому пользователь всегда подтверждает уже актуальную сумму.
Удалить локальное предпочтение можно вызовом
`clear_preferred_payment_method()`: это не удаляет карту в аккаунте
«Пятёрочки».

Если «Пятёрочка» не сохранила карту, скрыла её или банк требует 3-D Secure,
MCP не может обойти официальный платёжный шаг. Сохранение карты выполняет
только сама платёжная система/«Пятёрочка», а не этот проект.

## Переопределение endpoint-а

Если feature-флаг аккаунта использует другую версию API, endpoint описывается
методом, URL/path и шаблоном JSON. Значения в фигурных скобках подставляются в
момент вызова:

```json
{
  "endpoints": {
    "cart_set": {
      "method": "PUT",
      "base": "orders",
      "path": "/v5/orders/{cart_id}/item/{product_id}/",
      "json": {
        "qty": "{quantity}"
      }
    }
  }
}
```

Поддерживаемые имена:

- `cart_list`
- `cart_create`
- `cart_get`
- `cart_add`
- `cart_set`
- `cart_delete`
- `cart_clear`
- `delivery_intervals`
- `order_update`
- `cart_revise`
- `payment_methods`
- `payment_method_select`
- `pay_linked_card`
- `pay_unlinked_card`
- `pay_linked_sbp`
- `pay_unlinked_sbp`
- `pay_linked_sberpay`
- `pay_unlinked_sberpay`
- `active_orders`
- `order_history`
- `order_get`
- `cancel_reasons`
- `order_cancel`

Не копируйте в публичный issue или чат `config.json` и исходный HAR.

## Защита денег

`confirm_order` не работает, пока одновременно не выполнены все условия:

- `checkout.submit_enabled` явно установлен в `true`;
- только что выполнен `checkout_preview`;
- передан одноразовый токен именно этого preview;
- подтверждённая пользователем сумма совпадает с preview;
- live-корзина имеет ту же сумму и fingerprint;
- прямо перед платёжным POST повторно совпали сумма, версия и fingerprint;
- набран минимум, выбраны доставка, квартира и способ оплаты;
- сумма не превышает `checkout.max_total`.

Submit выполняется ровно один раз и не повторяется автоматически при сетевой
ошибке. Preview расходуется до сетевого запроса. Оставляйте
`submit_enabled: false`, пока не готовы провести первый контролируемый заказ.
Для активации вручную измените owner-only
`~/.config/pyaterochka-mcp/config.json`, одновременно задав разумный
`max_total`. Это включает возможность, но само по себе ничего не заказывает.

### Осознанно принятый риск полной автоматизации

Чтобы сохранить сценарий уровня «показать итог → пользователь отвечает
“ок” → оформить привязанной картой», одноразовый `confirmation_token`
намеренно остаётся в ответе MCP, а `confirm_order` доступен модели после
явного подтверждения только что показанной точной суммы.

Санитизация внешних строк, ограниченные схемы, аннотации инструментов,
одноразовый token, TTL, fingerprint и повторная live-проверка существенно
снижают риск, но не являются криптографическим доказательством того, что
человек прочитал preview. Prompt injection из данных upstream остаётся
остаточным риском, который владелец проекта осознанно принимает ради полной
автоматизации. Для более строгого режима оставьте `submit_enabled=false` и
оформляйте заказ в официальном интерфейсе.

Автоматизация не может отменить требование 3-D Secure, антифрод-проверку,
подтверждение СБП или другой challenge, который запросит банк либо X5.

## Один аккаунт — одна общая корзина

Корзина хранится на стороне «Пятёрочки», а не внутри MCP. Официальный сайт,
приложение и все MCP-процессы с одной X5ID-сессией видят и меняют одну корзину.
Не собирайте её одновременно из нескольких клиентов: чужое изменение
аннулирует preview, а live-проверка перед оплатой остановит submit. После
неоднозначной ошибки сначала вызовите `view_cart`, `active_orders` и
`order_history`, не повторяя финансовый запрос.

## Источники

Каталожные маршруты и формы ответов сверены с MIT-проектами:

- [`Open-Inflation/pyaterochka_api`](https://github.com/Open-Inflation/pyaterochka_api)
- [`zavorateam/pyatorochka-min-api`](https://github.com/zavorateam/pyatorochka-min-api)

Архитектура и safety-паттерны частично адаптированы из
[`Dudude-bit/yandex-lavka-mcp`](https://github.com/Dudude-bit/yandex-lavka-mcp).
Копирайты и полные уведомления MIT сохранены в [`NOTICE`](NOTICE).

## Лицензия

Собственный код проекта распространяется по
[MIT License](LICENSE). Уведомления об использованных MIT-проектах и их
авторские строки сохранены в [`NOTICE`](NOTICE). Техническая проверка
совместимости лицензий, перечень зависимостей и обязанности при
распространении описаны в [`docs/LICENSING.md`](docs/LICENSING.md).

Название «Пятёрочка» и связанные товарные знаки принадлежат их
правообладателям. MIT-лицензия относится к коду этого репозитория и не даёт
разрешения на товарные знаки, приватный API или нарушение условий сервиса.

TDQS

A3.9/5.0

Scored across 24 tools

Disambiguation5/5

Each tool clearly targets a distinct action or resource, such as cart operations, product search, or order management, with no overlapping functionality.

Naming Consistency5/5

Tool names follow a consistent verb_noun pattern with underscores, e.g., add_to_cart, list_categories, confirm_order, making them predictable and easy to navigate.

Tool Count5/5

24 tools cover the full workflow of a grocery delivery service without being excessive, each serving a necessary function for the intended usage.

Completeness5/5

The tool set comprehensively covers store selection, product browsing, cart management, checkout, payment, order history, and cancelation, with no obvious gaps.

Maintenance

ActivitySlowing
ResponsivenessNo issues