Bollywood HungamaJanhvi Kapoor, Sreeleela and Siddharth Gupta team up for Umesh Bisht’s thriller, first schedule begins in NainitalInquirerTaal Volcano records 17 earthquakes in 24 hoursCNN TürkTaksitli alışverişlerde yeni dönem: Cep telefonlarında 12 taksit sınırı değiştiPunchPolice remove Rivers DPO after station renovation by suspected cultistsDaily MaverickKATLEHONG MASS SHOOTING: Girl, 11, who survived mass shooting still has bullet lodged near her spineRTP DesportoFrancisco Cabral na final de pares do Masters 1.000 de XangaiThe Jerusalem PostIDF blocks roads leading to Gaza border after Nahala settlers attempt to build outpost overnightEgypt IndependentTemperatures drop 3°C as rain reaches CairoMalay MailFahmi: No Malaysian palm oil companies involved in burning activities in IndonesiaColliderApple TV's New Crown Jewel Officially Continues Streaming DominationSouth China Morning PostChina’s AI boom, self-sufficiency push fuel earnings surge for local chip firmsSky TG24Sciopero scuola e blocco autotrasportatori: giornata di mobilitazione da Nord a Sud. LIVE
The Daily Newsstand · Free, Always
Friday, October 16, 2026

MCP ВкусВилл собирает корзину под мои КБЖУ: как я перестала тратить по 30 минут на заказ товаров из интернет-магазина

Translate

Всем, кто помешан на правильном питании и AI, посвящается :)

Каждый заказ продуктов отнимал у меня 30–40 минут: хочется нового, у меня лимит калорий и нормы белка, а фильтра по КБЖУ в интернет-магазинах, где я покупаю, нет, и я читала карточку за карточкой. Теперь это делает Claude через MCP-сервер ВкусВилла: просматривает товары, подбирает блюда из моей базы рецептов, составляет меню на неделю и подгоняет граммы под мои нормы решателем, а не на глаз. На выходе план питания, список того, что приготовить заранее, карточки рецептов и ссылка, по которой корзина уже собрана. В статье рассказываю, как я к этому пришла, где сервер спотыкается и какой промпт можно взять целиком.

Скриншоты терминала в статье — реконструкция: реплики и ответы взяты из моей сессии дословно или с сокращениями, оформление нарисовано заново. Скриншоты страниц сняты с настоящих страниц.

Сразу оговорюсь. 900–1000 ккал в день — мой личный коридор под мою цель. Это ниже обычных норм, и подбирать свой коридор стоит с врачом. Статья про инструмент, а не про диету.

Все примеры в статье на Claude, потому что его знает большинство читателей. MCP — открытый стандарт, и любая модель, которая его поддерживает, подключается к серверу ВкусВилла и работает с ним по тем же правилам: те же инструменты, те же лимиты, та же ссылка на корзину. Отличаться может только вход: обход из шага 3 нужен именно Claude Code.

Где уже есть MCP для покупок

Перед тем как садиться за свой пример, я полезла смотреть, кто еще из магазинов пустил ИИ-ассистентов к себе через MCP. Пока это в основном проекты энтузиастов: их пилят поверх веб-версий сервисов, кто во что горазд. Вот что нашла на 13 октября 2026 года:

Магазин или платформа

Чей сервер

Что умеет

ВкусВилл

официальный, mcp.vkusvill.ru

поиск по каталогу, состав и КБЖУ товара, ссылка на готовую корзину

Яндекс Лавка

неофициальный, автор описал его на Хабре

поиск, корзина и заказ через веб-API Лавки под вашей сессией; автор сам предупреждает, что это может нарушать правила сервиса

Wildberries, Ozon, Яндекс Маркет и другие

неофициальный, проект сообщества

поиск и сравнение цен, только чтение

Официальный сервер, где есть и КБЖУ, и корзина, среди российских продуктовых магазинов я нашла только у ВкусВилла. На нем дальше все и показываю, хотя подход годится для любого магазина, который откроет такой же доступ.

Зачем мне это

Для меня важно, что я ем. У меня есть требования к еде: дневной лимит калорий, норма белка и клетчатки. И при этом хочется пробовать новое, а не заказывать одно и то же каждую неделю. Поэтому заказ продуктов в интернет-магазине занимал у меня в среднем 30–40 минут.

Время уходило не на выбор, а на чтение. Фильтра по калориям и КБЖУ в интернет-магазинах, где я покупаю, нет. Чтобы понять, подходит ли новый творог или готовый суп, приходилось открывать карточку и читать состав и пищевую ценность. Потом следующую. Потом еще одну.

В этом году я перешла на систему питания по модели Сергея Обложко. Это не диета с запретами, а способ собирать каждый прием пищи из понятных долей. Основа модели — «метаболическая тарелка»: половина тарелки клетчатка (100–150 г овощей), четверть белок (60–100 г), четверть сложные углеводы (60–100 г), жиров минимум. Еще одно правило этой модели — «вкусная точка» (у Обложко она называется сладкой): после каждого приема пищи небольшая сладкая порция, у меня до 60 ккал. Так сладкое остается в жизни и не превращается в отдельный перекус.

Рецепты у меня уже собраны. Их копит мой бот: я присылаю ссылку на ролик или пишу рецепт словами, бот раскладывает его в Obsidian. Там же лежат сборники рецептов Обложко и мои адаптации. Не хватало моста между рецептами и магазином.

Тот же бот помогает следить за тем, что я съела. Я пишу прием пищи составом или присылаю фото, и бот считает КБЖУ по моей личной базе продуктов, а если продукта в базе нет, просит фото этикетки и запоминает новинку, чтобы не подставлять типовые цифры. Вечером приходят две картинки: сводка дня и разбивка по приемам.

Схема 1. Как бот ведет мое питание

Схема 1. Как бот ведет мое питание

Скрин 2. Как я веду питание в боте

Скрин 2. Как я веду питание в боте

Скрин 3. Разбивка по приемам пищи

Скрин 3. Разбивка по приемам пищи

Теперь вся система целиком. Бот работает на сервере и раскладывает рецепты заметками в Obsidian. Там же лежат мои нормы КБЖУ, личная база продуктов и дневник питания. Claude Code читает эту базу, ходит в MCP-сервер ВкусВилла за товарами и возвращает мне отчет и ссылки на корзины, которые открываются прямо на сайте магазина.

Схема 4. Из чего состоит система

Схема 4. Из чего состоит система

Сам сбор корзины укладывается в шесть шагов. Сверху то, что я принесла сама: нормы КБЖУ, базу рецептов и правила метода. Справа MCP-сервер ВкусВилла: Claude обращается к нему в начале, чтобы выгрузить каталог, и в конце, чтобы собрать ссылку на корзину. Между ними работают Python-скрипты, которые Claude написал и запустил сам: справочник, расчет КБЖУ блюд, подгонка дня под нормы и пересчет недели в упаковки. Дальше рассказываю, как я к этому пришла.

Схема 5. Как устроен сбор корзины

Схема 5. Как устроен сбор корзины

Что умеет MCP ВкусВилла

Если коротко, MCP (Model Context Protocol) — это стандарт, по которому модель вызывает внешние инструменты. Сервер ВкусВилла живет по адресу https://mcp.vkusvill.ru/mcp, и инструменты у него двух сортов: публичные и личные.

Инструмент

Что делает

Нужна авторизация

vkusvill_products_search

поиск по каталогу: цена, вес, рейтинг, состав, КБЖУ; с OAuth еще и остаток

нет

vkusvill_product_details

карточка товара по id; с OAuth еще и остаток

нет

vkusvill_product_barcode

карточка по штрихкоду

нет

vkusvill_product_analogs

аналоги товара

нет

vkusvill_products_discount

товары со скидкой

нет

vkusvill_recipes

рецепты ВкусВилла

нет

vkusvill_shops

магазины

нет

vkusvill_cart_link_create

ссылка на корзину, до 30 позиций

нет

vkusvill_orders_history

заказы за последние 30 дней

да, OAuth

vkusvill_product_lp

«Любимый продукт» пользователя

да, OAuth

vkusvill_discounts_personal

персональные скидки, акция «6 скидок»

да, OAuth

С личными придется повозиться, им нужен OAuth 2.0 с PKCE. Агента регистрируют на vkusvill.ru/oauth/registration, по шагам это в разделе «Как повторить». Первую версию корзин я собирала без авторизации, а потом все-таки вошла. Через /mcp не вышло, обход тоже в «Как повторить», шаг 3. Со входом появляется то, чего мне не хватало: в поиске и карточке товара есть остаток по адресу доставки из личного кабинета, поле available_quantity. У весовых товаров он в килограммах (у куриного филе стояло 0,69), у штучных в упаковках. Меняется и сам поиск: по запросу «филе куриное» 13 октября без входа сервер нашел 619 товаров, со входом 567, и в первых тридцати не было ни одного с нулевым остатком. Похоже, то, чего нет по вашему адресу, поиск просто не показывает.

Скрин 6. Регистрация OAuth-клиента во ВкусВилле

Скрин 6. Регистрация OAuth-клиента во ВкусВилле

Скрин 7. Письмо с ключами (данные замазаны)

Скрин 7. Письмо с ключами (данные замазаны)

Публичные инструменты в Claude Code подключаются одной командой, подключение со входом другое, оно в шаге 3 «Как повторить»:

claude mcp add --transport http vkusvill https://mcp.vkusvill.ru/mcp

После перезапуска инструменты появляются в списке, и с каталогом уже можно разговаривать обычным языком.

Первый запрос про продукты до 120 ккал

Начала я с простого вопроса: «Подключись к ВкусВиллу и посмотри, какие продукты у них меньше 100–120 калорий».

Скрин 8. Первый запрос и ответ таблицей

Скрин 8. Первый запрос и ответ таблицей

Claude прошелся по девяти категориям, на каждую отдельный поисковый запрос. Творог, йогурты, кефир, птица, рыба, морепродукты, супы, салаты, десерты. Ответ прилетел таблицами по разделам. Ну и цифры там приятные: кефир 1% — 37 ккал, треска — 77, пикша — 73–77, коктейльные креветки — 50–69, суп с фрикадельками из индейки — вообще 27–29.

А теперь сюрприз. Один и тот же товар ВкусВиллу делают несколько производителей, и у каждого свое КБЖУ. Сервер честно отдает все варианты, но одной строкой. Вот и выходит, что суп «Куриный» с домашней лапшой бывает 27 ккал на 100 г, а бывает 74. Салат «Витаминный» от 65 до 112. Какая партия окажется на полке? Заранее не узнать.

Я для себя вывела простое правило. Если считаете калории точно, берите товары с одним производителем или с узким разбросом. У сырой рыбы, кефира и греческого йогурта разброса почти нет, а у готовой кулинарии он бывает двух-трехкратным.

Как выгрузить весь каталог, если сервер отдает по 10 товаров

Дальше я попросила пройти всю базу и собрать все продукты до 150 ккал на 100 г. Здесь и начались ограничения.

10 товаров на страницу. Поиск возвращает максимум 10 позиций, остальное — страницами. Листать тысячи товаров через диалог с моделью дорого: один товар с составом и КБЖУ весит около тысячи токенов, страница из десяти — около десяти тысяч, и все это остается в контексте.

Пустой запрос не принимается. Хотелось перебрать каталог по категориям без поискового слова, но сервер отвечает ошибкой «Пустой поисковый запрос». Звездочка как запрос возвращает ноль товаров.

Поэтому Claude предложил обойти модель: обращаться к MCP-серверу напрямую по HTTP. MCP-сервер в режиме Streamable HTTP — это обычный JSON-RPC, его можно вызвать хоть из curl:

curl -s -X POST https://mcp.vkusvill.ru/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"vkusvill_products_search",
                 "arguments":{"q":"творог","mode":"full","limit":10,"page":1,"vvonly":0}}}'

Скрипт на Python перебирает около трехсот слов: продукты, блюда, названия категорий. Каждый запрос он пролистывает до 30 страниц, убирает дубли по id, а названия категорий из ответа сервера сам добавляет в очередь. Весь список я не прошла: к моменту написания обход остановился на 185 запросах.

Скрин 9. Лог обхода каталога

Скрин 9. Лог обхода каталога

На этом шаге столкнулись с двумя проблемами.

Защита отрезает Python. curl проходил, а запрос из стандартного urllib получал 403 и страницу «Access Blocked». Перед сервером стоит защита Qrator, и ей не нравится User-Agent Python. Помог заголовок User-Agent как у curl. Обходить защиту агрессивнее я не стала: данные открытые, а нагрузку я держала под лимитом.

Лимит 60 запросов в минуту. Сервер честно пишет его в заголовках X-RateLimit-Limit и X-RateLimit-Remaining. Скрипт делает паузу около секунды между запросами и отступает при ошибке. Полный обход идет часами, поэтому его запускают в фоне, а не в диалоге.

Итог выгрузки на момент написания: 7 222 уникальных товара за 185 поисковых запросов, из них 2 005 укладываются в 150 ккал на 100 г. У 1 202 нет пищевой ценности. Часть из них вообще не еда (косметика, товары для дома и животных), а около 260 — овощи, фрукты, ягоды и зелень: капуста, морковь, яблоки, огурцы. Про половину тарелки каталог молчит, так что калорийность овощей придется брать из справочника.

Справочник «Легкая корзина»

Таблица на две тысячи строк в терминале бесполезна. Я попросила Claude собрать из нее страницу-справочник с поиском, фильтром по категориям, ползунком «до N ккал» и сортировкой по белку.

Скрин 10. Справочник продуктов до 150 ккал

Скрин 10. Справочник продуктов до 150 ккал

Для своей тарелки я добавила метрику «белок на 100 ккал». Она показывает, сколько сытости вы получаете за калории. У трески это 22 г белка на 100 ккал, у обезжиренного творога — около 20, у греческого йогурта 2% — 12. У салата «Винегрет» — меньше 2. Товары от 10 г белка на 100 ккал страница помечает как «белковые».

Еще одна метка — «зависит от партии». Ее получают товары, у которых один производитель укладывается в порог, а другой нет.

Корзина под мой метод

Главная задача звучала так: «Сделай мне подбор корзины продуктов, зная, как мне надо питаться, оцени стоимость на неделю». Пока Claude работал, я дописывала условия: «сделай несколько вариантов», «объедини с моими наработками и базой рецептов», «900–1000 калорий, обязательно с вкусной точкой после каждой еды».

Скрин 11. Условия, которые я добавляла по ходу

Скрин 11. Условия, которые я добавляла по ходу

Claude не начал заново после каждой реплики. Он прочитал мой конспект метода и сборники рецептов, нашел в Obsidian папку, куда мой бот складывает рецепты, и сверил ее с серверной копией. На сервере нашлась пицца на основе из куриного фарша с творогом, около 90 ккал на 100 г. Я сохраняла ее через бота в сентябре, а в домашней базе ее еще не было.

Получилось четыре корзины на одного человека на 7 дней. В каждой пять приемов пищи и вкусная точка после каждого. Потом я попросила еще варианты без готовки, и Claude добавил четыре корзины из готовой кулинарии и продуктов, которые достаточно разморозить или открыть.

Скрин 12. Первая версия страницы с корзинами

Скрин 12. Первая версия страницы с корзинами

Одних калорий мало, нужны нормы КБЖУ

Первая версия считала только калории. Тут я поняла, что не учла нормы по КБЖУ от тренера. Мои требования: до 1000 ккал, белок 78 г, жиры около 37 г и не меньше 30, углеводы около 88 г, клетчатка 25 г.

Когда я прогнала корзины по всем пяти показателям, почти все развалились. Белка выходило 55–65 г вместо 78, жиров кое-где не набиралось и 30 г, а клетчатку первая версия вообще не считала. Подогнать вручную типовой день каждой из восьми корзин у меня не получилось: добавляю белка и вылетаю за 1000 ккал, срезаю углеводы, и проседает клетчатка.

Тут Claude предложил свести все к задаче линейного программирования. Звучит страшнее, чем есть. Переменные в ней — граммы каждого продукта в дне, ограничения — мои нормы, а минимизирует она две вещи: насколько день ушел от исходного меню и, с меньшим весом, сколько он стоит. Считает все это scipy.optimize.linprog с методом HiGHS.

# упрощенно; x[i] — граммы продукта i в дне, g0[i] — исходные граммы
# минимизируем |x - g0| / g0  +  W * цена_за_грамм * x
A_ub, b_ub = [], []
A_ub.append(kcal);     b_ub.append(970)    # калории не выше 970
A_ub.append(-protein); b_ub.append(-82)    # белок не ниже 82 г
A_ub.append(-fat);     b_ub.append(-32)    # жиры 32–40 г
A_ub.append(fat);      b_ub.append(40)
A_ub.append(-fiber);   b_ub.append(-25.5)  # клетчатка от 25 г
bounds = [(g * 0.3, g * 1.8) for g in g0]  # каждый продукт 30–180% от исходного
res = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=bounds, method="highs")

Почему в коде 970 вместо 1000 и 82 вместо 78? Потом граммы округляются до удобных, и без запаса день вылетает за норму на пару граммов белка. Два дня решатель поначалу вообще отказался собирать, мол, невыполнимо: в рыбной неделе и в готовой кулинарии не хватало жиров. Выручили яйцо и масло, которому разрешили гулять от 5 до 10 г на прием. Жиры по той же причине держим в коридоре 32–40 г, а не 30–37. В финальной версии добавилось еще одно ограничение: углеводы не меньше 70 г.

