likes-store-mcp
by trueblackat
README.md
# likes-store-mcp
MCP-сервер likes-store для агентств. Подключает ИИ-ассистента (Claude Desktop, Claude Code, Cursor или любой другой MCP-клиент) к вашему аккаунту likes-store: ассистент видит каталог с вашими ценами и баланс, считает точную стоимость заказа, оформляет его после вашего согласия и следит за статусами. Лайки, просмотры, подписчики и комментарии в Instagram\*, TikTok, ВКонтакте, Telegram и на других площадках из каталога можно заказывать обычной фразой в чате, не открывая кабинет.
Сервер работает поверх API для агентств (`/api/v1`) и умеет ровно то, что открывает ключ API. Весь сервер — один файл на Node.js без единой зависимости.
## Что умеет
| Инструмент | Что делает |
| --- | --- |
| `list_services` | Каталог услуг с ценой для вашего аккаунта: границы количества, цена за штуку, скидки за объём, подсказки к ссылке. Фильтры по площадке, типу и строке поиска. |
| `get_balance` | Баланс: основной и подарочный. |
| `list_projects` | Проекты агентства, по одному на клиента. Можно вместе с архивными. |
| `quote_order` | Примерка заказа: проверяет ссылку и количество, считает сумму со всеми скидками и говорит, хватает ли денег. Ничего не списывает. |
| `place_order` | Оформляет заказ по примерке и списывает деньги с баланса. |
| `get_order` | Заказ по номеру: статус, сколько выполнено, сколько вернулось на баланс. |
| `list_orders` | Заказы постранично, с фильтрами по статусу, проекту и периоду. |
| `topup_link` | Ссылка на форму пополнения баланса в кабинете. |
У каждого инструмента заданы все четыре подсказки из спецификации MCP (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`), по которым клиент решает, когда спрашивать ваше подтверждение. Семь инструментов только читают; `place_order` помечен как необратимый (`destructiveHint: true`), потому что тратит деньги, и как безопасный для повтора (`idempotentHint: true`), потому что повтор второго заказа не ставит.
## Как устроен заказ
Заказ проходит в три шага, и третий без первых двух невозможен.
1. `quote_order` делает примерку: сайт проверяет ссылку, количество и потолки и возвращает точную сумму. Ассистент показывает вам строку вроде «5 000 шт. «Лайки» (Instagram\*) по ссылке https://instagram.com/p/… за 1 350 ₽ (скидка за объём 23 %), с баланса спишется 1 350 ₽».
2. Вы соглашаетесь или нет. Описание `place_order` прямо требует от ассистента дождаться вашего явного согласия на эту сумму.
3. `place_order` принимает только номер примерки (`quoteId`), поэтому заказать то, чего вы не видели, ассистент не может.
Цена из примерки уходит в API как верхняя граница (`maxPrice`). Если за время раздумий цена выросла, заказ не оформится и деньги не спишутся; ассистент сделает новую примерку и снова покажет сумму.
Номер примерки уходит заголовком `Idempotency-Key`, и это защищает от двойного списания. Повторный `place_order` с тем же `quoteId` вернёт уже оформленный заказ, а не поставит второй. На этом держится и поведение при сбоях: если сеть оборвалась, сайт не ответил за 30 секунд или прокси вернул 502, сервер один раз повторяет запрос с тем же ключом. Когда исход так и остаётся неизвестным, ассистент получает прямой текст: «заказ мог оформиться, повторите с тем же quoteId — второго не будет».
Примерка живёт 15 минут в памяти сервера. После перезапуска сервера или по истечении срока нужна новая примерка, а значит, и новое согласие.
## Где взять ключ
Ключ выпускается в кабинете, раздел «API»: `https://likes-store.com/dashboard/api`. Раздел открыт аккаунтам со статусом агентства, заявка на статус — на странице `https://likes-store.com/agency`. Ключ показывается один раз, сразу после выпуска.
Выпустите для ассистента отдельный ключ, не тот, на котором работают ваши скрипты: его можно отозвать, ничего больше не сломав. Ассистенту, который только смотрит, дайте ключ «только чтение» и запускайте сервер с `LS_READONLY=1`. Ассистенту, который заказывает, задайте у ключа дневной потолок трат: тогда даже ошибка обойдётся не дороже потолка.
## Установка
Нужен Node.js версии 18 или новее (в нём есть встроенный `fetch`). Проверить: `node --version`.
Дальше есть два пути.
**Ничего не устанавливать.** Запускать прямо из GitHub:
```
npx -y github:trueblackat/likes-store-mcp
```
**Скачать репозиторий себе.** Так запуск быстрее и не зависит от сети:
```
git clone https://github.com/trueblackat/likes-store-mcp.git
cd likes-store-mcp
node likes-store-mcp.mjs
```
Запущенный без флагов сервер ничего не печатает и ждёт команд MCP-клиента на стандартном вводе. Так и должно быть: запускает его сам клиент. Остановить: Ctrl+C.
## Проверить ключ
```
LS_API_KEY=ls_... npx -y github:trueblackat/likes-store-mcp --check
```
Из скачанной папки то же самое: `LS_API_KEY=ls_... node likes-store-mcp.mjs --check`.
С рабочим ключом сервер напечатает:
```
Адрес: https://likes-store.com
Ключ рабочий.
Баланс: 12 500 ₽, подарочный: 300 ₽
Услуг доступно: 142
```
и завершится с кодом 0. Если ключа нет, он отозван или сайт недоступен, будет понятная причина и код 1.
## Подключить
### Claude Desktop
Откройте файл настроек: в самом Claude Desktop это «Settings → Developer → Edit Config», а на диске он лежит в `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) или `%APPDATA%\Claude\claude_desktop_config.json` (Windows). Добавьте блок `mcpServers`:
```json
{
"mcpServers": {
"likes-store": {
"command": "npx",
"args": ["-y", "github:trueblackat/likes-store-mcp"],
"env": {
"LS_API_KEY": "ls_..."
}
}
}
}
```
Если репозиторий скачан, вместо `npx` укажите `node` и абсолютный путь к файлу:
```json
{
"mcpServers": {
"likes-store": {
"command": "node",
"args": ["/абсолютный/путь/likes-store-mcp/likes-store-mcp.mjs"],
"env": {
"LS_API_KEY": "ls_..."
}
}
}
}
```
На Windows обратные косые черты в пути удваиваются: `"C:\\mcp\\likes-store-mcp\\likes-store-mcp.mjs"`. После правки перезапустите Claude Desktop. Если Claude Desktop пишет, что не находит `npx` или `node` (так бывает, когда Node.js поставлен через nvm), укажите в `command` полный путь из `which npx` или `which node`.
### Claude Code
Одной командой:
```
claude mcp add --env LS_API_KEY=ls_... --transport stdio likes-store -- npx -y github:trueblackat/likes-store-mcp
```
Или из скачанной папки: `claude mcp add --env LS_API_KEY=ls_... --transport stdio likes-store -- node /абсолютный/путь/likes-store-mcp/likes-store-mcp.mjs`.
Порядок важен: имя сервера (`likes-store`) не должно стоять сразу после `--env LS_API_KEY=…`, иначе Claude Code прочтёт его как ещё одну переменную и откажется добавлять сервер.
Чтобы сервер был доступен во всех проектах, а не только в текущем, добавьте `--scope user` перед именем сервера:
```
claude mcp add --env LS_API_KEY=ls_... --transport stdio --scope user likes-store -- npx -y github:trueblackat/likes-store-mcp
```
### Cursor
Тот же блок `mcpServers`, что и для Claude Desktop, в файле `~/.cursor/mcp.json` (для всех проектов) или `.cursor/mcp.json` в папке проекта.
### Другие клиенты
Подойдёт любой клиент, который запускает локальные MCP-серверы по stdio: команда `npx` с аргументами `-y github:trueblackat/likes-store-mcp` (или `node` и путь к файлу), ключ — в переменной окружения `LS_API_KEY`. Сервер понимает обе версии протокола: с рукопожатием `initialize` (2024-11-05 … 2025-11-25) и без него (2026-07-28).
## Примеры запросов
Названия инструментов ассистенту знать не нужно, достаточно сказать, что сделать.
- **«Сколько будут стоить 10 000 лайков на этот пост? https://instagram.com/p/…»** — `list_services` находит услугу, `quote_order` считает сумму со скидкой за объём и проверяет, хватает ли денег.
- **«Оформляй»** — `place_order` по только что показанной примерке.
- **«Что с заказами клиента „Кофейня“ за эту неделю?»** — `list_projects` находит проект, `list_orders` выбирает его заказы с понедельника.
- **«Хватит ли денег на 50 000 просмотров в Telegram?»** — `quote_order`; если не хватает, `topup_link` даёт ссылку на пополнение и называет недостающую сумму.
## Переменные окружения
| Переменная | Обязательна | Значение |
| --- | --- | --- |
| `LS_API_KEY` | да | Ключ API агентства. Без него инструменты отвечают подсказкой, где взять ключ. |
| `LS_API_URL` | нет | Адрес сайта, в кабинете которого вы выпустили ключ. По умолчанию `https://likes-store.com`. От него строятся ссылки на пополнение и на раздел «API». |
| `LS_READONLY` | нет | `1` — без инструмента заказа: `place_order` не появляется в списке вовсе. |
| `LS_TIMEOUT_MS` | нет | Таймаут одного запроса, по умолчанию 30 000 мс. |
| `LS_QUOTE_TTL_MS` | нет | Сколько живёт примерка, по умолчанию 900 000 мс (15 минут). |
## Чего сервер не умеет и почему
- **Пополнять баланс и выводить деньги.** Деньги заводит и выводит человек, в кабинете, своей картой. `topup_link` только даёт ссылку на форму, а сумму называет словами: подставить её в форму по ссылке нельзя.
- **Заказывать свои комментарии**, то есть комментарии с вашим текстом. Писать тексты от имени живых людей ассистенту мы не поручаем, поэтому такие услуги в каталоге сервера не показываются; заказать их можно в кабинете. Обычные комментарии без своего текста в каталоге есть.
- **Отменять заказы.** В API такой операции нет. Если заказ не выполнится целиком, невыполненная часть вернётся на баланс сама.
- **Подключаться как удалённый коннектор по адресу.** Сервер локальный: он запускается на вашем компьютере, и ключ уходит только на адрес из `LS_API_URL`.
## Ключ и безопасность
Ключ открывает заказы от имени вашего аккаунта и трату денег с его баланса. Не отправляйте его в чаты, не коммитьте в git и не вставляйте в сам разговор с ассистентом: ключ нужен только в настройках клиента. Сервер ключ не печатает ни в ответах, ни в журнале. Если ключ всё-таки утёк, отзовите его в кабинете (раздел «API») и выпустите новый.
Частота запросов ограничена сайтом: 60 в минуту на ключ. Если ассистент упрётся в лимит, сервер подождёт, сколько попросит сайт (не дольше 10 секунд), и повторит запрос один раз.
## Разработка
```
npm test
```
Тесты запускают сервер отдельным процессом и говорят с ним по stdio, как настоящий MCP-клиент, а вместо сайта поднимают поддельное API на `node:http`. Ни сеть, ни ключ не нужны; зависимостей нет, всё на встроенном `node:test`.
## Лицензия
MIT, полный текст — в [LICENSE](LICENSE).
---
\* Instagram и Facebook принадлежат Meta, признанной в России экстремистской организацией.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues