Skip to main content
Glama
bbwrl

Shopping List MCP Server

by bbwrl

Приложение «Список покупок»

Простое приложение для списка покупок, созданное с помощью Next.js 15 (App Router). Каждый продукт принадлежит человеку, может быть отмечен как купленный и удалён.

Этот проект намеренно небольшой — это учебный/тренировочный проект для IMS Praxis 5.

Возможности

  • Добавлять продукты, отмечать их как купленные, удалять

  • Фильтровать по человеку

  • Хранение данных в простом JSON-файле (не требуется сервер базы данных)

  • Три способа работы с данными:

    • Server Actions – используется напрямую фронтендом (src/app/actions.ts)

    • REST API – доступен по адресу /api/products, например, для внешних клиентов или curl

    • MCP server – предоставляет те же данные в виде инструментов MCP (например, для ChatGPT), вызывая REST API

Related MCP server: LystBot

Технологический стек

  • Next.js 15 / React 19, App Router

  • TypeScript

  • Нет базы данных, нет ORM – хранение в JSON-файле (data/products.json)

  • MCP TypeScript SDK через mcp-handler, использующий Streamable HTTP transport

Начало работы

npm install
npm run dev

Откройте приложение по адресу http://localhost:3000.

Для локального запуска приложения не требуется ни конфигурации, ни файла .env. См. Переменные окружения для одной необязательной настройки, используемой MCP-сервером.

Структура проекта

src/
  app/
    page.tsx            # Home page (Server Component), loads products server-side
    actions.ts           # Server Actions: addProductAction, togglePurchasedAction, deleteProductAction
    api/
      products/
        route.ts          # GET /api/products, POST /api/products
        [id]/route.ts      # GET/PATCH/DELETE /api/products/:id
      [transport]/
        route.ts          # MCP endpoint (Streamable HTTP), served at /api/mcp
  components/
    ProductForm.tsx        # Add-product form (uses a Server Action)
    ProductList.tsx        # List incl. toggle/delete (uses Server Actions)
  lib/
    productRepository.ts   # the only place that touches the filesystem (data/products.json)
    mcp/
      server.ts             # registers the MCP tools
      shoppingApiClient.ts   # MCP's only way to reach the data — calls the REST API, never the repository directly
  types/
    product.ts             # Product type

data/
  products.json            # data store (created automatically if missing)

Модель данных

interface Product {
  id: string;
  name: string;
  person: string;
  purchased: boolean;
  createdAt: string; // ISO date
}

Хранение данных

Все продукты хранятся в data/products.json. Весь доступ к файлу инкапсулирован в src/lib/productRepository.ts — ни пользовательский интерфейс, ни маршруты API не читают и не записывают файл напрямую. Репозиторий предоставляет:

getProducts()
getProductsByPerson(person)
getProductById(id)
addProduct(product)
updateProduct(id, changes)
deleteProduct(id)

Примечание: Это файловое хранение намеренно является лишь прототипным/разработочным решением. На Vercel (и других серверных платформах) локальная файловая система не обеспечивает надёжного сохранения данных между запросами или развёртываниями — записи могут быть потеряны. Для production-использования productRepository.ts следует заменить на настоящую постоянную базу данных (например, Turso). Поскольку остальная часть приложения (UI, Server Actions, маршруты API) взаимодействует с данными только через экспортированные функции репозитория, такая замена затрагивает лишь один этот файл.

Фронтенд ↔ Бэкенд

Фронтенд (page.tsx, ProductForm, ProductList) использует Next.js Server Actions (src/app/actions.ts) для создания, обновления и удаления продуктов. В клиенте нет вызова fetch — Server Actions напрямую вызывают репозиторий, а затем запускают обновление серверно отрисованных данных через revalidatePath("/").

REST API по адресу /api/products независим и может использоваться отдельно (например, внешними инструментами, скриптами или для тестирования) — он читает и записывает тот же источник данных.

REST API

Получение продуктов

GET /api/products
GET /api/products?person=Rinaldo   # filter by person, case-insensitive
GET /api/products/:id

Добавление продукта

POST /api/products
Content-Type: application/json

{ "name": "Milk", "person": "Rinaldo" }

id, purchased (false) и createdAt устанавливаются автоматически.

Обновление продукта

PATCH /api/products/:id
Content-Type: application/json

{ "purchased": true }