Дальше я по ходу добавляла условия из жизни, и каждое меняло модель:

  • Филе покупаю сама, раз в неделю. Поэтому куриное филе из корзины ВкусВилла переехало в отдельную строку «ваше филе, N г на неделю, сырой вес», а все остальное по-прежнему добирается из ВВ.

  • Беру только филе. Голени Claude заменил на филе и заодно переписал под него мой рецепт голеней, ведь запекать филе надо по-другому и готовность проверять тоже иначе.

  • Говядину не беру. Борщ и салат «Метаболический» из книги Обложко пришлось пересчитать на курице, и калорийность блюд теперь считается из реальных ингредиентов рецепта. Для проверки посчитали уху, вышло 20,5 ккал на 100 г, а в книге 20.

  • Завтрак у меня всегда один и тот же. Белок яичный 150 г, горошек и кукуруза по 50 г, халапеньо 10 г, соус с рикоттой 20 г, перец 120–150 г, иногда маринованный огурчик. Получается около 255 ккал и 25 г белка. В модель он вошел константой, так что нормы решатель добивает остальными четырьмя приемами.

  • Немного готовки можно. Группа «без готовки» превратилась в «минимум готовки», где филе надо отварить или запечь на 2–3 дня вперед.

Итог после всех условий — все восемь дней укладываются в нормы по калориям, белку, жирам и клетчатке, углеводы держит решатель от 70 г:

Корзина

Неделя во ВкусВилле

Ваше филе на неделю

ккал

Б

Ж

Клетчатка

Домашняя духовка

≈ 5 370 ₽

718 г

966

81

32

25

Мультиварка: индейка и бобовые

≈ 6 700 ₽

560 г

978

82

32

26

Готовое из ВВ + филе

≈ 7 920 ₽

910 г

992

83

34

26

Рыбная неделя

≈ 9 850 ₽

70 г

982

87

32

26

Минимум готовки

Супная неделя

≈ 7 240 ₽

770 г

959

81

32

26

Холодная сборка

≈ 7 290 ₽

560 г

976

84

31

26

Море: минимум готовки

≈ 7 660 ₽

490 г

965

80

32

25

Офисные ланч-боксы

≈ 8 100 ₽

770 г

968

82

31

25

Корзины подорожали по сравнению с первой версией на сумму от 130 ₽ до 3 тысяч: например, «Домашняя духовка» была 4 289 ₽, стала 5 370 ₽. Это не цены ВкусВилла: в недельную сумму вошли продукты моего завтрака на 7 дней, больше овощей ради клетчатки и яйца ради жиров. Крупы, отруби, муку, масло и шоколад я вынесла в блок «запасы на 2–3 недели», в недельную сумму они не входят. Цены — каталог на 13 октября 2026 года: акции магазина в них уже учтены, персональные скидки нет.

Пример дня из корзины «Домашняя духовка»:

Прием

Еда

ккал

Вкусная точка

ккал

Завтрак

мой постоянный: белок, горошек, кукуруза, перец, халапеньо, соус с рикоттой

255

клубника 30 г

11

Перекус

йогурт 2% 100 г, сырые овощи 100 г

91

мандарин 60 г

23

Обед

борщ на курице 250 г, капустные оладьи 60 г, овощи 150 г

223

ягодное желе 30 г

12

Перекус

салат «Метаболический» 130 г, яйцо

150

шоколад 85%, 5 г

31

Ужин

филе, брокколи 140 г, отруби 10 г

142

яблоко 60 г

28

861

105

Вкусные точки занимают около 100 ккал из тысячи. Звучит расточительно, но для меня это и есть причина, по которой режим держится дольше недели.

Отчет, который можно открыть

Первую версию Claude свел в одну страницу. Там восемь корзин, нормы КБЖУ полосками, пример дня и список покупок со ссылкой на корзину ВкусВилла. Посмотреть можно здесь: https://claude.ai/artifact/BjKiBhymkTSvmps6csyoMs

Скрин 13. Сводка: нормы и корзины

Скрин 13. Сводка: нормы и корзины

Самый полезный для меня блок называется «Готовим на день», он есть у каждой корзины. В нем написано, какие блюда этого дня надо приготовить и что можно сварить партией сразу на 2–3 дня, чтобы не стоять у плиты каждый вечер. И отдельной строкой стоит, сколько граммов филе купить на неделю.

Скрин 14. День, «Готовим на день» и список покупок

Скрин 14. День, «Готовим на день» и список покупок

На название блюда можно нажать, и откроется карточка рецепта с ингредиентами, шагами и КБЖУ на 100 г. Если рецепт переделан под меня, там стоит пометка о замене, например говядина на куриное филе.

