Lumenco Catalog MCP Server
Каталог Lumenco (скрапер Phase 1 + MCP Phase 2)
В этом репозитории два уровня:
Phase 1 собирает данные с
https://en.staging.lumenco.ca/в PostgreSQL.Phase 2 предоставляет этот каталог через read-only сервер Model Context Protocol, чтобы Claude мог получать товары, спецификации, списки и кандидатов для рекомендаций без просмотра Lumenco.
CLAUDE
│ MCP / HTTPS
▼
Lumenco Product Database (Streamable HTTP)
│ tools → services → repositories
▼
PostgreSQL (Phase 1 catalog)Phase 1 собирает. Phase 2 предоставляет. Claude рассуждает.
MCP-сервер никогда не собирает данные с Lumenco, не скачивает PDF-файлы спецификаций, не вызывает LLM и не пишет в базу данных.
Как выглядит сайт
Стейджинг Lumenco — это витрина Magento 2.
Область | Поведение |
Бренды |
|
Списки брендов |
|
Товары | Канонические URL, например |
Спецификации | Обычно PDF-файлы того же origin в |
Sitemap |
|
GraphQL |
|
Загрузка | Страницы товаров рендерятся на сервере. HTTP |
Краулер остаётся на en.staging.lumenco.ca. Внешние PDF-файлы Specification Sheet могут скачиваться как документы товаров. Реклама, аналитика, корзина, оформление заказа и URL соцсетей игнорируются.
robots.txt написан для публичных поисковых систем (User-agent: * запрещает большинство путей, кроме /brand и нескольких CMS-страниц). Этот скрапер — авторизованный сбор данных каталога со стейджинга, поэтому ROBOTS_TXT_OBEY по умолчанию имеет значение false. Установите его в true, если хотите, чтобы Scrapling учитывал этот файл.
Related MCP server: Catalog Services MCP Server
Структура проекта
scraper/ Phase 1 Scrapling crawler
config.py
spider.py
discovery.py
fetcher.py
cli.py
selectors/
parsers/
pipelines/
database/ shared SQLAlchemy models + repositories
utils/
app/ Phase 2 read-only MCP server
server.py Streamable HTTP + /health
config.py
auth/middleware.py bearer token (replaceable with OAuth)
tools/ MCP tool layer
services/ catalog / product / search / recommendations
repositories/ read-only queries over Phase 1 tables
schemas/
database/session.py pooled, read-only sessions
alembic/ PostgreSQL migrations
tests/
scripts/create_readonly_user.sql1. Установка зависимостей
Требуется Python 3.10+.
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
pip install -r requirements.txtHTTP/браузерные дополнения Scrapling включены через scrapling[fetchers]. Если нужен браузерный запасной вариант (DynamicFetcher), установите бинарники браузера:
scrapling installНеобязательный OCR для сканированных/только-изображения PDF-спецификаций:
pip install pytesseract Pillow
# plus a Tesseract OCR engine on the hostOCR по умолчанию выключен (ENABLE_OCR=false). PDF-файлы на основе изображений сохраняются и помечаются ocr_required, а не сохраняются как пустой текст.
2. Настройка PostgreSQL
Самая быстрая локальная настройка:
docker compose up -d postgresЭто запускает PostgreSQL 16 с:
пользователь:
lumencoпароль:
lumencoбаза данных:
lumencoпорт хоста:
5433(порт контейнера остаётся5432; 5433 позволяет избежать конфликта с установкой PostgreSQL на Windows, которая уже использует 5432)
Скопируйте конфигурацию окружения:
copy .env.example .env # Windows
cp .env.example .env # macOS / LinuxСтрока подключения по умолчанию:
DATABASE_URL=postgresql+psycopg2://lumenco:lumenco@127.0.0.1:5433/lumenco
LUMENCO_BASE_URL=https://en.staging.lumenco.ca/Создайте таблицы (подойдёт любой из вариантов):
python -m scraper init-db
python -m alembic upgrade head3. Запуск тестового краула на 5 товаров
python -m scraper crawl --limit 5Это обнаруживает товары с живого сайта, обрабатывает только первые 5, скачивает их Specification Sheet, сохраняет строки в PostgreSQL и выводит отчёт о крауле.
Также можно закрепить бренд:
python -m scraper crawl --limit 5 --url https://en.staging.lumenco.ca/brand/aaledИли отдельный товар:
python -m scraper crawl --url https://en.staging.lumenco.ca/aaled-aa-900018-1x4-bl.html4. Запуск полного краула
python -m scraper crawlЭто обходит все бренды (и списки категорий), проходит все страницы пагинации и собирает каждый обнаруживаемый товар. Не путайте --limit с ограничением производственного каталога — --limit предназначен только для разработки.
Ограничение скорости встроено: конкурентность, лимиты на домен, задержка скачивания, повторы с экспоненциальной задержкой и опциональный AutoThrottle. Настройте их в .env:
MAX_CONCURRENCY=5
CONCURRENT_REQUESTS_PER_DOMAIN=3
DOWNLOAD_DELAY=0.5
RETRY_COUNT=3
AUTOTHROTTLE_ENABLED=true5. Возобновление краула
Контрольные точки Scrapling включены через CRAWL_DIR (по умолчанию ./data/crawl). Нажмите Ctrl+C один раз для корректной паузы. Запустите снова с:
python -m scraper crawl --resumeПоведение при возобновлении:
Scrapling восстанавливает ожидающие запросы из
CRAWL_DIR.Товары, уже сохранённые со статусом
scrape_status=success, пропускаются, если не передать--force.Неудачные товары повторяются.
PDF-файлы спецификаций не извлекаются повторно, если хэш документа не изменился.
6. Просмотр базы данных
python -m scraper stats
python -m scraper validate
python -m scraper product --sku aa-900018-1x4-blИли с помощью psql:
psql postgresql://lumenco:lumenco@127.0.0.1:5433/lumencoПолезные запросы:
SELECT count(*) FROM products;
SELECT sku, product_name, price, brand FROM products ORDER BY last_scraped_at DESC LIMIT 20;
SELECT p.sku, d.filename, d.extraction_status, left(d.extracted_text, 200)
FROM specification_documents d
JOIN products p ON p.id = d.product_id
WHERE d.extraction_status = 'extracted'
LIMIT 10;7. Как обрабатываются Specification Sheet
Для каждой страницы товара парсер ищет:
a.document-item-link(элемент управления "Specification Sheet" от Lumenco)Эквивалентные метки: Specification Sheet, Spec Sheet, Specifications, Technical Data, PDF, Fiche technique и т. д.
Затем конвейер:
Сохраняет URL документа.
Скачивает файл с помощью
httpx(не браузера).Проверяет магические байты PDF (
%PDF).Сохраняет детерминированную копию:
data/specifications/{sku}_{hash16}.pdf.Извлекает текст с помощью PyMuPDF.
Очищает пробелы, сохраняя разрывы страниц/разделов.
Сохраняет извлечённый текст, SHA-256 хэш, метод и статус.
Разбирает строки
Label: Valueиз PDF без выдумывания полей.Объединяет спецификации из PDF со спецификациями со страницы товара, сохраняя источник:
{
"Voltage": {
"value": "120-277V",
"source": "product_page",
"raw": "120-277V",
"normalized": {"min": 120, "max": 277, "unit": "V"}
}
}Если в PDF мало текста или его нет, статус — ocr_required (или OCR выполняется, когда ENABLE_OCR=true). Пустые успешные извлечения не сохраняются молча.
Неизменённые PDF-файлы пропускаются при последующих краулах по хэшу содержимого.
8. Устранение неполадок с неудачными товарами
Симптом | Что делать |
| Прочитайте JSON-список |
Товар не прошёл HTTP 5xx / таймаут | Повторно запустите |
Отсутствует Specification Sheet | Ожидаемо для некоторых SKU. Статус — |
PDF помечен | Включите OCR-дополнения или просмотрите сохранённый файл в |
PDF помечен | Связанный файл не был PDF (страница ошибки HTML и т. п.). Проверьте |
Дублирующиеся товары | Не должно происходить: уникальные |
Страницы брендов выглядят пустыми | Убедитесь, что вы на |
Ошибки DynamicFetcher | Запустите |
Ошибки подключения к базе данных | Проверьте |
Структурированные журналы выглядят так:
[INFO] PRODUCT_FETCH url=https://en.staging.lumenco.ca/aaled-aa-900018-1x4-bl.html sku=aa-900018-1x4-bl status=success
[INFO] SPEC_SHEET sku=aa-900018-1x4-bl status=extracted duration=0.84s
[ERROR] SPEC_SHEET sku=... status=failed error=...Тесты
pytestПокрытие включает нормализацию URL, разбор товара/SKU/цены, обнаружение spec-sheet, извлечение PDF, upsert в базу данных / предотвращение дубликатов, порядок элементов списков, оценку рекомендаций и интеграцию MCP-инструментов.
Справочник CLI
python -m scraper crawl --limit 100
python -m scraper crawl --mode development --limit 100 --url https://en.staging.lumenco.ca/brand/aaled
python -m scraper crawl --resume
python -m scraper reprocess-specs
python -m scraper embeddings --limit 100
python -m scraper embedding-stats
python -m scraper recommend --sku ABC123 --type related --limit 5
python -m scraper recommendation-eval
python -m scraper validate
python -m scraper stats
python -m scraper sample
python -m scraper product --sku ABC123
python -m scraper init-db
python -m app.serverРежим краула по умолчанию — development: максимум 100 успешно обработанных товаров, только бренды (без обхода категорий). Полный краул каталога отклоняется, если не передать --mode full --limit N или --mode full --confirm-full.
Phase 2.5 — качество данных на 100 товаров
Этот проект в настоящее время нацелен на контролируемый набор данных Lumenco из ~100 товаров. В живом каталоге более 30 000 SKU; полный краул каталога намеренно выходит за рамки.
Конвейер
Scrapling → извлечение товаров → скачивание PDF → текст PDF или OCR → нормализация спецификаций → PostgreSQL → read-only MCP
Сначала выполняется извлечение текста PDF. OCR (Tesseract через pytesseract) запускается только тогда, когда в PDF нет значимого текста. Установите ENABLE_OCR=true и установите Tesseract плюс pip install pytesseract Pillow.
Нормализованные спецификации сохраняют источник и флаги конфликтов. Сырой текст spec-sheet хранится в specification_documents.extracted_text. MCP get_product возвращает компактные структурированные спецификации; get_product_specifications может включать сырой текст при include_raw_text=true.
Французские URL категорий Magento (например, /eclairage-interieur и /electricite) по-прежнему появляются в общем заголовке на английском хосте. Там они возвращают 404. Краулер не ставит в очередь эти пути. Новые краулы также используют изолированный каталог контрольных точек Scrapling (data/crawl/run-<id>), чтобы старый файл паузы не мог возобновить тысячи URL категорий. Используйте --resume только для продолжения общего data/crawl контрольной точки.
Французские URL категорий Magento, переписанные на английский хост, классифицируются как expected_404 и не считаются ошибками товаров.
После краула:
python -m scraper stats
python -m scraper validate
python -m scraper sample
python -m scraper product --sku L0110TUT8002020Phase 3A — векторный поиск + эмбеддинги товаров
Phase 3A добавляет семантические представления товаров с помощью PostgreSQL + pgvector. Он не реализует ранжирование Related/Upsell/Cross-sell (это Phase 3B).
Архитектура
~100 product dataset
↓
Canonical product text (cleaned, no HTML)
↓
EmbeddingService (OpenAI-compatible API)
↓
product_embeddings (pgvector)
↓
VectorSearchService
↓
MCP tool: search_similar_productsНастройка
Используйте образ Postgres с pgvector (
docker-compose.ymlиспользуетpgvector/pgvector:pg16).Задайте переменные окружения для эмбеддингов в
.env(см..env.example).Миграция:
python -m alembic upgrade headГенерация эмбеддингов для каталога разработки:
python -m scraper embeddings --limit 100
python -m scraper embedding-statsНеизменённые товары пропускаются через content_hash. Используйте --force для полной перегенерации.
Стратегия индексов
HNSW по косинусному расстоянию (vector_cosine_ops, m=16, ef_construction=64) — хорошо подходит для набора из ~100 товаров и остаётся пригодным по мере роста каталога. IVFFlat можно рассмотреть позже для гораздо больших каталогов.
MCP
Новый read-only инструмент: search_similar_products. Он только читает сохранённые векторы; он не вызывает API эмбеддингов и не собирает данные с Lumenco. Существующие инструменты рекомендаций не изменяются.
Phase 3B — гибридный движок рекомендаций
Рекомендации сочетают сходство pgvector со структурированными правилами товаров. Одного векторного сходства недостаточно: трубка T8 на 18 Вт, трубка T8 на 30 Вт и светильник T8 могут быть семантически близки, но они соответствуют Related, Upsell и Cross-sell соответственно.
Product → vector candidates + structured neighbors
↓
hard exclusions
↓
Related / Upsell / Cross-sell scorers
↓
scores + confidence + reasons → MCPТип | Значение |
Related | Похожий сценарий использования / категория / спецификации |
Upsell | То же семейство и измеримое улучшение (не только цена) |
Cross-sell | Дополняющий (драйвер, отделка, корпус, светильник↔трубка) |
В ранжировании не используется LLM. MCP-инструменты find_related_products, find_upsell_products и find_cross_sell_products вызывают RecommendationService (read-only).
CLI
python -m scraper recommend --sku L0110TUT8002020 --type related --limit 5
python -m scraper recommend --sku L0110TUT8002020 --type upsell --limit 5 --debug
python -m scraper recommend --sku L0110TUT8002020 --type cross-sell --limit 5
python -m scraper recommendation-eval --sample-size 10 --limit 3Веса настраиваются через переменные окружения, такие как RELATED_VECTOR_WEIGHT, UPSELL_TECHNICAL_WEIGHT, CROSS_SELL_COMPATIBILITY_WEIGHT (см. .env.example).
Phase 3C — рабочий процесс Claude + MCP
User → Claude → MCP (/mcp) → PostgreSQL + pgvector + RecommendationService → Claude → UserОбязанности
Слой | Назначение |
Scrapling | Обход / хранение |
PostgreSQL + pgvector | Источник истины + векторы |
RecommendationService | Детерминированный рейтинг «Похожие»/«Апселл»/«Кросс-сейл» |
MCP | Получение только для чтения (без скрапинга, без записи, без LLM) |
Claude | Диалог, выбор инструментов, объяснение |
Навык Claude
Навык проекта: .cursor/skills/lumenco-product-mcp/SKILL.md
Сквозные промпты
Подключение Claude / Inspector
docker compose up -d postgrespython -m app.serverУкажите клиенту на
http://localhost:8000/mcp(Streamable HTTP)Необязательно:
MCP_AUTH_TOKEN+Authorization: Bearer …
Для удалённого развёртывания позже: публикуйте только MCP HTTPS-эндпоинт; PostgreSQL держите в приватной сети.
Набор данных для разработки
Текущий каталог: ~100 товаров. Полный каталог Lumenco (30k+) намеренно выходит за рамки.
Фаза 2 — Lumenco Product Database MCP
MCP-сервер Streamable HTTP только для чтения с именем Lumenco Product Database.
Архитектура
Claude
│ MCP / Streamable HTTP
▼
Lumenco MCP Server (/mcp, /health)
│
▼
MCP Tool Layer
│
▼
Service Layer catalog / product / search / similarity / recommendation
│
▼
Repository Layer SQLAlchemy, no raw SQL in tools
│
▼
PostgreSQL + pgvector products, specs, listings, product_embeddingsЛокальная настройка
Завершите настройку Фазы 1 (PostgreSQL +
.env+python -m alembic upgrade head).Запустите обход, чтобы каталог заполнился.
Установите дополнительные зависимости MCP, если их ещё нет в
requirements.txt:
pip install -r requirements.txtЗадайте MCP-переменные в
.env:
MCP_HOST=0.0.0.0
MCP_PORT=8000
MCP_AUTH_TOKEN=replace-with-a-long-random-token
DATABASE_URL=postgresql+psycopg2://lumenco:lumenco@127.0.0.1:5433/lumenco
DB_POOL_SIZE=10
DB_MAX_OVERFLOW=20
DB_POOL_TIMEOUT=30Для продакшена создайте роль только для SELECT:
psql postgresql://lumenco:lumenco@127.0.0.1:5433/lumenco -f scripts/create_readonly_user.sqlЗатем укажите DATABASE_URL на lumenco_mcp.
Запуск
python -m app.serverИли:
uvicorn app.server:app --host 0.0.0.0 --port 8000Docker:
docker compose up --build mcpMCP-эндпоинт
http://localhost:8000/mcp
Проверка состояния
GET http://localhost:8000/health
{
"status": "ok",
"service": "lumenco-product-mcp",
"database": "connected"
}MCP Inspector
npx -y @modelcontextprotocol/inspectorПодключитесь к http://localhost:8000/mcp с транспортом Streamable HTTP. Если задан MCP_AUTH_TOKEN, добавьте:
Authorization: Bearer <token>Убедитесь, что все восемь инструментов отображаются и выполняются.
Доступные инструменты
Все инструменты только читают PostgreSQL. Ни один не загружает URL-адреса Lumenco.
get_catalog_status
Размер каталога и свежесть последнего обхода. Без входных данных.
get_listing_products
Товары по URL-адресу листинга бренда/категории в исходной позиции листинга.
Входные данные | Обязательный | Примечания |
| да | Нормализуется и используется как ключ базы данных |
| нет | По умолчанию 20, максимум 100 |
| нет | По умолчанию 0 |
get_product
Полная запись товара по product_id и/или sku.
get_product_specifications
Структурированные характеристики плюс сохранённый текст спецификации. PDF-файлы не загружаются.
search_products
Поиск по локальному каталогу (SKU, название, бренд, категория, описание, характеристики).
Необязательные фильтры: brand, category, subcategory, sku, min_price, max_price.
search_similar_products
Семантические соседи из сохранённых pgvector-эмбеддингов (косинусное сходство). Не генерирует эмбеддинги и не вызывает LLM.
Необязательные фильтры: brand, category, subcategory, min_price, max_price.
find_related_products
Гибридные кандидаты Related (вектор + категория/применение/характеристики). Включает match_score, confidence, score_breakdown и match_reasons. Необязательный параметр debug=true.
find_upsell_products
Гибридные кандидаты Upsell. Требуется измеримое улучшение (не только цена). Причины в upgrade_reasons.
find_cross_sell_products
Гибридные кандидаты Cross-sell. Совместимость имеет решающее значение; альтернативы из того же семейства исключаются.
Инструменты рекомендаций исключают исходный товар и дедуплицируют кандидатов. Claude должен запросить пул кандидатов, а затем сам выбрать финальные 3 Related / 4 Upsell / 7 Cross-sell.
Пример рабочего процесса
Пользователь: проанализируй первые 10 товаров с https://en.staging.lumenco.ca/brand/aaled и дай 3 Related, 4 Upsell, 7 Cross-sell.
get_listing_products(listing_url=..., limit=10)get_product(product_id=...)для каждого исходного товараfind_related_products/find_upsell_products/find_cross_sell_productsсlimit=10Claude выбирает финальный набор из пулов кандидатов
Продакшен-развёртывание
Публикуйте только MCP HTTPS-эндпоинт. PostgreSQL держите в приватной сети.
Internet → HTTPS → MCP server → private PostgreSQLПодходящие платформы: Railway, Render, Google Cloud Run, AWS, Cloudflare.
Требования:
Терминатор HTTPS перед
uvicorn/ Docker-образомзадан
MCP_AUTH_TOKEN(bearer-мидлвара изолирована, чтобы позже её можно было заменить на OAuth)DATABASE_URLтолько для чтенияпроверка состояния на
/health
Не публикуйте порт 5432.
Пользовательский коннектор Claude
После того как сервер станет доступен по публичному HTTPS-URL:
В Claude добавьте пользовательский коннектор.
MCP URL:
https://your-host/mcpИмя сервера должно отображаться как Lumenco Product Database.
Настройте bearer-аутентификацию с помощью
MCP_AUTH_TOKENили OAuth, если вы замените мидлвару.Спросите: «Сколько товаров сейчас в базе Lumenco?» Claude должен вызвать
get_catalog_status.
Временный публичный HTTPS для локального тестирования: Cloudflare Tunnel, ngrok или аналогичные перед localhost:8000.
Безопасность
Нет инструментов
execute_sql,fetch_url,run_commandили обходаТолько параметризованные запросы SQLAlchemy
Применяются лимиты запросов
Сеансы открывают
SET TRANSACTION READ ONLYв PostgreSQLСекреты не возвращаются в ошибках инструментов
This server cannot be installed
Maintenance
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
- FlicenseNot gradedqualityCmaintenanceEnables searching and retrieving product information from DigiKey's API, including part lookup, keyword search, product details, and pricing.
- FlicenseAqualityDmaintenanceEnables interaction with Adobe Commerce Catalog Services to retrieve product variants, price overrides, category permissions, and environment details via MCP.7
- FlicenseAqualityCmaintenanceExposes marketing catalogs (offers, assets, campaigns, and computed metrics) to MCP clients, enabling natural language queries and AI-driven marketing analysis.8
- AlicenseAqualityBmaintenanceEnables read-only discovery and verification of products across droplinked's KYB-attested merchant network via tools for inventory, merchant, and brand attestation lookups.7MIT
Related MCP Connectors
Federated commerce search across independent WooCommerce merchants. Keyless, read-only MCP server.
Agent-native product catalog for AI shopping agents. 296M+ products, 28 countries.
Manage products, EU Digital Product Passports, operator parties, and GS1 EPCIS supply-chain events.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ai-code-co/Claude_MCP_Lumenco'
If you have feedback or need assistance with the MCP directory API, please join our Discord server