Не все поля должны быть указаны (name, person, purchased — каждое опционально и может обновляться независимо).

Удаление продукта

DELETE /api/products/:id

Ответы с ошибками

{ "error": "Product not found" }

Случай

Status

Некорректный/пустой запрос

400

Неизвестный ID

404

Внутренняя ошибка

500

Примеры curl

# Add a product
curl -X POST http://localhost:3000/api/products \
  -H "Authorization: Bearer $SHOPPING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Milk","person":"Rinaldo"}'

# List a person's products
curl "http://localhost:3000/api/products?person=Rinaldo" \
  -H "Authorization: Bearer $SHOPPING_API_KEY"

# Mark a product as purchased
curl -X PATCH http://localhost:3000/api/products/PRODUCT_ID \
  -H "Authorization: Bearer $SHOPPING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"purchased":true}'

# Delete a product
curl -X DELETE http://localhost:3000/api/products/PRODUCT_ID \
  -H "Authorization: Bearer $SHOPPING_API_KEY"

MCP Server

Сервер Model Context Protocol предоставляет список покупок MCP-клиентам (например, ChatGPT). Он общается только с вышеуказанным REST API — никогда напрямую с productRepository.ts или data/products.json — поэтому остаётся независимым от используемого бэкенда хранения данных.

MCP client → MCP server → REST API → productRepository → data/products.json

Конечная точка: /api/mcp (Streamable HTTP transport), реализована в src/app/api/[transport]/route.ts через mcp-handler.

Инструменты:

Инструмент

Описание

list_products

Список продуктов, опционально отфильтрованных по человеку

add_product

Добавить продукт для человека

update_product

Обновить имя/человека/куплен у продукта

mark_product_purchased

Удобный инструмент для отметки продукта как (не) купленного

delete_product

Удалить продукт

Требует тот же bearer-токен, что и REST API (см. Аутентификация). Протестируйте локально с помощью MCP Inspector:

npx @modelcontextprotocol/inspector --cli http://localhost:3000/api/mcp --method tools/list \
  --header "Authorization: Bearer $SHOPPING_API_KEY"

Переменные окружения

Переменная

Обязательная

Описание

SHOPPING_API_BASE_URL

Нет

Базовый URL, который MCP-сервер использует для вызова REST API. По умолчанию http://localhost:3000 локально или https://$VERCEL_URL на Vercel. Установите явно, если в production используется собственный домен.

SHOPPING_API_KEY

Да

Общий секрет, требуемый в виде Authorization: Bearer <key> для REST API и конечной точки MCP. Запросы без соответствующего токена отклоняются.

См. .env.example.

Аутентификация

REST API и конечная точка MCP требуют bearer-токен — единый общий секрет, задаваемый через SHOPPING_API_KEY. Логин для каждого пользователя отсутствует; это простая проверка статического токена, подходящая для прототипа, а не для полноценного OAuth.

curl http://localhost:3000/api/products \
  -H "Authorization: Bearer $SHOPPING_API_KEY"

Запрос с отсутствующим или неверным токеном получает 401 Unauthorized. Если SHOPPING_API_KEY вообще не установлен на сервере, запросы отклоняются с кодом 500 (закрытый отказ, а не открытый).

Server Actions (src/app/actions.ts) не затрагиваются — они вызывают productRepository напрямую на сервере и никогда не проходят через REST API, поэтому им не нужен токен.

Известные ограничения

  • Отсутствие аутентификации/авторизации как на REST API, так и на MCP-сервере — любой может просматривать и редактировать все продукты. Планируется как последующее улучшение.

  • Одновременные записи сериализуются в рамках одного процесса (простая очередь в productRepository.ts), что хорошо для прототипа, но не для production-развёртываний с несколькими экземплярами.

  • Как отмечено выше, хранение данных небезопасно при развёртывании на бессерверных платформах, таких как Vercel — следующем шагом предусмотрена настоящая база данных (например, Turso).

Развёртывание

Приложение можно развернуть как любой проект Next.js, например, на Vercel. Перед использованием в production следует заменить уровень хранения данных (см. выше) на настоящую базу данных.

Подробнее о Next.js: Next.js Documentation · Learn Next.js

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Shopping MCP for AI agents: search, compare, Amazon buy links. Auto-register.

  • Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.

  • Connect e-commerce and marketing data to AI assistants via MCP.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bbwrl/shopping-list-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server