Скрин 15. Карточка рецепта

Скрин 15. Карточка рецепта

Это была первая итерация. Дальше я гоняла ее по кругу и пришла вот к такой версии: https://claude.ai/artifact/7jD9eC4LAJ9KzovXW58iA4

Финальный вариант экрана с вариантами корзин

Финальный вариант экрана с вариантами корзин

Корзин стало четыре вместо восьми, и каждая про один способ готовки: духовка, мультиварка, рыба из духовки и котлеты с тефтелями. Готовлю я теперь два вечера в неделю: в воскресенье на понедельник–среду, в среду на четверг–воскресенье. Все горячее идет в духовку или мультиварку, плита не нужна. Перекусы без готовки и каждый день разные, а в нормы решатель укладывает каждый из семи дней, а не один типовой.

Пример рецептов, и порядка готовки на неделю

Пример рецептов, и порядка готовки на неделю

Неделя стоит от 6 415 до 8 916 ₽. На неделю одна ссылка: больше 30 позиций ВкусВилл в одну не берет, поэтому там, где похожих товаров было несколько, я оставила один: один творог вместо трех разных, скир вместо скира и йогурта, одни огурцы вместо соленых и маринованных, а запасы на несколько недель вынесла в отдельную ссылку.

Перед ссылкой Claude сверяет каждую позицию с остатком по моему адресу. В день проверки не хватило трех товаров, их заменили похожими, а граммы пересчитали. Промпт к этой версии — в конце статьи.

Пример меню на неделю

Пример меню на неделю

Ссылка на корзину вместо списка покупок

На последнем шаге работает vkusvill_cart_link_create. Ему передают список товаров: id — номер товара из поиска, q — сколько положить. Обратно приходит ссылка вида vkusvill.ru/?share_basket=…. Открываете ее, а товары уже лежат в корзине.

{"products": [
  {"id": 489,   "q": 1.0},
  {"id": 26797, "q": 4},
  {"id": 38893, "q": 1}
]}

Количество q у весовых товаров считается в килограммах, у штучных в упаковках. С лимитом позиций я разобралась на живом сервере. Описание инструмента до сих пор говорит «до 20», но решает схема параметров: корзину из 31 позиции сервер отклоняет сразу, а ссылку на 30 создает, и в корзине все 30 на месте, я проверила. Остатки ссылка не сверяет: я положила в ссылку товар, которого оставалось 11 упаковок, с количеством 31, и ссылка все равно создалась. Так что перед ссылкой пусть модель сравнит q с available_quantity, иначе лишнее всплывет уже в корзине.

Еще одна странность: больше половины вызовов у меня вернули «Ошибка создания ссылки, попробуйте позже», и от размера корзины это не зависит: ссылка на один товар падала точно так же. Помогает повтор с паузой секунд в десять: ссылка на 30 товаров получилась с пятой попытки.

Скрин 16. Ссылки на корзины, первая версия, до подгонки под КБЖУ

Скрин 16. Ссылки на корзины, первая версия, до подгонки под КБЖУ

По ссылке ВкусВилл показывает окно «С вами поделились товарами», где весь список уже собран, с количеством и ценой за штуку. Мне остается нажать «Проверить наличие товаров» и выбрать адрес доставки, а если что-то лишнее, убрать его крестиком прямо в окне.

Скрин 17. Что открывается по ссылке на корзину

Скрин 17. Что открывается по ссылке на корзину

Что не получилось и где осторожнее

  • Наличие только с OAuth. Без входа сервер не знает ваш адрес, и часть корзины может не оказаться в наличии. Когда я вошла и перепроверила свои корзины, в шести из восьми чего-то не хватило: перца нужно 3, а осталось 2, горбуши в желе не оказалось вовсе.

  • Овощи и фрукты без КБЖУ. Ровно та часть тарелки, которой должно быть больше всего, в каталоге без цифр.

  • КБЖУ — диапазон. Для готовой еды разница между производителями доходит до двух-трех раз. Я считаю по верхней границе.

  • Скидки работают не так, как кажется. Каталог отдает цену уже с акцией: в моих корзинах таких товаров было четыре, от −12% до −24%. Персональные «6 скидок» сервер со входом тоже отдает (vkusvill_discounts_personal): мне пришло 18 предложений по −20%, но в корзины из них попал только щавелевый суп, и «Офисные ланч-боксы» подешевели всего на 88 ₽. Если хотите на скидках сэкономить, пусть модель сначала возьмет список персональных скидок и подбирает замены под него. Итог в корзине может отличаться, по моим прикидкам, на 5–10% в обе стороны.

Как повторить у себя

1. Подключите сервер командой claude mcp add --transport http vkusvill https://mcp.vkusvill.ru/mcp. Это публичные инструменты. Если планируете вход, сразу переходите к шагу 3: там подключение другое.

2. Хотите видеть наличие по своему адресу, историю заказов и персональные скидки — зарегистрируйте своего агента на vkusvill.ru/oauth/registration. В форме нужны название, почта, Redirect URI http://localhost:8765/callback и все четыре галочки доступов: скрипт ниже просит именно их, и если отметить меньше, ВкусВилл ответит invalid_scope. localhost — это ваш же компьютер, так что адрес у всех одинаковый, а порт 8765 можно взять любой свободный: главное, чтобы он совпадал в форме и в константе PORT в скрипте. Client ID и Client Secret придут на почту из формы. Секрет никому не пересылайте, даже в чат с моделью.

3. Войти через /mcp у меня не вышло, и у вас, скорее всего, тоже не выйдет. Claude Code сам добавляет к запросу доступ offline_access, чтобы продлевать токен без повторного входа: так он делает, когда сервер авторизации объявляет его поддержку, а ВкусВилл объявляет. Убрать его не выйдет даже настройкой oauth.scopes. А клиенту, которого вы зарегистрировали через форму, этот доступ не выдан: галочки для него там нет. ВкусВилл отвечает ошибкой invalid_scope, и дело тут не в ключах. Поэтому токен я получаю сама, коротким скриптом с PKCE и только четырьмя доступами из формы:

# vv_token.py — токен ВкусВилла без offline_access
# python vv_token.py          — войти через браузер и сохранить токен
# python vv_token.py --header — отдать заголовок для headersHelper в Claude Code
import base64, hashlib, http.server, json, os, secrets, sys, time
import urllib.parse, urllib.request, webbrowser

CLIENT_ID = os.environ.get("VV_CLIENT_ID", "")
CLIENT_SECRET = os.environ.get("VV_CLIENT_SECRET", "")
PORT = 8765  # тот же порт, что в Redirect URI в форме ВкусВилла
REDIRECT = f"http://localhost:{PORT}/callback"
SCOPE = "catalog.search purchase_history.read discounts.view recommendations.personalized"
TOKEN_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "vv-token.json")

if "--header" in sys.argv:
    t = json.load(open(TOKEN_FILE))
    if t["expires_at"] < time.time():
        sys.exit("токен ВкусВилла истек, запустите vv_token.py без --header")
    print(json.dumps({"Authorization": "Bearer " + t["access_token"]}))
    sys.exit()

if not CLIENT_ID or not CLIENT_SECRET:
    sys.exit("задайте переменные VV_CLIENT_ID и VV_CLIENT_SECRET из письма ВкусВилла")
verifier = secrets.token_urlsafe(64)
challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest()).rstrip(b"=").decode()
state = secrets.token_urlsafe(16)
webbrowser.open("https://oauth.vkusvill.ru/oauth2/auth?" + urllib.parse.urlencode({
    "response_type": "code", "client_id": CLIENT_ID, "redirect_uri": REDIRECT, "scope": SCOPE,
    "state": state, "code_challenge": challenge, "code_challenge_method": "S256"}))

got = {}
class Callback(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        got.update(urllib.parse.parse_qsl(urllib.parse.urlparse(self.path).query))
        self.send_response(200)
        self.send_header("Content-Type", "text/plain; charset=utf-8")
        self.end_headers()
        self.wfile.write("Готово, вкладку можно закрыть".encode())

server = http.server.HTTPServer(("localhost", PORT), Callback)
while "code" not in got and "error" not in got:
    server.handle_request()
if got.get("state") != state or "code" not in got:
    sys.exit("вход не прошел: " + got.get("error_description", got.get("error", "state не совпал")))

req = urllib.request.Request("https://oauth.vkusvill.ru/oauth2/token", headers={"User-Agent": "curl/8.5.0"},
    data=urllib.parse.urlencode({"grant_type": "authorization_code", "code": got["code"],
        "redirect_uri": REDIRECT, "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET,
        "code_verifier": verifier}).encode())
tok = json.load(urllib.request.urlopen(req))
json.dump({"access_token": tok["access_token"], "expires_at": time.time() + tok.get("expires_in", 3600)},
          open(TOKEN_FILE, "w"))
print("Токен сохранен, действует", tok.get("expires_in", 3600) // 3600, "ч")

Client ID и Client Secret скрипт берет из переменных VV_CLIENT_ID и VV_CLIENT_SECRET, так секрет не попадет ни в код, ни в чат. Скрипт откроет браузер, ВкусВилл покажет обычный экран согласия, а токен ляжет в vv-token.json рядом со скриптом. Живет он около суток, потом скрипт нужно запустить еще раз. Если личные инструменты вдруг перестали отвечать, первым делом проверьте токен.

Скрин 18. Экран согласия ВкусВилла

Скрин 18. Экран согласия ВкусВилла

Осталось отдать токен серверу. Для этого в Claude Code есть настройка headersHelper: она запускает скрипт при каждом подключении к серверу и подставляет заголовок Authorization: Bearer. Сервер, подключенный на первом шаге, сначала удалите:

claude mcp remove vkusvill
claude mcp add-json vkusvill '{"type":"http","url":"https://mcp.vkusvill.ru/mcp","headersHelper":"python /путь/к/vv_token.py --header"}'

На Mac и в Linux вместо python обычно нужно написать python3, а путь к скрипту — полный. В Windows команду удобнее запускать из Git Bash или WSL: в cmd и старом PowerShell кавычки внутри JSON ломаются. После этого перезапустите Claude Code.

4. Расскажите модели про себя одним блоком. Я писала туда цель, нормы КБЖУ, как устроена тарелка, какие блюда у меня постоянные, что люблю и чего не ем.

5. Не торопитесь с корзиной. Сначала пусть модель сделает справку по категориям, и разброс КБЖУ вылезет раньше, чем испортит вам расчет.

6. Через диалог весь каталог не вытащить, тут нужен скрипт, который ходит в MCP напрямую. Только поставьте паузу, иначе упретесь в лимит 60 запросов в минуту.

7. Нормы пусть подгоняет решатель. Пять показателей сразу руками не сводятся, я пробовала.

8. А в конце попросите ссылку на корзину, чтобы не перебивать список покупок руками. Больше 30 позиций в одну ссылку не кладите, перед ссылкой пусть модель сверит количество в корзине с остатком, а если сервер ответит «попробуйте позже», пусть повторяет запрос секунд через десять, пока ссылка не соберется.

А вот промпт уже к финальной версии, его можно брать целиком. Строка про наличие работает, только если вы вошли во ВкусВилл, шаг 3:

Подбери корзины ВкусВилла на неделю на одного человека.
Питаюсь по метаболической тарелке. Нормы на день: до 1000 ккал, белок от 78 г,
жиры 30–37 г, углеводы от 70 г, клетчатка от 25 г. 5 приемов пищи.
Масло — не больше 1 ст. л. в день.
Завтрак всегда одинаковый: <состав>, его не меняй.
Куриное филе покупаю сама, выпиши граммы на неделю отдельно.
Тарелка: половина — овощи 100–150 г, четверть — белок 60–100 г,
четверть — сложные углеводы 60–100 г, жиров минимум.
После каждого приема — вкусная точка до 60 ккал.
Готовлю два вечера в неделю: в воскресенье на понедельник–среду,
в среду на четверг–воскресенье. Все горячее — в духовке или мультиварке.
Перекусы без готовки и каждый день разные.
Возьми блюда из моих рецептов: <путь к папке>.
Сделай четыре корзины, каждую под один способ готовки,
у каждой меню на 7 дней, список покупок с ценой и ссылку на корзину.
Подгони граммы под нормы через линейную оптимизацию, каждый день отдельно.
Бери только то, что есть в наличии по моему адресу, и не больше, чем осталось.
Перед ссылкой сверь каждую позицию с остатком; чего не хватает — замени похожим и пересчитай граммы.
Корзина на неделю — одна ссылка, не больше 30 позиций. Если позиций больше, бери один товар там, где их несколько похожих: один творог вместо трех разных, одни огурцы вместо соленых и маринованных.
Если сервер ответит «попробуйте позже», повтори через 10 секунд.
Запасы на несколько недель вынеси в отдельную ссылку, в недельную сумму их не считай.

Самое ценное для меня тут даже не сэкономленное время у полки. У меня впервые сошлись вместе метод, нормы тренера, мои рецепты и реальный магазин с ценами, а раньше каждое жило в своем углу. Теперь корзина на неделю собирается за один запрос, и листать карточки я наконец перестала.

Делитесь своим опытом, какие приемы AI помогли вам в решении бытовых задач.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.